若是一個網站流量很大,則查詢數據庫將會耗費大量時間。若是將常常查詢的的數據和對象緩存到內存中,則須要查詢數據庫時,直接返回內存中緩存的數據。這中靜態化方式則會高效不少。分佈式緩存系統是爲了解決數據庫服務器和web服務器直接的瓶頸。其中memcached是一個開源、高性能、分佈式的內存對象緩存系統。主要經過在內存中緩存數據和對象減輕數據庫的負載來加速動態web程序。內存中緩存的數據通php
過API的方式被存取,數據就像一張大的HASH表,以鍵-值對方式存在。html
讀取web
執行讀取操做的順序是從 Web 層獲取請求(須要執行一次數據庫查詢)並檢查以前在緩存中存儲的查詢結果。若是我找到所需的值,則返回它。若是未找到,則執行查詢並將結果存儲在緩存中,而後再將結果返回給 Web 層。算法
寫入數據庫
將數據寫入到數據庫中時,首先須要執行數據庫寫入操做,而後將以前緩存的任何受此寫入操做影響的結果設定爲無效。此過程有助於防止緩存和數據庫之間出現數據不一致性。vim
Memcached採用client/server架構,服務端啓動守護進程,等待clent請求到達,採用異步I/O,使用libevenet做爲事件通知機制。能夠建設多個服務端協同工做,但這些服務端之間並不通訊,每一個server端對本身的數據進行管理,客戶端制定server端IP和端口進行通訊。緩存在內存中的數據並不會同步到磁盤上,所以,重啓後緩存的數據就會丟失。當緩存數據的總大小達到初始設置值時,就會使用LRU算法刪除不用的緩存。緩存
Memcached採用slaballocation機制分配和管理內存,其原理是將內存分割成各類尺寸的塊chunk,Chunk就是用來存儲key-value數據的最小單位,把尺寸相同的塊分紅組(slab class) ,每一個slab class的大小能夠在memcached啓動時制定GrowethFactor控制,默認值爲1.25。這些內存塊不會釋放,可重複利用。bash
可同過如下命令看到slab class生成過程:服務器
#/usr/local/memcached/bin/memcached -d -f 1.25 -n 50 -vvv -u nobody slabclass 1: chunk size 104 perslab 10082 slabclass 2: chunk size 136 perslab 7710 slabclass 3: chunk size 176 perslab 5957 slabclass 4: chunk size 224 perslab 4681 slabclass 5: chunk size 280 perslab 3744 slabclass 6: chunk size 352 perslab 2978 slabclass 7: chunk size 440 perslab 2383 slab class 8: chunk size 552 perslab 1899 slabclass 9: chunk size 696 perslab 1506 slabclass 10: chunk size 872 perslab 1202 slabclass 11: chunk size 1096 perslab 956 slabclass 12: chunk size 1376 perslab 762 slabclass 13: chunk size 1720 perslab 609 slabclass 14: chunk size 2152 perslab 487 slabclass 15: chunk size 2696 perslab 388 slabclass 16: chunk size 3376 perslab 310 slabclass 17: chunk size 4224 perslab 248 slabclass 18: chunk size 5280 perslab 198 slabclass 19: chunk size 6600 perslab 158 slabclass 20: chunk size 8256 perslab 127 slabclass 21: chunk size 10320 perslab 101 slabclass 22: chunk size 12904 perslab 81 slabclass 23: chunk size 16136 perslab 64 slabclass 24: chunk size 20176 perslab 51 slabclass 25: chunk size 25224 perslab 41 slabclass 26: chunk size 31536 perslab 33 slabclass 27: chunk size 39424 perslab 26 slabclass 28: chunk size 49280 perslab 21 slabclass 29: chunk size 61600 perslab 17 slabclass 30: chunk size 77000 perslab 13 slabclass 31: chunk size 96256 perslab 10 slabclass 32: chunk size 120320 perslab 8 slabclass 33: chunk size 150400 perslab 6 slabclass 34: chunk size 188000 perslab 5 slabclass 35: chunk size 235000 perslab 4 slabclass 36: chunk size 293752 perslab 3 slabclass 37: chunk size 367192 perslab 2 slabclass 38: chunk size 458992 perslab 2 slabclass 39: chunk size 573744 perslab 1 slabclass 40: chunk size 717184 perslab 1 slabclass 41: chunk size 1048576 perslab 1 <26server listening (auto-negotiate) <27server listening (auto-negotiate) <28send buffer was 124928, now 268435456 <32send buffer was 124928, now 268435456 <31server listening (udp) <35server listening (udp) <30server listening (udp) <34server listening (udp) <29server listening (udp) <33server listening (udp) <28server listening (udp) <32server listening (udp)
Memcached
經常使用選項說明
架構
-l <ip_addr>
:指定進程監聽的地址;
-d:
以
daemon
模式運行;
-u <username>
:以指定的用戶身份運行
memcached
進程;
-m <num>
:用於緩存數據的最大內存空間,單位爲
MB
,默認爲
64MB
;
-c <num>
:最大支持的併發鏈接數,默認爲
1024
;
-p <num>:
指定監聽的
TCP
端口,默認爲
11211
;
-U <num>
:指定監聽的
UDP
端口,默認爲
11211
,
0
表示關閉
UDP
端口;
-t <threads>
:用於處理入站請求的最大線程數,僅在
memcached
編譯時開啓了支持線程纔有效;
-f <num>
:設定
Slab Allocator
定義預先分配內存空間大小固定的塊時使用的增加因子;
-M
:當內存空間不夠使用時返回錯誤信息,而不是按
LRU
算法利用空間;
-n:
指定最小的
slab chunk
大小;單位是字節;
-S:
啓用
sasl
進行用戶認證;須要在編譯時指定
—enable-sasal
當Memcached接收到客戶端發送過來的數據時首先會根據收到數據的大小選擇一個最合適的Slab Class,而後經過查詢Memcached保存着的該Slab Class內空閒Chunk的列表就能夠找到一個可用於存儲數據的Chunk。當一條數據庫過時或者丟棄時,該記錄所佔用的Chunk就能夠回收,從新添加到空閒列表中。從以上過程咱們能夠看出Memcached的內存管理制效率高,並且不會形成內存碎片,可是它最大的缺點就是會致使空間浪費。由於每一個 Chunk都分配了特定長度的內存空間,因此變長數據沒法充分利用這些空間。如圖所示,將100個字節的數據緩存到128個字節的Chunk中,剩餘的28個字節就浪費掉了。
安裝libevent
Libevent是memcached所依賴的異步事件通知庫,在安裝memcached的以前須要安裝它。
# cdlibevent-2.0.22-stable # ./configure –prefix=/usr/local/libevetn # make # make install
# cd memcached-1.4.24 # ./configure--prefix=/usr/local/memcached --with-libevent=/usr/local/libevent # make # make install
爲memcached體佛那個SysV風格服務啓動腳本
# vim/etc/init.d/memcached
#!/bin/bash # # Init file formemcached # # 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="nobody" MAXCONN="1024" CACHESIZE="64" OPTIONS="" RETVAL=0 prog="/usr/local/memcached/bin/memcached" desc="Distributedmemory 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=$? echo [ $RETVAL -eq 0 ] && touch$lockfile return $RETVAL } stop() { echo -n $"Shutting down $desc(memcached): " killproc $prog RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f$lockfile return $RETVAL } restart() { stop start } reload() { echo -n $"Reloading $desc ($prog):" killproc $prog -HUP RETVAL=$? 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
# chmod +x/etc/init.d/memcached
set
添加新的鍵值對,若是以存在,將會重寫
add
當緩存中不存在鍵時,add
命令纔會向緩存中添加一個鍵值對。若是緩存中已經存在鍵,則以前的值將仍然保持相同,而且將 得到響應NOT_STORED。
replace
僅當鍵已經存在時,replace
命令纔會替換緩存中的鍵。若是緩存中不存在鍵,那麼您將從 memcached 服務器接受到 一條 NOT_STORED 響應。
get
命令用於檢索與以前添加的鍵值對相關的值。
gets 同get,但返回的信息要多餘get
delete
用於刪除 memcached 中的任何現有值。您將使用一個鍵調用 delete
,若是該鍵存在於緩存中,則刪除該值。若是不存 在,則返回一條 NOT_FOUND 消息。
append 在一個存在的項後增長數據。
prepend 在一個存在的項首增長數據
stats 當前memcached實例信息
flush_all 清理緩存中的全部鍵值對
stats slabs顯示slabs信息,能夠獲取每一個slabs的chunksize長度,從而肯定數據到底保存在哪一個slab
stats items 顯示slab中item數目
修改命令語法:
command <key><flags> <expiration time> <byte>
<value>
key
用於查找緩存值
flags
能夠包括鍵值對的×××參數,客戶機使用它存儲關於鍵值對的額外信息
expiration time
緩存中保存鍵值對的時間,秒爲單位,
0
表示永遠
bytes
緩存中存儲的字節
value
存儲的值
# telnet localhost 11211 set xiaobai 0 0 3 123 STORED add xiaobai 0 0 3 123 NOT_STORED get xiaobai VALUE xiaobai 0 3 123 END gets xiaobai VALUE xiaobai 0 3 32 123 END append xiaobai 0 0 3 456 STORED get xiaobai VALUE xiaobai 0 6 123456 END prepend xiaobai 0 0 3 789 STORED get xiaobai VALUE xiaobai 0 9 789123456 END delete xiaobai DELETED get xiaobai END
安裝memcached的php擴展
#cd memcache-2.2.7 # /usr/local/php/bin/phpize #./configure --with-php-config=/usr/local/php/bin/php-config --enable-memcache #make #make install 安裝完成後會提示 Installingshared extensions: /usr/local/php/lib/php/extensions/no-debug-zts-20100525/
#mkdir /etc/php.d #vim /etc/php.d/memcache.ini extension = /usr/local/php/lib/php/extensions/no-debug-zts-20100525/memcache.so 或vim /etc/php.ini extension =/usr/local/php/lib/php/extensions/no-debug-zts-20100525/memcache.so
測試PHP擴展是否安裝成功
#vim /usr/html/test.php <?php $mem= new Memcache; $mem->connect('127.0.0.1',11211); $mem->set('test','Hello xiaoming',0,12); $val= $mem->get('test'); echo$val; ?>