Memcache協議中文版

協議
memcached 的客戶端使用TCP連接 與 服務器通信。(UDP接口也一樣有效,參考後文的 「UDP協議」 )一個運行中的memcached服務器監視一些(可設置)端口。客戶端鏈接這些端口,發送命令到服務器,讀取回應,最後關閉鏈接。
結束會話不須要發送任何命令。當再也不需memcached服務時,要客戶端能夠在任什麼時候候關閉鏈接。須要注意的是,鼓勵客戶端緩存這些鏈接,而不是每次須要存取數據時都從新打開鏈接。這是由於memcached 被特地設計成及時開啓不少鏈接也可以高效的工做(數百個,上千個若是須要的話)。緩存這些鏈接,能夠消除創建鏈接所帶來的開銷(/*/相對而言,在服務器端創建一個新鏈接的準備工做所帶來的開銷,能夠忽略不計。)。
在memcache協議中發送的數據分兩種:文本行 和 自由數據。 文本行被用於來自客戶端的命令和服務器的迴應。自由數據用於客戶端從服務器端存取數據時。一樣服務器會以字節流的方式傳回自由數據。/*/服務器不用關心自由數據的字節順序。自由數據的特徵沒有任何限制;可是經過前文提到的文本行,這項數據的接受者(服務器或客戶端),便可以精確地獲知所發送的數據庫的長度。
文本行固定以「\r\n」(回車符緊跟一個換行符)結束。 自由數據也是一樣會以「\r\n」結束,可是 \r(回車符)、\n(換行符),以及任何其餘8位字符,都可出如今數據中。所以,當客戶端從服務器取回數據時,必須使用數據區塊的長度來肯定數據區塊的結束位置,而不要依據數據區塊末尾的「\r\n」,即便它們固定存在於此。
鍵值
存儲在memcached中的數據經過鍵值來標識。鍵值是一個文本字符串,對於須要存取這項數據的客戶端而言,它必須是惟一的。鍵值當前的長度限制設定爲250字符(固然,客戶端一般不會用到這麼長的鍵);鍵值中不能使用製表符和其餘空白字符(例如空格,換行等)。
命令
全部命令分爲3種類型:
存儲命令(有3項:’set’、’add’、’repalce’)指示服務器儲存一些由鍵值標識的數據。客戶端發送一行命令,後面跟着數據區塊;而後,客戶端等待接收服務器回傳的命令行,指示成功與否。
取回命令(只有一項:’get’)指示服務器返回與所給鍵值相符合的數據(一個請求中右一個或多個鍵值)。客戶端發送一行命令,包括全部請求的鍵值;服務器每找到一項內容,都會發送回客戶端一行關於這項內容的信息,緊跟着是對應的數據區塊;直到服務器以一行「END」迴應命令結束。
/*?*/其餘的命令都不能攜帶自由數據。在這些命令中,客戶端發送一行命令,而後等待(由命令所決定)一行迴應,或最終以一行「END」結束的多行命令。
一行命令固定以命令名稱開始,接着是以空格隔開的參數(若是有參數的話)。命令名稱大小寫敏感,而且必須小寫。一些客戶端發送給服務器的命令會包含一些時限(針對內容或客戶端請求的操做)。這時,時限的具體內容既能夠是Unix時間戳(從1970年1月1日開始的秒鐘數),或當前時間開始的秒鐘數。對後者而言,不能超過 60*60*24*30(30天);若是超出,服務器將會理解爲Unix時間戳,而不是從當前時間起的秒偏移。
錯誤字串
每個由客戶端發送的命令,均可能收到來自服務器的錯誤字串回覆。這些錯誤字串會以三種形式出現:
- 「ERROR\r\n」
意味着客戶端發送了不存在的命令名稱。
- 「CLIENT_ERROR <error>\r\n」
意味着輸入的命令行裏存在一些客戶端錯誤,例如輸入未遵循協議。<error>部分是人類易於理解的錯誤解說……
- 「SERVER_ERROR <error>\r\n」
意味着一些服務器錯誤,致使命令沒法執行。<error>部分是人類易於理解的錯誤解說。在一些嚴重的情形下(一般應該不會遇到),服務器將在發送這行錯誤後關閉鏈接。這是服務器主動關閉鏈接的惟一狀況。
在後面每項命令的描述中,這些錯誤行不會再特別提到,可是客戶端必須考慮到這些它們存在的可能性。
存儲命令
首先,客戶端會發送一行像這樣的命令:
<command name> <key> <flags> <exptime> <bytes>\r\n
- <command name> 是 set, add, 或者 repalce
  • set 意思是 「儲存此數據」
  • add 意思是 「儲存此數據,只在服務器*未*保留此鍵值的數據時」
  • replace意思是 「儲存此數據,只在服務器*曾*保留此鍵值的數據時」
- <key> 是接下來的客戶端所要求儲存的數據的鍵值
- <flags> 是在取回內容時,與數據和發送塊一同保存服務器上的任意16位無符號×××(用十進制來書寫)。客戶端能夠用它做爲「位域」來存儲一些特定的信息;它對服務器是不透明的。
- <exptime> 是終止時間。若是爲0,該項永不過時(雖然它可能被刪除,以便爲其餘緩存項目騰出位置)。若是非0(Unix時間戳或當前時刻的秒偏移),到達終止時間後,客戶端沒法再得到這項內容。
- <bytes> 是隨後的數據區塊的字節長度,不包括用於分野的「\r\n」。它能夠是0(這時後面跟隨一個空的數據區塊)。
在這一行之後,客戶端發送數據區塊。
<data block>\r\n
- <data block> 是大段的8位數據,其長度由前面的命令行中的<bytes>指定。
發送命令行和數據區塊之後,客戶端等待回覆,可能的回覆以下:
- 「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」容許從外部刪除內容:
delete <key> <time>\r\n
- <key> 是客戶端但願服務器刪除的內容的鍵名
- <time> 是一個單位爲秒的時間(或表明直到某一刻的Unix時間),在該時間內服務器會拒絕對於此鍵名的「add」和「replace」命令。此時內容被放入delete隊列,沒法再經過「get」獲得該內容,也沒法是用「add」和「replace」命令(可是「set」命令可用)。直到指定時間,這些內容被最終從服務器的內存中完全清除。
<time>參數 是可選的,缺省爲0(表示內容會馬上清除,而且隨後的存儲命令都可用)。
此命令有一行迴應:
- 「DELETED\r\n」
表示執行成功
- 「NOT_FOUND\r\n」
表示沒有找到這項內容
參考隨後的「flush_all」命令使全部內容無效
增長/減小
命令 「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:32u 該進程累計的用戶時間
(秒:微妙)
rusage_system 32u: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 服務器在存儲時被容許使用的字節總數
其它命令
「flush_all」命令有一個可選的數字參數。它老是執行成功,服務器會發送「OK\r\n」迴應。它的效果是使已經存在的項目當即失效(缺省),或在指定的時間後。此後執行取回命令,將不會有任何內容返回(除非從新存儲一樣的鍵名)。flush_all 實際上沒有當即釋放項目所佔用的內存,而是在隨後陸續有新的項目被儲存時執行。flush_all 效果具體以下:它致使全部更新時間早於flush_all所設定時間的項目,在被執行取回命令時命令被忽略。
「version」命令沒有參數:
version\r\n
在迴應中,服務器發送:
「VERSION <version>\r\n」
<version> 是服務器的版本字串。
「quit」命令沒有參數:
quit\r\n
接收此命令後,服務器關閉鏈接。不過,客戶端能夠在再也不須要時,簡單地關閉鏈接就行,並不必定須要發送這個命令。
UDP 協議
當來自客戶端的鏈接數遠大於TCP鏈接的上限時,可使用基於UDP的接口。UDP接口不能保證傳輸到位,因此只有在不要求成功的操做中使用;好比被用於一個「get」請求時,會因不當的緩存處理而發生錯誤或迴應有遺失。
每一個UDP數據包都包含一個簡單的幀頭,數據以後的內容與TCP協議的描述相似。在執行所產生的數據流中,請求必須被包含在單獨的一個UDP數據包中,可是迴應可能跨越多個數據包。(只有「get」和「set」請求例外,跨越了多個數據包)
幀頭有8字節長,以下(均由16位整數組成,網絡字節順序,高位在前):
  • 0-1 請求ID
  • 2-3 序號
  • 4-5 該信息的數據包總數
  • 6-7 保留位,必須爲0
請求ID有客戶端提供。通常它會是一個從隨機基數開始的遞增值,不過客戶端想用什麼樣的請求ID均可以。服務器的迴應會包含一個和請求中的一樣的ID。客戶端使用請求ID來區分每個迴應。任何一個沒有請求ID的數據包,多是以前的請求遭到延遲而形成的,應該被丟棄。序號的返回是從0到n-1,n是該條信息的數據包數量。