Memcached的原理與應用(未完)

1.Memcached的介紹

  Memcached是一套開源、分佈式、高性能的內存對象緩存系統,通常用於在減少web應用對數據庫的訪問而提升整體性能。Memcached是基於內存的"key-value(鍵值)"的緩存服務器,並且key是經過HASH編碼的,使得其查找速度非常迅速,不會因爲數據過多而出現查詢過慢的問題。

  Memcached在多數場景下作爲數據庫前端的公共cache使用,因爲它比數據庫少了很多SQL的解析、磁盤操作等開銷,而且使用內存來管理數據,可以提供比數據庫更好的性能。除此之外,Memcached也可以作爲服務器之間數據共享的存儲媒介。

  Memcached不支持數據的持久化,也就是當系統宕機,數據全部丟失。而且,Memcached本身是一個客戶端分佈式緩存方案,它的"分佈式"功能依賴於客戶端的算法。

  注:key-value指得是,一個是關鍵字(查找的依據),一個是value(所要的值),每個key對應一個value。

  注:只要是可序列化的數據,Memcached就可以緩存。


2.Memcached的設計思想

  Memcached僅僅是一個緩存服務器,爲程序員提供緩存功能,其設計哲學思想主要反映在如下:

  (1) 簡單key/value緩存:服務器不關心數據本身的意義及結構,只要是可序列化數據即可緩存。存儲項由"鍵、過期時間、可選的標識及數據"四個部分組成;

  (2) 功能的實現一半依賴於客戶端,一辦依賴於服務器端:

    客戶端負責發送存儲項至服務器端、從服務端獲取數據、以及當無法連接至服務器時採取相應的動作;

    服務器端負責接收來自客戶端的數據並將其緩存到內存中,而且需要保證數據的有效性(管理過期超時項)。

  (3) 服務器的分佈式特徵:各個Memcached服務器之間互相不通信,都是獨立的,不共享數據;

  (4) O(1)的執行效率:由於其的key基於HASH編碼,並且數據存放於內存中,所以其速度是O(1)級的(在5條數據中查找1條數據的速度和在100條數據中查找1條的速度是一樣的);

  (5) 懶惰模式清理過期的數據:默認情況下,Memcached是一個LRU緩存,同時,它按事先規定的時長清理過期的數據;但事實上,Memcached不會刪除任何已緩存數據,只不過在數據過期時不在對客戶端所見;而且,Memcached也不會真正的按期限去清理緩存,只有當get命令命中目標時才檢查該數據是否過期。


3.Memcached的C/S交互

  Memcached提供了爲數不多的幾個命令來實現客戶端/服務器端的交互,C/S基於memcached的協議通信:

  (1) 存儲類命令:set(設置),add(新增),replace(替換),append(緩存內容後追加),prepend(緩存內容前追加)

  (2) 獲取數據類命令:get(獲取),delete(刪除),incr/decr(數字+1,例如微博轉發數)

  (3) 統計類命令:stats(整體狀態信息),stats itmes(itmes信息),stats slabs(slbas信息),stats sizes(slbas大小信息)

  (4) 清理命令:flush_all

  注:Memached協議具有兩種通信模式:文本格式(默認)和二進制格式。


4.Memcached的內存分配

  Linux是基於malloc()申請內存,free()釋放內存,由於memcached基於內存進行數據進行管理,通常其緩存數據的頻率比較大,所以會導致memcached會頻繁向Linux(Kernel)發起申請、釋放的請求,而Linux的malloc()和free()的性能是低效的,爲了解決這個問題,memached基於slab allocator機制對數據進行申請、釋放。

  在slab allocator的機制上,memcached啓動後申請一段內存頁面(Page,內存空間;一個頁面默認爲1MB),並使用slab allocator對內存頁面進行"格式化",將其格式化成爲特定大小的N個chunk(區塊,緩存數據的空間;例如格式化10個1k的區塊,5個2k的區塊;同類的區塊稱作slab class)。從而避免內存的頻繁釋放、回收,但是由於一個數據只能存放於一個chunk中,此機制可能會浪費內存空間(當你有1k、2k、4k三種chunk時,需要存儲一個3k的數據,此時只能存儲在4k的chunk中,也就浪費了1k的空間)。

  slab allocator的chunk分配上,需要指定增長因子,例如從1k開始,增長因子如果2,則每次遞歸2k。增長因子不能過大,否則會出現嚴重的空間浪費。


5.Memcached的分佈式:

  Memcached的分佈式是由客戶端實現的,也就是當應用到Memcached的分佈式緩存(多臺memcached服務器)時,爲了保證緩存的命中率,我們需要讓客戶端進行計算,使其可以將請求分配到已經緩存了該資源的Memcached上(存儲也是同樣的過程)。一般常用的有兩種算法,一種是根據餘數來計算分佈,另一種是根據一致性HASH算法來計算分佈。餘數算法先求得鍵的整數散列值,再除以服務器臺數,根據餘數來選擇服務器。一致性HASH先算出Memcached服務器節點的散列值,並將其分散到0到2^32次方的圓上,然後用同樣的方法算出鍵的值並映射到圓上,最後從數據映射到的位置開始順時針查找,以找到的第一臺服務器爲準。


6.Memcached的併發模型:

  Memcached會涉及到併發請求,所以其依賴於libevent庫。libevent庫就包含了常用的IO模型,epoll,poll,select。新版本一般爲單進程響應多請求。


7.Memcached的客戶端(擴展庫):

  程序員在開發時,調用memcached的API,memcached的功能才能生效。介於調用API的複雜性,大多數的程序開發語言都提供了已經打包好的擴展庫,使得程序員在使用時只需要調用庫功能即可:

  (1) memcached:php連接memcached服務器可以使用的擴展庫;

  (2) memcache:php連接memcached服務器可以使用的另一個擴展庫,少用;

  (3) libmemcached:C連接memcached的擴展庫


8.Memcached的安裝及配置:

  8.1 memcached的安裝:

[root@localhost ~]# yum install -y memcached

  8.2 memcached的常用組件:

[root@localhost ~]# rpm -ql memcached
/etc/rc.d/init.d/memcached  #memcached啓動腳本
/etc/sysconfig/memcached    #memcached啓動腳本配置文件
/usr/bin/memcached          #memcahed二進制程序,服務器端軟件
/usr/bin/memcached-tool     #memcached工具
.....

  8.3 memcached二進制程序的常用選項及參數:

-l <ip_addr>  #監聽的IP地址
-d        #以獨立守護進程模式運行,默認運行在前臺;Linux有三種進程:超級守護進程(負責多個進程的管理,xinetd)、獨立守護進程(自身管理的進程)、瞬時守護進程(超級守護進程管理的進程)
-u <username>  #指定程序運行者的身份
-m <num>    #定義memcached可以使用的內存空間,默認是64MB
-c <num>    #最大併發連接
-p <num>    #監聽的TCP端口,默認爲11211
-U <num>    #監聽的UDP端口,默認爲11211
-M        #指定當內存耗盡時,memcached不清空緩存,而返回錯誤信息
-n <size>    #指定最小的chunk大小
-f <factor>   #指定chunk的增長因子
-t <threads>  #指定memcached的工作線程數,默認爲4
-B <proto>   #指定memcached協議類型,默認爲文本模式;

  8.4 啓動Memcached程序:

[root@localhost ~]# memcached -u memcached -d
[root@localhost ~]# ss -tunl|grep "11211"
udp    UNCONN     0      0                      *:11211                 *:*     
udp    UNCONN     0      0                     :::11211                :::*     
tcp    LISTEN     0      128                   :::11211                :::*     
tcp    LISTEN     0      128                    *:11211                 *:*

  8.5 測試連接到Memcached服務器並寫入一條數據:

[root@localhost ~]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
add testkey 0 60 5   #add的格式爲 "add key(鍵) flag(標識) timeout(超時時間) length(長度)"
12345   #value(key的值)
STORED  #已經存儲的提示
get testkey  #獲取testkey這個鍵的信息及值
VALUE testkey 0 5  #鍵的信息
12345   #鍵的值
END  #結束符

  8.6 PHP安裝memcached擴展:

  前面說過,要想使用Memcached的功能,就需要開發人員在編寫程序的時候調用memcached的API,不過,大多數的程序都已經提供了Memcached的擴展庫,這樣只需要調用該庫的功能即可。同樣的,PHP也爲Memcached提供了擴展庫,這裏以memcached這個擴展庫(注意:memcached的m是小寫的,這個庫的名字就叫做memcached)爲例:








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章