Memcache技術分享:介紹、使用、存儲、算法、優(yōu)化、命中率

1、memcached 介紹

1.1 memcached是什么?

memcached 是以LiveJournal旗下Danga Interactive 公司的Brad Fitzpatric 為首開發(fā)的一款軟件。現(xiàn)在已成為mixi、hatena、Facebook、Vox、LiveJournal 等眾多服務中提高Web

應用擴展性的重要因素。許多Web 應用都將數(shù)據(jù)保存到RDBMS 中,應用服務器從中讀取數(shù)據(jù)并在瀏覽器中顯示。但隨著數(shù)據(jù)量的增大、訪問的集中,就會出現(xiàn)RDBMS 的負擔加重、數(shù)據(jù)庫響應惡化、網(wǎng)站顯示延遲等重大影響。這時就該memcached 大顯身手了。memcached 是高性能的分布式內存緩存服務器。一般的使用目的是,通過緩存數(shù)據(jù)庫查詢結果,減少數(shù)據(jù)庫訪問次數(shù),以提高動態(tài)Web 應用的速度、提高可擴展性。

內置內存存儲方式

研究memcached這個產品,首先從它的內存模型開始:我們知道c++里分配內存有兩種方式,預先分配和動態(tài)分配,顯然,預先分配內存會使程序比較快,但是它的缺點是不能有效利用內存,而動態(tài)分配可以有效利用內存,但是會使程序運行效率下降,memcached的內存分配就是基于以上原理,顯然為了獲得更快的速度,有時候我們不得不以空間換時間。

Memcached的高性能源于兩階段哈希(two-stage hash)結構。Memcached就像一個巨大的、存儲了很多對的哈希表。通過key,可以存儲或查詢任意的數(shù)據(jù)。 客戶端

可以把數(shù)據(jù)存儲在多臺memcached上。當查詢數(shù)據(jù)時,客戶端首先參考節(jié)點列表計算出key的哈希值(階段一哈希),進而選中一個節(jié)點;客戶端將請求發(fā)送給選中的節(jié)點,然后

memcached節(jié)點通過一個內部的哈希算法(階段二哈希),查找真正的數(shù)據(jù)(item)并返回給客戶端。從實現(xiàn)的角度看,memcached是一個非阻塞的、基于事件的服務器程序。

為了提高性能,memcached 中保存的數(shù)據(jù)都存儲在memcached 內置的內存存儲空間中。由于數(shù)據(jù)僅存在于內存中,因此重啟memcached、重啟操作系統(tǒng)會導致全部數(shù)據(jù)消失。另外,內容容量達到指定值之后,就基于LRU(Least Recently Used)算法自動刪除不使用的緩存。memcached 本身是為緩存而設計的服務器,因此并沒有過多考慮數(shù)據(jù)的永久性問題

memcached 不互相通信的分布式

memcached 盡管是“分布式”緩存服務器,但服務器端并沒有分布式功能。各個

memcached 不會互相通信以共享信息。那么,怎樣進行分布式呢?這完全取決于客戶端的實現(xiàn)。

2.2 memcached啟動

memcached 啟動的命令在安裝目錄的bin 二級目錄下,如/home/test/app/memcahced-1.4.2/bin/memcached -p 11222 -m 128–d

常用的一些啟動選項介紹選項說明

-p 偵聽的端口,默認為11211

-m 使用內存大小,默認的64m

-d 作為daemon 在后臺啟動

-vv 用very vrebose 模式啟動,調試信息和錯誤輸出到控制臺

-l 偵聽的地址,默認為所有可以訪問的地址

-M 用于在內存溢出的時候,返回一個錯誤,禁止自動的移出數(shù)

據(jù),替代的是返回一個error

-P Pid 文件存在的路徑,僅限加上-d 參數(shù)是用

-c 最大同時的連接數(shù),默認為1024

其它的一些選項,可以通過–h 命令來進行查看

2.3命令行訪問memcached

下面假設memcached 啟動時的-p 參數(shù)為11311,命令操作在啟動memcached

本機首先telnet 連接到memcached 服務器

telnet 127.0.0.1 11311

telnet 成功之后,大概會顯示下面的信息

Trying 127.0.0.1...

Connected to localhost.localdomain (127.0.0.1).

Escape character is '^]'.

各種狀態(tài)(stats)

STAT \r\n

如:stats命令,則返回以下信息:

stats

STAT pid 26804

STAT uptime 182783

STAT time 1404973716

STAT version 1.4.13

STAT libevent 2.0.11-stable

STAT pointer_size 64

STAT rusage_user 2.320647

STAT rusage_system 5.411177

STAT curr_connections 34

STAT total_connections 558

STAT connection_structures 37

STAT reserved_fds 20

STAT cmd_get 127292

STAT cmd_set 60056

STAT cmd_flush 145

STAT cmd_touch 0

STAT get_hits 83811

STAT get_misses 43481

STAT delete_misses 15970

STAT delete_hits 11992

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 14300156

STAT bytes_written 11507140

STAT limit_maxbytes 134217728 ? ???# ?分配給memcache的內存大小(字節(jié))

STAT accepting_conns 1

STAT listen_disabled_num 0

STAT threads 4

STAT conn_yields 0

STAT hash_power_level 16

STAT hash_bytes 524288

STAT hash_is_expanding 0

STAT expired_unfetched 16884

STAT evicted_unfetched 0

STAT bytes 609350 ???# 當前服務器存儲items占用的字節(jié)數(shù)

STAT curr_items 4668 ???# 服務器當前存儲的items數(shù)量

STAT total_items 60056

STAT evictions 0 ? ??# 分配給memcache的空間用滿后需要刪除舊的items數(shù),踢出。

STAT reclaimed 27160 ?#回收再利用,已過期的數(shù)據(jù)條目來存儲新數(shù)據(jù)。

END

存儲命令(set ,add ,replace)

客戶端會發(fā)送一行像這樣的命令:

\r\n

如:

set key1 0 600 5\r\nvalue\r\n

add key2 0 500 2\r\n

replace key1 0 600 6\r\nvalue1\r\n

詳細的命令說明,可以見附錄的memcached 中英文協(xié)議內容

讀取命令(get)

命令如下:get *\r\n

- * 表示一個或多個鍵值,由空格隔開的字串

如:

get key1

VALUE key1 0 7

value12

刪除命令(delete)

命令如:delete \r\n

是客戶端希望服務器刪除的內容的鍵名

- 是一個單位為秒的時間(或代表直到某一刻的Unix時間),在該時間內服務器會拒絕對于此鍵名的“add”和“replace”命令。此時內容被放入delete隊列,無法再通過“get”得到該內容,也無法是用“add”和“replace”命令(但是“set”命令可用)。直到指定時間,這些內容被最終從服務器的內存中徹底清除

參數(shù)是可選的,缺省為0(表示內容會立刻清除,并且隨后的存儲命令均可用

如:delete key1

退出命令(quit)

如:quit

4、理解memcached 的內存存儲

Memcache內存分配機制

Memcache使用了Slab Allocator的內存分配機制:按照預先規(guī)定的大小,將分配的內存分割成特定長度的塊,以完全解決內存碎片問題

Memcache的存儲涉及到slab,page,chunk三個概念

1.Chunk為固定大小的內存空間,默認為96Byte。

2.page對應實際的物理空間,1個page為1M。

3.同樣大小的chunk又稱為slab。

4.1Slab Allocation機制:整理內存以便重復使用

最近的memcached 默認情況下采用了名為Slab Allocator 的機制分配、管理內存。在該機制出現(xiàn)以前,內存的分配是通過對所有記錄簡單地進行malloc和free 來進行的。但是,這種方式會導致內存碎片,加重操作系統(tǒng)內存管理器的負擔,最壞的情況下,會導致操作系統(tǒng)比memcached 進程本身還慢。Slab Allocator 就是為解決該問題而誕生的

Slab Allocation 的原理相當簡單。將分配的內存分割成各種尺寸的塊

(chunk),并把尺寸相同的塊分成組(chunk 的集合)

而且,slab allocator 還有重復使用已分配的內存的目的。也就是說,分配到的內存不會釋放,而是重復利用。

Slab Allocation 的主要術語

Page

分配給Slab 的內存空間,默認是1MB。分配給Slab 之后根據(jù)slab 的大小切分成chunk。

Chunk

用于緩存記錄的內存空間。

Slab Class

特定大小的chunk 的組

4.2Slab中緩存記錄的原理

memcached 根據(jù)收到的數(shù)據(jù)的大小,選擇最適合數(shù)據(jù)大小的slab,memcached 中保存著slab 內空閑chunk 的列表,根據(jù)該列表選擇chunk,然

后將數(shù)據(jù)緩存于其中

4.3 Slab Allocator的缺點

由于分配的是特定長度的內存,因此無法有效利用分配的內存。例如,將100 字節(jié)的數(shù)據(jù)緩存到128 字節(jié)的chunk 中,剩余的28字節(jié)就浪費了

對于該問題目前還沒有完美的解決方案,但在文檔中記載了比較有效的解決方案。就是說,如果預先知道客戶端發(fā)送的數(shù)據(jù)的公用大小,或者僅緩存大小相同的數(shù)據(jù)的情況下,只要使用適合數(shù)據(jù)大小的組的列表,就可以減少浪費。但是很遺憾,現(xiàn)在還不能進行任何調優(yōu),只能期待以后的版本了。但是,我們可以調節(jié)slab class 的大小的差別。接下來說明growth factor 選項。

4.4使用Growth Factor進行調優(yōu)

memcached 在啟動時指定Growth Factor 因子(通過f 選項),就可以在某種程度上控制slab 之間的差異。默認值為1.25。但是,在該選項出現(xiàn)之前,這個因子曾經固定為2,稱為“powers of 2”策略。

下面是啟動后的verbose 輸出:

slab class 1: chunk size 128 perslab 8192

slab class 2: chunk size 256 perslab 4096

slab class 3: chunk size 512 perslab 2048

slab class 4: chunk size 1024 perslab 1024

slab class 5: chunk size 2048 perslab 512

slab class 6: chunk size 4096 perslab 256

slab class 7: chunk size 8192 perslab 128

slab class 8: chunk size 16384 perslab 64

slab class 9: chunk size 32768 perslab 32

slab class 10: chunk size 65536 perslab 16

slab class 11: chunk size 131072 perslab 8

slab class 12: chunk size 262144 perslab 4

slab class 13: chunk size 524288 perslab 2

可見,從128 字節(jié)的組開始,組的大小依次增大為原來的2 倍。這樣設置的問題是,slab 之間的差別比較大,有些情況下就相當浪費內存。因此,為盡量減少內存浪費,兩年前追加了growth factor 這個選項來看看現(xiàn)在的默認設置(f=1.25)時的輸出(篇幅所限,這里只寫到第10 組):

slab class 1: chunk size 88 perslab 11915

slab class 2: chunk size 112 perslab 9362

slab class 3: chunk size 144 perslab 7281

slab class 4: chunk size 184 perslab 5698

slab class 5: chunk size 232 perslab 4519

slab class 6: chunk size 296 perslab 3542

slab class 7: chunk size 376 perslab 2788

slab class 8: chunk size 472 perslab 2221

slab class 9: chunk size 592 perslab 1771

slab class 10: chunk size 744 perslab 1409

可見,組間差距比因子為2 時小得多,更適合緩存幾百字節(jié)的記錄。從上面的輸出結果來看,可能會覺得有些計算誤差,這些誤差是為了保持字節(jié)數(shù)的對齊而故意設置的。將memcached 引入產品,或是直接使用默認值進行部署時,最好是重新計算一下數(shù)據(jù)的預期平均長度,調整growth factor,以獲得最恰當?shù)脑O置。內存是珍貴的資源,浪費就太可惜了。

item占用空間計算

*nsuffix = (uint8_t) snprintf(suffix, 40, " %d %d\r\n", flags, nbytes – 2);? ? ?return sizeof(item) + nkey + *nsuffix + nbytes;

*nsuffix=" %d %d\r\n”的長度

如果ITEM_CAS標志設置時,這里有8字節(jié)的數(shù)據(jù)

完整的item長度是鍵長+值長+后綴長+item結構大?。?8字節(jié)) + 8

item.length=56+key.lenght+value.length+后綴長

32位機器 item結構是32字節(jié)

64位機器 itme結構是48字節(jié)

memcache存儲的時候對key的長度有限制,php和C的最大長度都是250

5、memcached 刪除機制

memcached 是緩存,不需要永久的保存到服務器上,本章介紹memcache 的刪除機制

5.1 memcached在數(shù)據(jù)刪除方面有效的利用資源

Memcached 不會釋放已經分配的內存,記錄過期之后,客戶端無法再看到這一條記錄,其存儲空間就可以利用。

Lazy Expiration

memcached 內部不會監(jiān)視記錄是否過期,而是在get 時查看記錄的時間戳,檢查記錄是否過期。這種技術被稱為lazy(惰性)expiration。因此,memcached不會在過期監(jiān)視上耗費CPU 時間

5.2 LRU:從緩存中有效刪除數(shù)據(jù)的原理

1.search->refcount?==?0 ?&& 已經過期的 ?刪除

2.tries?=?50;?//?最多嘗試50次?? ?LRU隊列tail 查找?search->refcount?==?0 ?第一個 刪除

3.?tries?=?50;?//?最多嘗試50次?? ?LRU隊列tail 查找search->refcount !=?0 查詢時間(超過3小時)的item??第一個 刪除

memcached 會優(yōu)先使用已超時的記錄的空間,但即使如此,也會發(fā)生追加新記錄時空間不足的情況,此時就要使用名為Least Recently Used(LRU)機制來分配空間。顧名思義,這是刪除“最近最少使用”的記錄的機制。因此,當memcached 的內存空間不足時(無法從slab class 獲取到新的空間時),就從最近未被使用的記錄中搜索,并將其空間分配給新的記錄。從緩存的實用角度來看,該模型十分理想。不過,有些情況下LRU 機制反倒會造成麻煩。memcached 啟動時通過“M”參數(shù)可以禁止LRU,如下所示:

$ memcached -M –m 1024

啟動時必須注意的是,小寫的“m”選項是用來指定最大內存大小的。不指定具體數(shù)值則使用默認值64MB。

指定“M”參數(shù)啟動后,內存用盡時memcached 會返回錯誤。話說回來,memcached 畢竟不是存儲器,而是緩存,所以推薦使用LRU

6、memcached 的分布式算法

6.1memcached的分布式

memcached 雖然稱為“分布式”緩存服務器,但服務器端并沒有“分布式”功能。memcached 的分布式,則是完全由客戶端程序庫實現(xiàn)的。這種分布式是memcached 的最大特點

memcached的分布式是什么意思?

下面假設memcached 服務器有node1~node3 三臺,應用程序要保存鍵名為“tokyo”、“kanagawa”、“chiba”、“saitama”、“gunma”的數(shù)據(jù)

首先向memcached 中添加“tokyo”。將“tokyo”傳給客戶端程序庫后,客戶端實現(xiàn)的算法就會根據(jù)“鍵”來決定保存數(shù)據(jù)的memcached 服務器。服務器選定后,即命令它保存“tokyo”及其值

同樣,“kanagawa”、“chiba”、“saitama”、“gunma”都是先選擇服務器再保接下來獲取保存的數(shù)據(jù)。獲取時也要將要獲取的鍵“tokyo”傳遞給函數(shù)庫。函數(shù)庫通過與數(shù)據(jù)保存時相同的算法,根據(jù)“鍵”選擇服務器。使用的算法相同,就能選中與保存時相同的服務器,然后發(fā)送get 命令。只要數(shù)據(jù)沒有因為某些原因被刪除,就能獲得保存的值。

這樣,將不同的鍵保存到不同的服務器上,就實現(xiàn)了memcached 的分布式。memcached 服務器增多后,鍵就會分散,即使一臺memcached 服務器發(fā)生故障無法連接,也不會影響其他的緩存,系統(tǒng)依然能繼續(xù)運行

6.2余數(shù)分布式算法

就是“根據(jù)服務器臺數(shù)的余數(shù)進行分散”。求得鍵的整數(shù)哈希值,再除以服務器臺數(shù),根據(jù)其余數(shù)來選擇服務器

余數(shù)算法的缺點

余數(shù)計算的方法簡單,數(shù)據(jù)的分散性也相當優(yōu)秀,但也有其缺點。那就是當添加或移除服務器時,緩存重組的代價相當巨大。添加服務器后,余數(shù)就會產生巨變,這樣就無法獲取與保存時相同的服務器,從而影響緩存的命中。

6.3Consistent Hashing(一致哈希)

知識補充:哈希算法,即散列函數(shù)。將任意長度的二進制值映射為較短的固定長度的二進制值,這個小的二進制值稱為哈希值。哈希值是一段數(shù)據(jù)唯一且極其緊湊的數(shù)值表示形式。如果散列一段明文而且哪怕只更改該段落的一個字母,隨后的哈希都將產生不同的值。要找到散列為同一個值的兩個不同的輸入,在計算上是不可能的,所以數(shù)據(jù)的哈希值可以檢驗數(shù)據(jù)的完整性。一般用于快速查找和加密算法。(常見的有MD5,SHA-1)

Consistent Hashing的簡單說明

Consistent Hashing 如下所示:首先求出memcached 服務器(節(jié)點)的哈希值,并將其配置到0~232 的圓(continuum)上。然后用同樣的方法求出存儲數(shù)據(jù)的鍵的哈希值,并映射到圓上。然后從數(shù)據(jù)映射到的位置開始順時針查找,將數(shù)據(jù)保存到找到的第一個服務器上。如果超過232 仍然找不到服務器,就會保存到第一臺memcached 服務器上。

從上圖的狀態(tài)中添加一臺memcached 服務器。余數(shù)分布式算法由于保存鍵的服務器會發(fā)生巨大變化,而影響緩存的命中率,但Consistent Hashing中,只有在continuum 上增加服務器的地點逆時針方向的第一臺服務器上的鍵會受到影響

Consistent Hashing:添加服務器

因此,Consistent Hashing 最大限度地抑制了鍵的重新分布。而且,有的Consistent Hashing 的實現(xiàn)方法還采用了虛擬節(jié)點的思想。使用一般的hash函數(shù)的話,服務器的映射地點的分布非常不均勻。因此,使用虛擬節(jié)點的思想,為每個物理節(jié)點(服務器)在continuum上分配100~200 個點。這樣就能抑制分布不均勻,最大限度地減小服務器增減時的緩存重新分布。

通過上文中介紹的使用Consistent Hashing 算法的memcached 客戶端函數(shù)庫進行測試的結果是,由服務器臺數(shù)(n)和增加的服務器臺數(shù)(m)計算增加服務器后的命中率計算公式如下:

(1 n/(n+m)) * 100

存儲命令

\r\n

- 是set, add,或者repalce

- 是接下來的客戶端所要求儲存的數(shù)據(jù)的鍵值

- 是在取回內容時,與數(shù)據(jù)和發(fā)送塊一同保存服務器上的任意16位無符號整形(用十進制來書寫)??蛻舳丝梢杂盟鳛椤拔挥颉眮泶鎯σ恍┨囟ǖ男畔ⅲ凰鼘Ψ掌魇遣煌该鞯?。

- 是終止時間。如果為0,該項永不過期(雖然它可能被刪除,以便為其他緩存項目騰出位置)。如果非0(Unix 時間戳或當前時刻的秒偏移),到達終止時間后,客戶端無法再獲得這項內容。

- 是隨后的數(shù)據(jù)區(qū)塊的字節(jié)長度,不包括用于分野的“\r\n”。它可以是0(這時后面跟隨一個空的數(shù)據(jù)區(qū)塊)。

- 是大段的8位數(shù)據(jù),其長度由前面的命令行中的指定。

? set 意思是“儲存此數(shù)據(jù)”

? add 意思是“儲存此數(shù)據(jù),只在服務器*未*保留此鍵值的數(shù)據(jù)時”

? replace 意思是“儲存此數(shù)據(jù),只在服務器*曾*保留此鍵值的數(shù)據(jù)時”

發(fā)送命令行和數(shù)據(jù)區(qū)塊以后,客戶端等待回復,可能的回復如下:

- "STORED\r\n"表明成功.

- "NOT_STORED\r\n"表明數(shù)據(jù)沒有被存儲,但不是因為發(fā)生錯誤。這通常意味著add或replace 命令的條件不成立,或者,項目已經位列刪除隊列(參考后文的“delete”命令)。

取回命令

get *\r\n

- * 表示一個或多個鍵值,由空格隔開的字串這行命令以后,客戶端的等待0個或多個項目,每項都會收到一行文本,然后跟著數(shù)據(jù)區(qū)塊。所有項目傳送完畢后,服務器發(fā)送以下字串:"END\r\n"來指示回應完畢,服務器用以下形式發(fā)送每項內容:

VALUE \r\n

\r\n

- 是所發(fā)送的鍵名

- 是存儲命令所設置的記號

- 是隨后數(shù)據(jù)塊的長度,*不包括* 它的界定符“\r\n”

- 是發(fā)送的數(shù)據(jù)

如果在取回請求中發(fā)送了一些鍵名,而服務器沒有送回項目列表,這意味著服務器沒這些鍵名(可能因為它們從未被存儲,或者為給其他內容騰出空間而被刪除,或者到期,或者被已客戶端刪除)。

刪除

delete \r\n

- 是客戶端希望服務器刪除的內容的鍵名

- 是一個單位為秒的時間(或代表直到某一刻的Unix時間),在該時間內服務器會拒絕對于此鍵名的“add”和“replace”命令。此時內容被放入delete隊列,無法再通過“get”得到該內容,也無法是用“add”和“replace”命令(但是“set”命令可用)。直到指定時間,這些內容被最終從服務器的內存中徹底清除。參數(shù)是可選的,缺省為0(表示內容會立刻清除,并且隨后的存儲命令均可用)。

此命令有一行回應:- "DELETED\r\n"表示執(zhí)行成功

- "NOT_FOUND\r\n"表示沒有找到這項內容

增加/減少

命令“incr”和“decr”被用來修改數(shù)據(jù),當一些內容需要替換、增加或減少時。這些數(shù)據(jù)必須是十進制的32位無符號整新。如果不是,則當作0 來處理。修改的內容必須存在,當使用“incr”/“decr”命令修改不存在的內容時,不會被當作0處理,而是操作失敗。

客戶端發(fā)送命令行:

incr \r\n或decr \r\n

- 是客戶端希望修改的內容的建名

- 是客戶端要增加/減少的總數(shù)。

回復為以下集中情形:

- "NOT_FOUND\r\n"指示該項內容的值,不存在。

- \r\n ,是增加/減少。

注意"decr"命令發(fā)生下溢:如果客戶端嘗試減少的結果小于0 時,結果會是0。"incr" 命令不會發(fā)生溢出。

狀態(tài)

命令"stats" 被用于查詢服務器的運行狀態(tài)和其他內部數(shù)據(jù)。有兩種格式。不帶參數(shù)的:

stats\r\n

這會在隨后輸出各項狀態(tài)、設定值和文檔。另一種格式帶有一些參數(shù):

stats \r\n

通過,服務器傳回各種內部數(shù)據(jù)。因為隨時可能發(fā)生變動,本文不提供參數(shù)的種類及其傳回數(shù)據(jù)。

各種狀態(tài)

受到無參數(shù)的"stats"命令后,服務器發(fā)送多行內容,如下:

STAT \r\n

服務器用以下一行來終止這個清單:END\r\n,在每行狀態(tài)中, 是狀態(tài)的名字,使狀態(tài)的數(shù)據(jù)。以下清單,是所有的狀態(tài)名稱,數(shù)據(jù)類型,和數(shù)據(jù)代表的含義。

在“類型”一列中,"32u"表示32 位無符號整型,"64u"表示64 位無符號整型,"32u:32u"表示用冒號隔開的兩個32 位無符號整型。

名稱

類型

含義

pid

32u

服務器進程ID

uptime

32u

服務器運行時間,單位秒

time

32u

服務器當前的UNIX時間

version

string

服務器的版本號

rusage_user

32u

該進程累計的用戶時間(秒:微妙)

rusage_system

32u

該進程累計的系統(tǒng)時間(秒:微妙)

curr_items

32u

服務器當前存儲的內容數(shù)量

total_items

32u

服務器啟動以來存儲過的內容總數(shù)

bytes

64u

服務器當前存儲內容所占用的字節(jié)數(shù)

curr_connections

32u

連接數(shù)

total_connections

32u

服務器運行以來接受的連接總數(shù)

connection_structures

32u

服務器分配的連接結構的數(shù)量

cmd_get

32u

取回請求總數(shù)

cmd_set

32u

存儲請求總數(shù)

get_hits

32u

請求成功的總次數(shù)

get_misses

32u

請求失敗的總次數(shù)

bytes_read

64u

服務器從網(wǎng)絡讀取到的總字節(jié)數(shù)

bytes_written

64u

服務器向網(wǎng)絡發(fā)送的總字節(jié)數(shù)

limit_maxbytes

32u

服務器在存儲時被允許使用的字節(jié)總數(shù)

如果不想每次通過輸入stats來查看memcache狀態(tài),可以通過echo "stats" |nc ?ip port 來查看,例如:echo "stats" | nc 127.0.0.1 9023。

7.Memcache 命中率

緩存命中率 = get_hits/cmd_get * 100% (總命中次數(shù)/總請求次數(shù))

要提高memcached的命中率,預估我們的value大小并且適當?shù)恼{整內存頁大小和增長因子是必須的。

命中率的提升可以通過多種方案實現(xiàn).

其一,提高服務獲取的內存總量

其二,提高空間利用率,這實際上也是另一種方式的增加內存總量

其三,應用一級別上再來一次LRU

其四,對于整體命中率,可以采取有效的冗余策略,減少分布式服務時某個server發(fā)生服務抖動的情況

8.一些注意

1. memcache已經分配的內存不會再主動清理。

2. memcache分配給某個slab的內存頁不能再分配給其他slab。

3. flush_all不能重置memcache分配內存頁的格局,只是給所有的item置為過期。

4. memcache最大存儲的item(key+value)大小限制為1M,這由page大小1M限制

5.由于memcache的分布式是客戶端程序通過hash算法得到的key取模來實現(xiàn),不同的語言可能會采用不同的hash算法,同樣的客戶端程序也有可能使用相異的方法,因此在多語言、多模塊共用同一組memcached服務時,一定要注意在客戶端選擇相同的hash算法

6.啟動memcached時可以通過-M參數(shù)禁止LRU替換,在內存用盡時add和set會返回失敗

7.memcached啟動時指定的是數(shù)據(jù)存儲量,沒有包括本身占用的內存、以及為了保存數(shù)據(jù)而設置的管理空間。因此它占用的內存量會多于啟動時指定的內存分配量,這點需要注意。

8.memcache存儲的時候對key的長度有限制,php和C的最大長度都是250

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容