【山外筆記-數據庫】Memcached教程詳解

本文打印版文檔下載地址

【山外筆記-數據庫】Memcached詳解教程-打印版.pdf

一、Memcached數據庫概述

1、Memcached簡介

(1)Memcached是一個自由開源的,高性能,分佈式內存對象緩存系統,通過在內存里維護一個統一的巨大的hash表來存儲各種格式的數據。

(2)Memcached本質上是一個基於內存的key-value存儲系統,用來存儲小塊的任意數據(字符串、對象)。

(3)Memcached的守護進程(daemon )用C語言編寫,但是客戶端可以用任何語言來編寫,並通過memcached協議與守護進程通信。

(4)Memcached是以守護程序(監聽)方式運行於一個或者多個服務器中,隨時會接受客戶端的連接和操作。

(5)Memcached客戶端有各種語言的版本,包括java,c,php,.net等等。

(6)Memcached通過在內存中緩存數據和對象來減少讀取數據庫的次數,提高動態、數據庫驅動網站的速度,減輕數據庫負載。

(7)Memcached的API兼容大部分流行的開發語言,其中包括Perl、PHP、Python、RubyC#、C/C++、Lua等。

memcached02.png

2、Memcached的特點

(1)協議簡單

(2)基於libevent的事件處理

libevent是一個將Linux的epoll、BSD類操作系統的kqueue等事件處理功能封裝成統一接口的程序庫。

(3)內置內存存儲方式

  • memcached中保存的數據都存儲在memcached內置的內存存儲空間中。

  • 由於數據僅存在於內存中,因此重啟memcached、重啟操作系統會導致全部數據消失。

  • 內存容量達到指定值之後,就基於LRU(Least Recently Used)算法自動刪除不使用的緩存。

  • memcached本身是為緩存而設計的服務器,因此並沒有過多考慮數據的永久性問題。

(4)分佈式memcached互不通信

  • memcached儘管是分佈式緩存服務器,但服務器端並沒有分佈式功能。

  • 各個memcached不會互相通信以共享信息。

memcached01.png

3、Memcached的工作原理:緩存式的Web應用程序架構

(1)在傳統的app層和db層之間加入cache層, 每個app服務器都可以綁定一個mc(memcached)。

(2)每次數據的讀取都可以從ms(內置分配內存的組件)中取得,如果沒有,再從db層讀取。

(3)當ms的hash表滿了之後,新的插入數據會替代老的數據,更新的策略是LRU(最近最少使用)+ 到期失效策略,失效數據首先被替換,然後再替換到最近未使用的數據。。

(4)當數據要進行更新時,除了要發送update的 sql給db層,同時也要將更新的數據發給,讓mc去更新ms中的數據。

4、Memcached的安裝

(1)Linux Memcached安裝

  • Ubuntu/Debian在線安裝

    sudo apt-get install libevent ibevent-dev
    sudo apt-get install memcached
    
  • Redhat/Fedora/Centos在線安裝

    yum install libevent libevent-devel
    yum install memcached
    
  • 源代碼安裝

    wget //memcached.org/latest                    下載最新版本
    tar -zxvf memcached-1.x.x.tar.gz                    解壓源碼
    cd memcached-1.x.x                                  進入目錄
    ./configure --prefix=/usr/local/memcached           配置
    make && make test                                   編譯
    sudo make install                                   安裝
    

(2)Windows Memcached安裝

在 1.4.5 版本以前 Memcached可以作為一個服務安裝,而在 1.4.5 及之後的版本刪除了該功能。因此需要採用不同的安裝方式。

Memcached安裝包下載地址://github.com/memcached/memcached/releases

  • Memcached 1.4.5 以前的版本

  • 解壓下載的安裝包到指定目錄。

  • memcached 可以作為一個服務安裝,cmd窗口執行

    c:\memcached\memcached.exe -d install
    
  • 啟動和關閉 memcached 服務

    c:\memcached\memcached.exe -d start
    c:\memcached\memcached.exe -d stop
    
  • 修改 memcached 的緩存配置項

    c:\memcached\memcached.exe -d runservice -m 512
    
  • 查看memcached 的的幫助信息

    c:\memcached\memcached.exe -h
    
  • 卸載memcached

    c:\memcached\memcached.exe -d uninstall
    
  • Memcached 1.4.5 以後的版本

    • 解壓下載的安裝包到指定目錄。

    • memcached 不能作為服務來運行,需要使用任務計劃中來開啟一個普通的進程,設置開機自動啟動。

      schtasks /create /sc onstart /tn memcached /tr "'c:\memcached\memcached.exe' -m 512"
      
    • 刪除 memcached 的任務計劃

      schtasks /delete /tn memcached
      
5、Memcached的運行

(1)Linux自動安裝 memcached 命令位於 /usr/local/bin/memcached

(2)查看Memcached命令的幫助:memcached -h

  • -d選項:啟動一個守護進程;
  • -m選項:分配給Memcached使用的內存數量,單位是MB;
  • -u選項:運行Memcached的用戶;
  • -l選項:監聽的服務器IP地址,可以有多個地址;
  • -p選項:設置Memcached監聽的端口,最好是1024以上的端口;
  • -c選項:最大運行的並發連接數,默認是1024;
  • -P選項:設置保存Memcached的pid文件。

(3)啟動Memcached服務

memcached -d -m 64M -u root -l 192.168.0.120 -p 11211 -c 256 -P /tmp/memcached.pid

(4)關閉Memcached服務

ps -ef|grep memcached
kill -9 memcached_pid
6、Memcached的連接

(1)通過 telnet 命令並指定主機ip和端口來連接 Memcached 服務。

(2)語法:telnet HOST PORT

二、Memcached 存儲命令

1、Memcached set 命令

(1)Memcached set 命令:用於將 value(數據值) 存儲在指定的 key(鍵) 中。

(2)如果set的key已經存在,該命令可以更新該key所對應的原來的數據,也就是實現更新的作用。

(3)set 命令的基本語法格式:

set key flags exptime bytes [noreply] 
value 

(4)參數說明:

  • key:鍵值 key-value 結構中的 key,用於查找緩存值。
  • flags:可以包括鍵值對的整型參數,客戶機使用它存儲關於鍵值對的額外信息 。
  • exptime:在緩存中保存鍵值對的時間長度(以秒為單位,0 表示永遠)
  • bytes:在緩存中存儲的位元組數
  • noreply(可選): 該參數告知服務器不需要返回數據
  • value:存儲的值(始終位於第二行)(可直接理解為key-value結構中的value)

(4)輸出信息:

  • STORED:保存成功後輸出。
  • ERROR:在保存失敗後輸出。
2、Memcached add 命令

(1)Memcached add 命令:用於將 value(數據值) 存儲在指定的 key(鍵) 中。

(2)如果 add 的 key 已經存在,則不會更新數據(過期的 key 會更新),之前的值將仍然保持不變,並且獲得響應 NOT_STORED。

(3)add 命令的基本語法格式:

add key flags exptime bytes [noreply]
value

(4)參數說明和輸出信息同set命令。

3、Memcached replace 命令

(1)Memcached replace 命令:用於替換已存在的 key(鍵)value(數據值)

(2)如果 key 不存在,則替換失敗,並且獲得響應 NOT_STORED

(3)replace 命令的基本語法格式:

replace key flags exptime bytes [noreply]
value

(4)參數說明和輸出信息同set命令。

(5) set 、add 、replace 三個命令的區別

  • add命令:用於向 memcache 服務器添加一個要緩存的數據,如果 key 存在則返回 false。

  • replace命令:用於向 memcache 服務器替換一個指定 key 的緩存內容,如果 key 不存在則返回 false。

  • set 命令:用於設置一個指定 key 的緩存內容,是 add 方法和 replace 方法的集合體。

4、Memcached append 命令

(1)Memcached append 命令:用於向已存在 key(鍵)value(數據值) 後面追加數據(字符串相加) 。

(2)append 命令的基本語法格式:

append key flags exptime bytes [noreply]
value

(3)參數說明同set命令。

(4)輸出信息

  • STORED:保存成功後輸出。
  • NOT_STORED:該鍵在 Memcached 上不存在。
  • CLIENT_ERROR:執行錯誤。
5、Memcached prepend 命令

(1)Memcached prepend 命令用於向已存在 key(鍵)value(數據值) 前面追加數據 。

(2)prepend 命令的基本語法格式:

prepend key flags exptime bytes [noreply]
value

(3)參數說明同set命令。

(4)輸出信息同append命令。

6、Memcached CAS 命令

(1)Memcached CAS(Check-And-Set 或 Compare-And-Swap) 命令:用於執行一個”檢查並設置”的操作。

  • Memcached CAS命令僅在當前客戶端最後一次取值後,該key 對應的值沒有被其他客戶端修改的情況下, 才能夠將值寫入。

  • 檢查是通過cas_token參數進行的, 這個參數是Memcach指定給已經存在的元素的一個唯一的64位值。

  • 使用 CAS 命令,需要從 Memcached 服務商通過 gets 命令獲取令牌(token)。

(2)CAS 命令的基本語法格式:

cas key flags exptime bytes unique_cas_token [noreply]
value

(3)參數說明:

  • unique_cas_token選項:通過 gets 命令獲取的一個唯一的64位值。
  • 其他參數說明同set命令。

(4)輸出信息:

  • STORED:保存成功後輸出。
  • ERROR:保存出錯或語法錯誤。
  • EXISTS:在最後一次取值後另外一個用戶也在更新該數據。
  • NOT_FOUND:Memcached 服務上不存在該鍵值。

三、Memcached查找命令

1、Memcached get 命令

(1)Memcached get 命令:獲取存儲在 key(鍵) 中的 value(數據值) ,如果 key 不存在,則返回空。

(2)get 命令的基本語法格式如下:

get key
get key1 key2 key3		#多個 key 使用空格隔開

(3)參數key:鍵值 key-value 結構中的 key,用於查找緩存值。

2、Memcached gets 命令

(1)Memcached gets 命令獲取帶有 CAS 令牌存 的 value(數據值) ,如果 key 不存在,則返回空。

(2)gets 命令的基本語法格式如下:

gets key
gets key1 key2 key3		#多個 key 使用空格隔開
3、Memcached delete 命令

(1)Memcached delete 命令:用於刪除已存在的 key(鍵)。

(2)delete 命令的基本語法格式:delete key [noreply]

(3)參數說明:

  • key:鍵值 key-value 結構中的 key,用於查找緩存值。
  • noreply(可選): 該參數告知服務器不需要返回數據

(4)輸出信息說明:

  • DELETED:刪除成功。
  • ERROR:語法錯誤或刪除失敗。
  • NOT_FOUND:key 不存在。
4、Memcached incr 命令

(1)Memcached incr 與 decr 命令用於對已存在的 key(鍵) 的數字值進行自增操作。

  • incr 與 decr 命令操作的數據必須是十進制的32位無符號整數。

  • 如果 key 不存在返回 NOT_FOUND,如果鍵的值不為數字,則返回 CLIENT_ERROR,其他錯誤返回 ERROR

(2)incr 命令的基本語法格式:incr key increment_value

(3)參數說明:

  • key:鍵值 key-value 結構中的 key,用於查找緩存值。
  • increment_value: 增加的數值。

(4)輸出信息說明:

  • NOT_FOUND:key 不存在。
  • CLIENT_ERROR:自增值不是對象。
  • ERROR其他錯誤,如語法錯誤等。
5、Memcached decr 命令

(1)Memcached incr 與 decr 命令用於對已存在的 key(鍵) 的數字值進行自減操作。

  • decr 命令操作的數據必須是十進制的32位無符號整數。

  • 如果 key 不存在返回 NOT_FOUND,如果鍵的值不為數字,則返回 CLIENT_ERROR,其他錯誤返回 ERROR

(2)decr 命令的基本語法格式:decr key decrement_value

(3)參數說明:

  • key:鍵值 key-value 結構中的 key,用於查找緩存值。
  • decrement_value: 減少的數值。

(4)輸出信息說明:

  • NOT_FOUND:key 不存在。
  • CLIENT_ERROR:自增值不是對象。
  • ERROR其他錯誤,如語法錯誤等。

四、Memcached 統計命令

1、Memcached stats 命令

(1)Memcached stats 命令用於返回統計信息例如 PID(進程號)、版本號、連接數等。

(2)stats 命令的基本語法格式:stats

stats
STAT pid 1162
STAT uptime 5022
STAT time 1415208270
STAT version 1.4.14
STAT libevent 2.0.19-stable
STAT pointer_size 64
STAT rusage_user 0.096006
STAT rusage_system 0.152009
STAT curr_connections 5
STAT total_connections 6
STAT connection_structures 6
STAT reserved_fds 20
STAT cmd_get 6
STAT cmd_set 4
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 4
STAT get_misses 2
STAT delete_misses 1
STAT delete_hits 1
STAT incr_misses 2
STAT incr_hits 1
STAT decr_misses 0
STAT decr_hits 1
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 262
STAT bytes_written 313
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT expired_unfetched 1
STAT evicted_unfetched 0
STAT bytes 142
STAT curr_items 2
STAT total_items 6
STAT evictions 0
STAT reclaimed 1
END

(3)狀態項說明:

  • pid: memcache服務器進程ID
  • uptime:服務器已運行秒數
  • time:服務器當前Unix時間戳
  • version:memcache版本
  • pointer_size:操作系統指針大小
  • rusage_user:進程累計用戶時間
  • rusage_system:進程累計系統時間
  • curr_connections:當前連接數量
  • total_connections:Memcached運行以來連接總數
  • connection_structures:Memcached分配的連接結構數量
  • cmd_get:get命令請求次數
  • cmd_set:set命令請求次數
  • cmd_flush:flush命令請求次數
  • get_hits:get命令命中次數
  • get_misses:get命令未命中次數
  • delete_misses:delete命令未命中次數
  • delete_hits:delete命令命中次數
  • incr_misses:incr命令未命中次數
  • incr_hits:incr命令命中次數
  • decr_misses:decr命令未命中次數
  • decr_hits:decr命令命中次數
  • cas_misses:cas命令未命中次數
  • cas_hits:cas命令命中次數
  • cas_badval:使用擦拭次數
  • auth_cmds:認證命令處理的次數
  • auth_errors:認證失敗數目
  • bytes_read:讀取總位元組數
  • bytes_written:發送總位元組數
  • limit_maxbytes:分配的內存總大小(位元組)
  • accepting_conns:服務器是否達到過最大連接(0/1)
  • listen_disabled_num:失效的監聽數
  • threads:當前線程數
  • conn_yields:連接操作主動放棄數目
  • bytes:當前存儲佔用的位元組數
  • curr_items:當前存儲的數據總數
  • total_items:啟動以來存儲的數據總數
  • evictions:LRU釋放的對象數目
  • reclaimed:已過期的數據條目來存儲新數據的數目
2、Memcached stats items 命令

(1)Memcached stats items 命令用於顯示各個 slab 中 item 的數目和存儲時長(最後一次訪問距離現在的秒數)。

(2)stats items 命令的基本語法格式:stats items

3、Memcached stats slabs 命令

(1)Memcached stats slabs 命令用於顯示各個slab的信息,包括chunk的大小、數目、使用情況等。

(2)stats slabs 命令的基本語法格式:stats slabs

4、Memcached stats sizes 命令

(1)Memcached stats sizes 命令:用於顯示所有item的大小和個數。

(2)該信息返回兩列,第一列是 item 的大小,第二列是 item 的個數。

(3)stats sizes 命令的基本語法格式:stats sizes

5、Memcached flush_all 命令

(1)Memcached flush_all 命令:用於清理緩存中的所有 key=>value(鍵=>值) 對。

(2)Memcached flush_all 命令提供了一個可選參數 time,用於在制定的時間後執行清理緩存操作。

(3)flush_all 命令的基本語法格式:flush_all [time] [noreply]

五、Memcached 應用

1、Java 連接 Memcached 服務

使用 Java 程序連接 Memcached,需要在 classpath 中添加 Memcached jar 包。

本站 jar 包下載地址:spymemcached-2.10.3.jar

以下程序假定 Memcached 服務的主機為 127.0.0.1,端口為 11211。

import net.spy.memcached.MemcachedClient;
import java.net.*;

public class MemcachedJava {
   public static void main(String[] args) {
      try{
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");		// 本地連接 Memcached 服務
         Future fo = mcc.set("mentest", 900, "Free Education");		// 存儲數據
         System.out.println("set status:" + fo.get());				// 查看存儲狀態
         System.out.println("mentest value in cache - " + mcc.get("mentest"));
         fo = mcc.add("mentest", 900, "memcached");					// 添加
         System.out.println("add status:" + fo.get());				// 打印狀態
         fo = mcc.add("codingground", 900, "All Free Compilers");	// 添加新key
         System.out.println("add status:" + fo.get());				// 打印狀態
         System.out.println("codingground value in cache - " + mcc.get("codingground"));
         fo = mcc.replace("mentest", 900, "Tutorials' Library");	// 添加新的 key
         System.out.println("replace status:" + fo.get());			// 打印狀態
         System.out.println("mentest value in cache - " + mcc.get("mentest"));
         fo = mcc.append("mentest", 900, " for All");				// 對存在的key進行數據添加操作
         System.out.println("append status:" + fo.get());			// 打印狀態
         System.out.println("mentest value in cache - " + mcc.get("codingground"));
         fo = mcc.prepend("mentest", 900, "Free ");					// 對存在的key進行數據添加操作
         System.out.println("prepend status:" + fo.get());			// 打印狀態
         System.out.println("mentest value in cache - " + mcc.get("codingground"));
         CASValue casValue = mcc.gets("mentest");			// 通過 gets 方法獲取 CAS token(令牌)
         System.out.println("CAS token - " + casValue);		// 輸出 CAS token(令牌) 值
         CASResponse casresp = mcc.cas("mentest", casValue.getCas(), 900, "Tutorials-Library");
         System.out.println("CAS Response - " + casresp);	// 輸出 CAS 響應信息
         System.out.println("mentest value in cache - " + mcc.get("mentest"));
         fo = mcc.delete("mentest");							// 對存在的key進行數據添加操作
         System.out.println("delete status:" + fo.get());	// 打印狀態
         System.out.println("mentest value in cache - " + mcc.get("codingground"));
         System.out.println("value in cache after increment - " + mcc.incr("number", 111));
         System.out.println("value in cache after decrement - " + mcc.decr("number", 112));
         mcc.shutdown();  											// 關閉連接    
      }catch(Exception ex){
         System.out.println( ex.getMessage() );
      }
   }
}

(1)連接操作:程序中使用 InetSocketAddress 連接 IP 為 127.0.0.1 端口 為 11211 的 memcached 服務。

(2)set 操作:mcc.set("mentest", 900, "Free Education")

(3)add 操作:mcc.add("mentest", 900, "memcached")

(4)replace 操作:mcc.replace("mentest", 900, "Tutorials' Library")

(5)append 操作:append("mentest", 900, " for All")

(6)prepend 操作:mcc.prepend("mentest", 900, "Free ")

(7)CAS 操作:mcc.cas("mentest", casValue.getCas(), 900, "Tutorials-Library")

(8)get 操作:mcc.get("mentest")

(9)gets 操作:mcc.gets("mentest")

(10)delete 操作:mcc.delete("mentest")

(11)Incr/Decr 操作:mcc.incr("number", 111)mcc.decr("number", 112)

2、PHP 連接 Memcached 服務

(1)PHP Memcache 擴展安裝

  • 離線安裝

    wget //pecl.php.net/get/memcache-2.2.7.tgz               
    tar -zxvf memcache-2.2.7.tgz
    cd memcache-2.2.7
    /usr/local/php/bin/phpize
    ./configure --with-php-config=/usr/local/php/bin/php-config
    make && make install
    
  • 在線安裝

    yum install -y php-memcached
    systemctl start httpd 			//開啟apache
    systemctl start memcached 		//開啟memcached
    setenforce 0
    

(2)檢查安裝結果:/usr/local/php/bin/php -m | grep memcache

(3) Memcache類

  • Memcache::add:增加一個條目到緩存服務器
  • Memcache::addServer:向連接池中添加一個memcache服務器
  • Memcache::close:關閉memcache連接
  • Memcache::connect :打開一個memcached服務端連接
  • Memcache::decrement :減小元素的值
  • Memcache::delete :從服務端刪除一個元素
  • Memcache::flush :清洗(刪除)已經存儲的所有的元素
  • Memcache::get :從服務端檢回一個元素
  • Memcache::getExtendedStats :緩存服務器池中所有服務器統計信息
  • Memcache::getServerStatus :用於獲取一個服務器的在線/離線狀態
  • Memcache::getStats :獲取服務器統計信息
  • Memcache::getVersion :返回服務器版本信息
  • Memcache::increment:增加一個元素的值
  • Memcache::pconnect:打開一個到服務器的持久化連接
  • Memcache::replace :替換已經存在的元素的值
  • Memcache::set :Store data at the server
  • Memcache::setCompressThreshold :開啟大值自動壓縮
  • Memcache::setServerParams :運行時修改服務器參數和狀態

(4)Memcache 函數:

  • memcache_debug:轉換調試輸出的開/關

六、參考資料

1、《Memcached 教程-菜鳥教程》

2、《PHP中文手冊》