memcached原理詳述及配置

若是一個網站流量很大,則查詢數據庫將會耗費大量時間。若是將常常查詢的的數據和對象緩存到內存中,則須要查詢數據庫時,直接返回內存中緩存的數據。這中靜態化方式則會高效不少。分佈式緩存系統是爲了解決數據庫服務器和web服務器直接的瓶頸。其中memcached是一個開源、高性能、分佈式的內存對象緩存系統。主要經過在內存中緩存數據和對象減輕數據庫的負載來加速動態web程序。內存中緩存的數據通php

過API的方式被存取,數據就像一張大的HASH表,以鍵-值對方式存在。html


wKiom1VlqXfDGk0RAADGGlK5jsk765.jpg



讀取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端口,默認爲112110表示關閉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個字節就浪費掉了。


wKioL1Vlq_WA5Gr2AABiXcuU-_8951.jpg



安裝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


基本 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;
?>
相關文章
相關標籤/搜索