天天看點

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

[[email protected] ~]# yum install -y memcached      

  8.2 memcached的常用元件:

[[email protected] ~]# 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程式:

[[email protected] ~]# memcached -u memcached -d
[[email protected] ~]# 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伺服器并寫入一條資料:

[[email protected] ~]# 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)為例:

轉載于:https://blog.51cto.com/minux/1748759