一、memcached 介紹php
1.1 memcached 是什麼?node
memcached 是以LiveJournal旗下Danga Interactive 公司的Brad Fitzpatric 爲首開發的一款軟件。如今已成爲mixi、hatena、Facebook、Vox、LiveJournal 等衆多服務中提升Webc++
應用擴展性的重要因素。許多Web 應用都將數據保存到RDBMS 中,應用服務器從中讀取數據並在瀏覽器中顯示。但隨着數據量的增大、訪問的集中,就會出現RDBMS 的負擔加劇、數據庫響應惡化、網站顯示延遲等重大影響。這時就該memcached 大顯身手了。memcached 是高性能的分佈式內存緩存服務器。通常的使用目的是,經過緩存數據庫查詢結果,減小數據庫訪問次數,以提升動態Web 應用的速度、提升可擴展性。算法
內置內存存儲方式數據庫
研究memcached這個產品,首先從它的內存模型開始:咱們知道c++裏分配內存有兩種方式,預先分配和動態分配,顯然,預先分配內存會使程序比較快,可是它的缺點是不能有效利用內存,而動態分配能夠有效利用內存,可是會使程序運行效率降低,memcached的內存分配就是基於以上原理,顯然爲了得到更快的速度,有時候咱們不得不以空間換時間。瀏覽器
Memcached的高性能源於兩階段哈希(two-stage hash)結構。Memcached就像一個巨大的、存儲了不少<key,value>對的哈希表。經過key,能夠存儲或查詢任意的數據。 客戶端
能夠把數據存儲在多臺memcached上。當查詢數據時,客戶端首先參考節點列表計算出key的哈希值(階段一哈希),進而選中一個節點;客戶端將請求發送給選中的節點,而後
memcached節點經過一個內部的哈希算法(階段二哈希),查找真正的數據(item)並返回給客戶端。從實現的角度看,memcached是一個非阻塞的、基於事件的服務器程序。緩存
爲了提升性能,memcached 中保存的數據都存儲在memcached 內置的內存存儲空間中。因爲數據僅存在於內存中,所以重啓memcached、重啓操做系統會致使所有數據消失。另外,內容容量達到指定值以後,就基於LRU(Least Recently Used)算法自動刪除不使用的緩存。memcached 自己是爲緩存而設計的服務器,所以並無過多考慮數據的永久性問題服務器
memcached 不互相通訊的分佈式網絡
memcached 儘管是「分佈式」緩存服務器,但服務器端並無分佈式功能。各個app
memcached 不會互相通訊以共享信息。那麼,怎樣進行分佈式呢?這徹底取決於客戶端的實現。
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 用於在內存溢出的時候,返回一個錯誤,禁止自動的移出數
據,替代的是返回一個error
-P Pid 文件存在的路徑,僅限加上-d 參數是用
-c 最大同時的鏈接數,默認爲1024
其它的一些選項,能夠經過–h 命令來進行查看
2.3命令行訪問memcached
下面假設memcached 啓動時的-p 參數爲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 '^]'.
各類狀態(stats)
STAT <name> <value>\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的內存大小(字節)
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佔用的字節數
STAT curr_items 4668 # 服務器當前存儲的items數量
STAT total_items 60056
STAT evictions 0 # 分配給memcache的空間用滿後須要刪除舊的items數,踢出。
STAT reclaimed 27160 #回收再利用,已過時的數據條目來存儲新數據。
END
存儲命令(set ,add ,replace)
客戶端會發送一行像這樣的命令:
<command name> <key> <flags> <exptime> <bytes>\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 中英文協議內容
讀取命令(get)
命令以下:get <key>*\r\n
- <key>* 表示一個或多個鍵值,由空格隔開的字串
如:
get key1
VALUE key1 0 7
value12
刪除命令(delete)
命令如:delete <key> <time>\r\n
<key> 是客戶端但願服務器刪除的內容的鍵名
- <time> 是一個單位爲秒的時間(或表明直到某一刻的Unix時間),在該時間內服務器會拒絕對於此鍵名的「add」和「replace」命令。此時內容被放入delete隊列,沒法再經過「get」獲得該內容,也沒法是用「add」和「replace」命令(可是「set」命令可用)。直到指定時間,這些內容被最終從服務器的內存中完全清除
<time>參數是可選的,缺省爲0(表示內容會馬上清除,而且隨後的存儲命令都可用
如:delete key1
退出命令(quit)
如:quit
四、理解memcached 的內存存儲
Memcache內存分配機制
Memcache使用了Slab Allocator的內存分配機制:按照預先規定的大小,將分配的內存分割成特定長度的塊,以徹底解決內存碎片問題
Memcache的存儲涉及到slab,page,chunk三個概念
1.Chunk爲固定大小的內存空間,默認爲96Byte。
2.page對應實際的物理空間,1個page爲1M。
3.一樣大小的chunk又稱爲slab。
4.1Slab Allocation 機制:整理內存以便重複使用
最近的memcached 默認狀況下采用了名爲Slab Allocator 的機制分配、管理內存。在該機制出現之前,內存的分配是經過對全部記錄簡單地進行malloc和free 來進行的。可是,這種方式會致使內存碎片,加劇操做系統內存管理器的負擔,最壞的狀況下,會致使操做系統比memcached 進程自己還慢。Slab Allocator 就是爲解決該問題而誕生的
Slab Allocation 的原理至關簡單。將分配的內存分割成各類尺寸的塊
(chunk),並把尺寸相同的塊分紅組(chunk 的集合)
並且,slab allocator 還有重複使用已分配的內存的目的。也就是說,分配到的內存不會釋放,而是重複利用。
Slab Allocation 的主要術語
Page
分配給Slab 的內存空間,默認是1MB。分配給Slab 以後根據slab 的大小切分紅chunk。
Chunk
用於緩存記錄的內存空間。
Slab Class
特定大小的chunk 的組
4.2 在Slab中緩存記錄的原理
memcached 根據收到的數據的大小,選擇最適合數據大小的slab,memcached 中保存着slab 內空閒chunk 的列表,根據該列表選擇chunk,然
後將數據緩存於其中
4.3 Slab Allocator 的缺點
因爲分配的是特定長度的內存,所以沒法有效利用分配的內存。例如,將100 字節的數據緩存到128 字節的chunk 中,剩餘的28字節就浪費了
對於該問題目前尚未完美的解決方案,但在文檔中記載了比較有效的解決方案。就是說,若是預先知道客戶端發送的數據的公用大小,或者僅緩存大小相同的數據的狀況下,只要使用適合數據大小的組的列表,就能夠減小浪費。可是很遺憾,如今還不能進行任何調優,只能期待之後的版本了。可是,咱們能夠調節slab class 的大小的差異。接下來講明growth factor 選項。
4.4 使用Growth Factor進行調優
memcached 在啓動時指定Growth Factor 因子(經過f 選項),就能夠在某種程度上控制slab 之間的差別。默認值爲1.25。可是,在該選項出現以前,這個因子曾經固定爲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 字節的組開始,組的大小依次增大爲原來的2 倍。這樣設置的問題是,slab 之間的差異比較大,有些狀況下就至關浪費內存。所以,爲儘可能減小內存浪費,兩年前追加了growth factor 這個選項來看看如今的默認設置(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 時小得多,更適合緩存幾百字節的記錄。從上面的輸出結果來看,可能會以爲有些計算偏差,這些偏差是爲了保持字節數的對齊而故意設置的。將memcached 引入產品,或是直接使用默認值進行部署時,最好是從新計算一下數據的預期平均長度,調整growth factor,以得到最恰當的設置。內存是珍貴的資源,浪費就太惋惜了。
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字節的數據
完整的item長度是鍵長+值長+後綴長+item結構大小(48字節) + 8
item.length=56+key.lenght+value.length+後綴長
32位機器 item結構是32字節
64位機器 itme結構是48字節
memcache存儲的時候對key的長度有限制,php和C的最大長度都是250
五、memcached 刪除機制
memcached 是緩存,不須要永久的保存到服務器上,本章介紹memcache 的刪除機制
5.1 memcached 在數據刪除方面有效的利用資源
Memcached 不會釋放已經分配的內存,記錄過時以後,客戶端沒法再看到這一條記錄,其存儲空間就能夠利用。
Lazy Expiration
memcached 內部不會監視記錄是否過時,而是在get 時查看記錄的時間戳,檢查記錄是否過時。這種技術被稱爲lazy(惰性)expiration。所以,memcached不會在過時監視上耗費CPU 時間
5.2 LRU:從緩存中有效刪除數據的原理
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 會優先使用已超時的記錄的空間,但即便如此,也會發生追加新記錄時空間不足的狀況,此時就要使用名爲Least Recently Used(LRU)機制來分配空間。顧名思義,這是刪除「最近最少使用」的記錄的機制。所以,當memcached 的內存空間不足時(沒法從slab class 獲取到新的空間時),就從最近未被使用的記錄中搜索,並將其空間分配給新的記錄。從緩存的實用角度來看,該模型十分理想。不過,有些狀況下LRU 機制反倒會形成麻煩。memcached 啓動時經過「M」參數能夠禁止LRU,以下所示:
$ memcached -M –m 1024
啓動時必須注意的是,小寫的「m」選項是用來指定最大內存大小的。不指定具體數值則使用默認值64MB。
指定「M」參數啓動後,內存用盡時memcached 會返回錯誤。話說回來,memcached 畢竟不是存儲器,而是緩存,因此推薦使用LRU
六、memcached 的分佈式算法
6.1memcached 的分佈式
memcached 雖然稱爲「分佈式」緩存服務器,但服務器端並無「分佈式」功能。memcached 的分佈式,則是徹底由客戶端程序庫實現的。這種分佈式是memcached 的最大特色
memcached 的分佈式是什麼意思?
下面假設memcached 服務器有node1~node3 三臺,應用程序要保存鍵名爲「tokyo」、「kanagawa」、「chiba」、「saitama」、「gunma」的數據
首先向memcached 中添加「tokyo」。將「tokyo」傳給客戶端程序庫後,客戶端實現的算法就會根據「鍵」來決定保存數據的memcached 服務器。服務器選定後,即命令它保存「tokyo」及其值
一樣,「kanagawa」、「chiba」、「saitama」、「gunma」都是先選擇服務器再保接下來獲取保存的數據。獲取時也要將要獲取的鍵「tokyo」傳遞給函數庫。函數庫經過與數據保存時相同的算法,根據「鍵」選擇服務器。使用的算法相同,就能選中與保存時相同的服務器,而後發送get 命令。只要數據沒有由於某些緣由被刪除,就能得到保存的值。
這樣,將不一樣的鍵保存到不一樣的服務器上,就實現了memcached 的分佈式。memcached 服務器增多後,鍵就會分散,即便一臺memcached 服務器發生故障沒法鏈接,也不會影響其餘的緩存,系統依然能繼續運行
6.2 餘數分佈式算法
就是「根據服務器臺數的餘數進行分散」。求得鍵的整數哈希值,再除以服務器臺數,根據其他數來選擇服務器
餘數算法的缺點
餘數計算的方法簡單,數據的分散性也至關優秀,但也有其缺點。那就是當添加或移除服務器時,緩存重組的代價至關巨大。添加服務器後,餘數就會產生鉅變,這樣就沒法獲取與保存時相同的服務器,從而影響緩存的命中。
6.3Consistent Hashing(一致哈希)
知識補充:哈希算法,即散列函數。將任意長度的二進制值映射爲較短的固定長度的二進制值,這個小的二進制值稱爲哈希值。哈希值是一段數據惟一且極其緊湊的數值表示形式。若是散列一段明文並且哪怕只更改該段落的一個字母,隨後的哈希都將產生不一樣的值。要找到散列爲同一個值的兩個不一樣的輸入,在計算上是不可能的,因此數據的哈希值能夠檢驗數據的完整性。通常用於快速查找和加密算法。(常見的有MD5,SHA-1)
Consistent Hashing 的簡單說明
Consistent Hashing 以下所示:首先求出memcached 服務器(節點)的哈希值,並將其配置到0~232 的圓(continuum)上。而後用一樣的方法求出存儲數據的鍵的哈希值,並映射到圓上。而後從數據映射到的位置開始順時針查找,將數據保存到找到的第一個服務器上。若是超過232 仍然找不到服務器,就會保存到第一臺memcached 服務器上。
從上圖的狀態中添加一臺memcached 服務器。餘數分佈式算法因爲保存鍵的服務器會發生巨大變化,而影響緩存的命中率,但Consistent Hashing中,只有在continuum 上增長服務器的地點逆時針方向的第一臺服務器上的鍵會受到影響
Consistent Hashing:添加服務器
所以,Consistent Hashing 最大限度地抑制了鍵的從新分佈。並且,有的Consistent Hashing 的實現方法還採用了虛擬節點的思想。使用通常的hash函數的話,服務器的映射地點的分佈很是不均勻。所以,使用虛擬節點的思想,爲每一個物理節點(服務器)在continuum上分配100~200 個點。這樣就能抑制分佈不均勻,最大限度地減少服務器增減時的緩存從新分佈。
經過上文中介紹的使用Consistent Hashing 算法的memcached 客戶端函數庫進行測試的結果是,由服務器臺數(n)和增長的服務器臺數(m)計算增長服務器後的命中率計算公式以下:
(1 n/(n+m)) * 100
存儲命令
<command name> <key> <flags> <exptime> <bytes>\r\n
- <command name> 是set, add,或者repalce
- <key> 是接下來的客戶端所要求儲存的數據的鍵值
- <flags> 是在取回內容時,與數據和發送塊一同保存服務器上的任意16位無符號整形(用十進制來書寫)。客戶端能夠用它做爲「位域」來存儲一些特定的信息;它對服務器是不透明的。
- <exptime> 是終止時間。若是爲0,該項永不過時(雖然它可能被刪除,以便爲其餘緩存項目騰出位置)。若是非0(Unix 時間戳或當前時刻的秒偏移),到達終止時間後,客戶端沒法再得到這項內容。
- <bytes> 是隨後的數據區塊的字節長度,不包括用於分野的「\r\n」。它能夠是0(這時後面跟隨一個空的數據區塊)。
- <data block> 是大段的8位數據,其長度由前面的命令行中的<bytes>指定。
• set 意思是「儲存此數據」
• add 意思是「儲存此數據,只在服務器*未*保留此鍵值的數據時」
• replace 意思是「儲存此數據,只在服務器*曾*保留此鍵值的數據時」
發送命令行和數據區塊之後,客戶端等待回覆,可能的回覆以下:
- "STORED\r\n"代表成功.
- "NOT_STORED\r\n"代表數據沒有被存儲,但不是由於發生錯誤。這一般意味着add或replace 命令的條件不成立,或者,項目已經位列刪除隊列(參考後文的「delete」命令)。
取回命令
get <key>*\r\n
- <key>* 表示一個或多個鍵值,由空格隔開的字串這行命令之後,客戶端的等待0個或多個項目,每項都會收到一行文本,而後跟着數據區塊。全部項目傳送完畢後,服務器發送如下字串:"END\r\n"來指示迴應完畢,服務器用如下形式發送每項內容:
VALUE <key> <flags> <bytes>\r\n
<data block>\r\n
- <key> 是所發送的鍵名
- <flags> 是存儲命令所設置的記號
- <bytes> 是隨後數據塊的長度,*不包括* 它的界定符「\r\n」
- <data block> 是發送的數據
若是在取回請求中發送了一些鍵名,而服務器沒有送回項目列表,這意味着服務器沒這些鍵名(可能由於它們從未被存儲,或者爲給其餘內容騰出空間而被刪除,或者到期,或者被已客戶端刪除)。
刪除
delete <key> <time>\r\n
- <key> 是客戶端但願服務器刪除的內容的鍵名
- <time> 是一個單位爲秒的時間(或表明直到某一刻的Unix時間),在該時間內服務器會拒絕對於此鍵名的「add」和「replace」命令。此時內容被放入delete隊列,沒法再經過「get」獲得該內容,也沒法是用「add」和「replace」命令(可是「set」命令可用)。直到指定時間,這些內容被最終從服務器的內存中完全清除。<time>參數是可選的,缺省爲0(表示內容會馬上清除,而且隨後的存儲命令都可用)。
此命令有一行迴應:- "DELETED\r\n"表示執行成功
- "NOT_FOUND\r\n"表示沒有找到這項內容
增長/減小
命令「incr」和「decr」被用來修改數據,當一些內容須要替換、增長或減小時。這些數據必須是十進制的32位無符號整新。若是不是,則看成0 來處理。修改的內容必須存在,當使用「incr」/「decr」命令修改不存在的內容時,不會被看成0處理,而是操做失敗。
客戶端發送命令行:
incr <key> <value>\r\n或decr <key> <value>\r\n
- <key> 是客戶端但願修改的內容的建名
- <value> 是客戶端要增長/減小的總數。
回覆爲如下集中情形:
- "NOT_FOUND\r\n"指示該項內容的值,不存在。
- <value>\r\n ,<value>是增長/減小。
注意"decr"命令發生下溢:若是客戶端嘗試減小的結果小於0 時,結果會是0。"incr" 命令不會發生溢出。
狀態
命令"stats" 被用於查詢服務器的運行狀態和其餘內部數據。有兩種格式。不帶參數的:
stats\r\n
這會在隨後輸出各項狀態、設定值和文檔。另外一種格式帶有一些參數:
stats <args>\r\n
經過<args>,服務器傳回各類內部數據。由於隨時可能發生變更,本文不提供參數的種類及其傳回數據。
各類狀態
受到無參數的"stats"命令後,服務器發送多行內容,以下:
STAT <name> <value>\r\n
服務器用如下一行來終止這個清單:END\r\n,在每行狀態中,<name> 是狀態的名字,<value>使狀態的數據。如下清單,是全部的狀態名稱,數據類型,和數據表明的含義。
在「類型」一列中,"32u"表示32 位無符號整型,"64u"表示64 位無符號整型,"32u:32u"表示用冒號隔開的兩個32 位無符號整型。
名稱 |
類型 |
含義 |
pid |
32u |
服務器進程ID |
uptime |
32u |
服務器運行時間,單位秒 |
time |
32u |
服務器當前的UNIX時間 |
version |
string |
服務器的版本號 |
rusage_user |
32u |
該進程累計的用戶時間(秒:微妙) |
rusage_system |
32u |
該進程累計的系統時間(秒:微妙) |
curr_items |
32u |
服務器當前存儲的內容數量 |
total_items |
32u |
服務器啓動以來存儲過的內容總數 |
bytes |
64u |
服務器當前存儲內容所佔用的字節數 |
curr_connections |
32u |
鏈接數 |
total_connections |
32u |
服務器運行以來接受的鏈接總數 |
connection_structures |
32u |
服務器分配的鏈接結構的數量 |
cmd_get |
32u |
取回請求總數 |
cmd_set |
32u |
存儲請求總數 |
get_hits |
32u |
請求成功的總次數 |
get_misses |
32u |
請求失敗的總次數 |
bytes_read |
64u |
服務器從網絡讀取到的總字節數 |
bytes_written |
64u |
服務器向網絡發送的總字節數 |
limit_maxbytes |
32u |
服務器在存儲時被容許使用的字節總數 |
若是不想每次經過輸入stats來查看memcache狀態,能夠經過echo "stats" |nc ip port 來查看,例如:echo "stats" | nc 127.0.0.1 9023。
7.Memcache 命中率
緩存命中率 = get_hits/cmd_get * 100% (總命中次數/總請求次數)
要提升memcached的命中率,預估咱們的value大小而且適當的調整內存頁大小和增加因子是必須的。
命中率的提高能夠經過多種方案實現.
其一,提升服務獲取的內存總量
其二,提升空間利用率,這實際上也是另外一種方式的增長內存總量
其三,應用一級別上再來一次LRU
其四,對於總體命中率,能夠採起有效的冗餘策略,減小分佈式服務時某個server發生服務抖動的狀況
8.一些注意1. memcache已經分配的內存不會再主動清理。2. memcache分配給某個slab的內存頁不能再分配給其餘slab。3. flush_all不能重置memcache分配內存頁的格局,只是給全部的item置爲過時。4. memcache最大存儲的item(key+value)大小限制爲1M,這由page大小1M限制5.因爲memcache的分佈式是客戶端程序經過hash算法獲得的key取模來實現,不一樣的語言可能會採用不一樣的hash算法,一樣的客戶端程序也有可能使用相異的方法,所以在多語言、多模塊共用同一組memcached服務時,必定要注意在客戶端選擇相同的hash算法6.啓動memcached時能夠經過-M參數禁止LRU替換,在內存用盡時add和set會返回失敗7.memcached啓動時指定的是數據存儲量,沒有包括自己佔用的內存、以及爲了保存數據而設置的管理空間。所以它佔用的內存量會多於啓動時指定的內存分配量,這點須要注意。8.memcache存儲的時候對key的長度有限制,php和C的最大長度都是250