源地址:http://kb.cnblogs.com/page/42731/
仔細學習了下,以下是記錄的筆記備忘內容。
一、memcached是什么?
memcached是高性能的分布式內存緩存服務器。
一般使用目的是,通過緩存數據庫查詢結果,減少數據庫訪問次數,以提高動態web應用的速度、提高可擴展性
memcached的特征:
1. 協議簡單
2. 基於libevent的事件處理
3. 內置內存存儲方式
4. memcached不互相通信的分布式
協議簡單:
memcached使用簡單文本行的協議,因此通過telnet也能在memcached上保存數據,取得數據。
基於libevent的事件處理
libevent是一個程序庫,它將linux的epoll、BSD類操作系統的kqueue等事件處理功能封裝成統一的接口。
memcached使用這個libevent庫,因此在linux、BSD等操作系統上發揮高性能。
內置內存存儲方式
memcached中保存的數據都存儲在memcached內置的內存存儲空間中。由於數據僅存儲在內存中,因此重啟memcached、重啟操作系統會導致全部數據的丟失。內容容量達到指定值之后,就基於LRU算法自動刪除不使用的緩存。memcached本身是為緩存而設計的服務器,因此沒有考慮數據的永久性問題。
memcached不互相通信的分布式
各個memcahced不會互相通信已共享信息,如何進行分布式,是由客戶端來實現的
memcached安裝
在安裝memcahced之前,首先要安裝libevent庫
# tar xf libevent-2.0.21-stable.tar.gz # cd libevent-2.0.21 # ./configure --prefix=/usr/local/libevent # make && make install # echo "/usr/local/libevent/lib" > /etc/ld.so.conf.d/libevent.conf # ldconfig # tar xf memcached-1.4.15.tar.gz # cd memcached-1.4.15 # ./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent # make && make install
memcached 編譯安裝時,啟動腳本:
#!/bin/bash # # Init file for memcached # # chkconfig: - 86 14 # description: Distributed memory caching daemon # # processname: memcached # config: /etc/sysconfig/memcached . /etc/rc.d/init.d/functions ## Default variables PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="64" OPTIONS="" RETVAL=0 prog="/usr/local/memcached/bin/memcached" desc="Distributed memory caching" lockfile="/var/lock/subsys/memcached" start() { echo -n $"Starting $desc (memcached): " daemon $prog -d -p $PORT -u $USER -c $MAXCONN -m $CACHESIZE $OPTIONS RETVAL=$? [ $RETVAL -eq 0 ] && success && touch $lockfile || failure echo return $RETVAL } stop() { echo -n $"Shutting down $desc (memcached): " killproc $prog RETVAL=$? [ $RETVAL -eq 0 ] && success && rm -f $lockfile || failure echo return $RETVAL } restart() { stop start } reload() { echo -n $"Reloading $desc ($prog): " killproc $prog -HUP RETVAL=$? [ $RETVAL -eq 0 ] && success || failure echo return $RETVAL } case "$1" in start) start ;; stop) stop ;; restart) restart ;; condrestart) [ -e $lockfile ] && restart RETVAL=$? ;; reload) reload ;; status) status $prog RETVAL=$? ;; *) echo $"Usage: $0 {start|stop|restart|condrestart|status}" RETVAL=1 esac exit $RETVAL
主配置文件:/etc/sysconfig/memcached PORT="11211" # memcached端口 USER="memcached" # 啟動用戶 MAXCONN="1024" # 最大連接數 CACHESIZE="64" # 內存緩存空間大小,單位:M OPTIONS="" # 其他選項 memcached客戶端連接 telnet ip:port 保存數據
向memcached保存數據的方法有:
add、replace、set
my $add = $memcached->add( '鍵', '值', '期限' );
my $replace = $memcached->replace( '鍵', '值', '期限' );
my $set = $memcached->set( '鍵', '值', '期限' );
向memcached保存數據時可以指定期限(秒)。不指定期限memcached按照LRU算法保存數據。上面三個方法的區別:
add: 僅當存儲空間中不存在鍵相同的數據時才保存
replace: 僅當存儲空間中存在鍵相同的數據時才保存
set: 與add和replace不同,無論何時都保存
獲取數據
獲取數據使用get 和 get_multi 方法
一次獲取多條數據時使用get_multi,可以非同步的同時取得多個鍵值,速度要比循環調用get快數十倍
my $val = $memcached->get('鍵');
my $val = $memcached->get_multi('鍵1', '鍵2', '鍵3', '鍵4', '鍵5');
刪除數據
刪除數據使用delete方法
$memcached->delete('鍵', '阻塞時間(秒)');
刪除第一個參數指定鍵的數據,第二個參數指定一個時間值,可以禁止使用同樣的鍵保存新數據。此功能可以用於防止緩存數據的不完整。注意:set函數忽視該阻塞,照常保存數據增一和減一操作
二、memcahced的內存存儲機制
slab Allocation機制:整理內存以便重復使用
slab allocator的基本原理是按照預先規定的大小,將分配的內存分割成特定的塊,以完全解決內存碎片問題。
slab Allocation 將分配的內存分割成各種尺寸的塊(chunk),並把尺寸相同的塊分成組(chunk的集合)
slab allocator 能重復使用已分配的內存目的。也就是說,分配到的內存不會釋放,而且重復利用。
slab Allocation的主要術語
Page: 內存分配給slab的內存空間,默認是1MB,分配給slab之后根據slab的大小切分成chunk,一個page為4kb
Chunk:用於緩存記錄的內存空間
slab class:特定大小chunk的組
在slab中緩存數據的原理:
memcached根據收到數據的大小,選擇最適合數據大小的slab,memcached中保存着slab內空閑的chunk的列表,根據該列表選擇chunk,然后將數據緩存於其中。
slab Allocator的缺點:
slab allocator 分配的是特定長度的內存因此無法有效利用分配的內存。例如:將100字節的數據緩存到128字節上,剩余的28字節就浪費掉了。
使用Growth Factor進行調優
memcached在啟動時指定Growth Factor因子(選項-f),就可以在某種程度上控制slab之間的差異,默認是1.25
設置命令:memcached -f 2 -vv
查看memcahced的內部狀態
# telnet 127.0.0.1 11211
stats
查看slabs的使用狀況
# memcached-tool 127.0.0.1
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
1 96B 30s 1 1 no 0 0 0
各項含義:
# slab class編號
Item_Size chunk大小
Max_age LRU內最舊的記錄的生存時間
Pages 分配給Slab的頁數
Count slab內的記錄數
Full? Slab內是否含有空閑chunk
這部分不是特別完全,后期補充,這個腳本對調優非常方便。
三、memcached的刪除機制
memcached在數據刪除方面有效利用資源,數據不會真正從memcached中消失
lazy Expiration
memcached內部不會監視記錄是否過期,而是在get時查看記錄的時間戳,檢查記錄是否過期。這種技術被成為lazy(惰性) expiration,因此memcached不會在過期監視上耗費cpu時間
LRU: 從緩存中有效刪除數據的原理
當memcached的內存空間不足時,就從最近未使用的記錄中搜索,並將其空間分配給新的記錄。新的記錄覆蓋掉使用最少的chunk
# memcached -M 禁止LRU,一般情況下是非常推薦使用LRU
四、memcached的分布式算法
memcached的分布式
memcached的分布式是由客戶端程序庫來實現的,這種分布式是memcached最大的特點。
set方法:
首先向memcached中添加'tokyo' 將'tokyo'傳給客戶端程序庫后,客戶端實現的算法就會根據'鍵'來決定保存數據的memcached服務器。
get方法:
獲取時也要將要獲取的鍵“tokyo”傳遞給函數庫。 函數庫通過與數據保存時相同的算法,根據“鍵”選擇服務器。 使用的算法相同,就能選中與保存時相同的服務器,然后發送get命令。 只要數據沒有因為某些原因被刪除,就能獲得保存的值。
Cache::Memcached的分布式方法
hash-type主要有兩種方法:
1. 取模法:這種算法不適用於memcached分布式,當一台memcached服務器故障,將會造成所有memcached緩存失效。
2. 一致性hash算法:首先求出memcached服務器的哈希值,並將其配置到1-2^32的圓上,然后用同樣的方法求出存儲數據的鍵的哈希值,並映射到圓上,然后從數據映射到的位置開始順時針查找,將數據保存到找到的第一個服務器上。