memcached快取知識簡單梳理

散盡浮華發表於2016-10-22

 

memcached工作原理
基本概念:slab,page,chunk。
slab,是一個邏輯概念。它是在啟動memcached例項的時候預處理好的,每個slab對應一個chunk size,也就是說不同slab有不同的chunk size。具體分配多少個slab由引數 -f (增長因子)和 -n (chunk最小尺寸)決定的。
page,可以理解為記憶體頁。大小固定為1m。slab會在儲存請求時向系統申請page,並將page按chunk size進行切割。
chunk,是儲存使用者資料的最小單位。使用者資料item(包括key,value)最終會儲存到chunk內。chunk規格是固定的,如果使用者資料放進來後還有剩餘則這剩餘部分不能做其他用途。

memcached工作流程
memcahed例項啟動,根據 -f 和 -n 進行預分配slab。以 -n 為最小值開始,以 -f 為比值生成等比數列,直到1m為止(每個slab的chunk size都要按8的倍數進行補全,比如:如果按比值算是556的話,會再加4到560成為8的整倍數)。然後每個slab分配一個page。當使用者發來儲存請求時(key,value),memcached會計算key+value的大小,看看屬於哪個slab。確定slab後看裡面的是否有空閒chunk放key+value,如果不夠就再向系統申請一個page(如果此時已經達到 -m 引數設定的記憶體使用上限,則看是否設定了 -M 。如果設定了 -M 則返回錯誤提示,否則按LRU演算法刪除資料)。申請後將該page按本slab的chunk size 進行切割,然後分配一個來存放使用者資料。
注意:
1)chunk是在page裡面劃分的,而page固定為1m,所以chunk最大不能超過1m。
2)chunk實際佔用記憶體要加48B,因為chunk資料結構本身需要佔用48B。
3)如果使用者資料大於1m,則memcached會將其切割,放到多個chunk內。
4)已分配出去的page不能回收。

優化建議
1)-n 引數的設定,注意將此引數設定為1024可以整除的數(還要考慮48B的差值),否則餘下來的部分就浪費了。
2)不要儲存超過1m的資料。因為要拆成多個chunk,計算和時間成本都成倍增加。
3)善用stats命令檢視memcached狀態。
4)消滅eviction(被刪除的資料)。
造成eviction是因為記憶體不夠,有三個思路:
(1)在CPU有餘力的情況下開啟壓縮(PHP擴充套件);
(2)增加記憶體;
(3)調整-f引數,減少記憶體浪費。
5)調整業務程式碼,提高命中率。
6)快取小資料。省頻寬,省網路I/O時間,省記憶體。
7)根據業務特點,為資料尺寸區間小的業務分配專用的memcached例項。這樣可以調小 -f 引數,使資料集中存在少數幾個slab上,記憶體浪費較少。
啟動時最重要的引數:
-m 整個memcached最大記憶體
-f chunk大小增長因子
-n chunk最小分配空間
-C 禁用CAS
-vvv 列印詳細資訊
我們通過計算可以看出,每個slab的chunk size大小都是上一個大小的1.25倍,1.25就是memcached啟動時制定的-f的值,所以,要根據不同的業務場景調整,既要儘可能少的減少記憶體浪費,又要存得下我們業務中的資料,再舉個例子,加入我們的業務很BT,大小都是200kb,我們該怎麼做?那當然是要保證我們申請的chunk大小都是200kb了,雖然memcached並不支援這麼做。假如建立了38個slabs,最後資料全都落到了第20-25個slab中,那0-19和26-38的記憶體就被浪費了,這只是能評估出來的,還有一種情況,加入我們的chunk大小是500kb,資料才200kb,因為每個chunk都只能儲存一個,所以一個chunk就會有500kb-200kb的空間浪費,如果有一千萬個chunk要存,那將會浪費多少空間?所以,在使用memcached之前,先要評估你的資料,根據它去調整-f因子。

memcached引數使用介紹(Win7使用者要以管理員身份啟動命令視窗哦!)
-p 監聽的埠 
-l 連線的IP地址, 預設是本機 
-d start 啟動memcached服務 
-d restart 重起memcached服務 
-d stop|shutdown 關閉正在執行的memcached服務 
-d install 安裝memcached服務 
-d uninstall 解除安裝memcached服務 
-u 以的身份執行 (僅在以root執行的時候有效)  
-m 最大記憶體使用,單位MB。預設64MB 
-M 記憶體耗盡時返回錯誤,而不是刪除項 
-c 最大同時連線數,預設是1024 
-f 塊大小增長因子,預設是1.25 
-n 最小分配空間,key+value+flags預設是48 
-h 顯示幫助

清空memcache快取的方法
預設memcache會監聽11221埠,如果想清空伺服器上memecache的快取:
1)第一種方法:
# telnet localhost 11221
進入後,執行flush_all

2)第二種方法:
# echo "flush_all"|nc localhost 11221

------------------------php的memcache和memcached擴充套件區別------------------------
memcache文件:http://pecl.php.net/package/memcache
memcached文件:http://pecl.php.net/package/memcached

1)首先看下開發時間:
memcache最早是在2004年2月開發的,最後更新是在2013年4月;
memcached最早是在2009年1月開發的,最後更新是在2014年1月更新的。
所以memcache的歷史比memcached早。

2)memcache是一個原生版本,完全在php框架內開發的。與之對應的帶d的memcached是建立在libmemcached的基礎上,所以相對來說,memcached版本的功能更全一些。
在安裝memcache擴充套件的時候並不要求安裝其他東西,但是在安裝memcached的時候會要求安裝libmemcached;
libmemcached是memcache的C客戶端,它具有的優點是低記憶體,執行緒安全等特點。
比如新浪微博之前就全面將php的memcache替換成php的memcached,在高併發下,穩定性果斷提高。

3)memcache的方法特別少,比如getMulti,setMulti都是沒有的,基本就剩下最簡單的get和set了。
所以說memcached比memcache支援更多的memcache協議。

memcache方法列表:http://cn2.php.net/memcache
memcached方法列表:http://www.php.net/manual/zh/book.memcached.php

4)Memcache是原生實現的,支援OO和非OO兩套介面並存。而memcached是使用libmemcached,只支援OO介面。

5)memcached直接配置了session支援,只要稍微修改下配置檔案就可以把session儲存在memcache中了。

6)memcached還有個非常稱讚的地方,就是flag不是在操作的時候設定了,而是有了一個統一的setOption()。Memcached實現了更多的memcached協議。

7)memcached支援Binary Protocol,而memcache不支援。這意味著memcached會有更高的效能。不過memcached目前還不支援長連線。

----------------------------------------------------------------------------
連線到memcache後,使用stats命令檢視快取狀態

[root@bastion-IDC ~]# telnet 192.168.1.5 11211
Trying 192.168.1.5...
Connected to 192.168.1.5.
Escape character is '^]'.
stats
STAT pid 20439  ----> Memcached 程式的ID
STAT uptime 179982 ----> 程式執行時間
STAT time 1382361665 ---->當前時間
STAT version 1.4.15 ----> Memcached 版本
STAT libevent 1.4.13-stable
STAT pointer_size 32
STAT rusage_user 21.916668
STAT rusage_system 40.576831
STAT curr_connections 11
STAT total_connections 329
STAT connection_structures 23
STAT reserved_fds 20
STAT cmd_get 2363348 ----> 總共獲取資料的次數(等於 get_hits + get_misses )
STAT cmd_set 279971 ----> 總共設定資料的次數
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 2286284 ----> 命中了多少次資料,也就是從 Memcached 快取中成功獲取資料的次數
STAT get_misses 77064 ----> 沒有命中的次數
STAT delete_misses 30803
STAT delete_hits 48876
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 574591015
STAT bytes_written 4353057466
STAT limit_maxbytes 67108864 ----> 總的儲存大小,預設為 64M
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 262144
STAT hash_is_expanding 0
STAT bytes 4717345 ----> 當前所用儲存大小
STAT curr_items 5654
STAT total_items 58461
STAT expired_unfetched 17
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 49

以上資料的命中率:2286284/2363348 = 96.7% 說明當前命中率是比較高的。

相關文章