異常錯誤響應
接下來,我們來完整學習 Mc 協議。在學習 Mc 協議之前,首先來看看 Mc 處理協議指令,如果發現異常,如何進行異常錯誤響應的。Mc 在處理所有 client 端指令時,如果遇到錯誤,就會返回 3 種錯誤資訊中的一種。
第一種錯誤是協議錯誤,一個”ERROR\r\n”的字串。表明 client 傳送了一個非法命令。
第二種錯誤是 client 錯誤,格式為"CLIENT_ERROR <error-描述資訊>\r\n"
。這個錯誤資訊表明 ,client 傳送的協議命令格式有誤,比如少了欄位、多了非法欄位等。
第三種錯誤是"SERVER_ERROR <error-描述資訊>\r\n"
。這個錯誤資訊表明 Mc server 端,在處理命令時出現的錯誤。比如在給 key/value 分配 Item 空間失敗後,會返回”SERVER_ERROR out of memory storing object” 錯誤資訊。
現在再來看看 Mc 的儲存協議。Mc 的儲存協議命令不多,只有 6 個。
Mc 儲存指令分 2 行。第一行是報文首部,第二行是 value 的 data block 塊。這兩部分用 \r\n 來進行分割和收尾。
儲存類指令的報文首行分 2 種格式,其中一種是在 cmd 儲存指令,後面跟 key、flags、expiretime、value 位元組數,以及一個可選的 noreply。
其中 flags 是使用者自己設計的一個特殊含義數字,Mc 對 flag 只儲存,而不進行任何額外解析處理,expiretime 是 key 的過期時間,value 位元組數是 value block 塊的位元組長度,而帶上 noreply 是指 Mc 處理完後靜默處理,不返回任何響應給 client。
這種 cmd 指令包括我們最常用的 set 指令,另外還包括 add、replace、append、reppend ,總共 5 個指令:
Set 命令用於儲存一個 key/value;
Add 命令是在當 key 不存在時,才儲存這個 key/value;
Replace 命令,是當 key 存在時,才儲存這個 key/value;
Append 命令,是當 key 存在時,追加 data 到 value 的尾部;
Prepend 命令,是當 key 存在時,將 data 加到 value 的頭部。
另外一種儲存協議指令,主要格式和欄位與前一種基本相同,只是多了一個 cas unique id,這種格式只有 cas 指令使用。cas 指令是指只有當這個 key 存在,且從本 client 獲取以來,沒有其他任何人修改過時,才進行修改。cas 的英文含義是 compare and set,即比較成功後設定的意思。
Mc 在響應儲存協議時,如果遇到錯誤,就返回前面說的3種錯誤資訊中的一種。否則就會返回如下 4 種正常的響應,”STORED\r\n”、”EXISTS\r\n”、”NOT_STORED\r\n”、”NOT_FOUND\r\n“。
其中,stored 表明儲存修改成功。NOT_STORED 表明資料沒有儲存成功,但並不是遇到錯誤或異常。這個響應一般表明 add 或 replace 等指令,前置條件不滿足時,比如 add,這個 key 已經存在 Mc,就會 add 新 key 失敗。replace 時, key 不存在,也無法 replace 成功。EXISTS 表明待 cas 的key 已經被修改過了,而 NOT_FOUND 是指待 cas 的 key 在 Mc 中不存在。
Mc 對儲存命令的請求及響應協議,可以參考下面的思維導圖來有一個完整的印象。
#
Mc 的獲取協議,只有 get、gets 兩種指令,如下圖所示。格式為 get/gets 後,跟隨若干個 key,然後 \r\n 結束請求命令。get 指令只獲取 key 的 flag 及 value,gets 會額外多獲取一個 cas unique id值。gets 主要是為 cas 指令服務的。
獲取命令的響應,就是 value 字串,後面跟上 key、flag、value 位元組數,以及 value 的 data block 塊。最後跟一個 END\r\n 表明所有存在的 key/value 已經返回,如果沒有返回的 key,則表明這個 key 在 Mc 中不存在。
Mc 的其他協議指令包括 delete、incr、decr、touch、gat、gats、slabs、lru、stats 這 9 種指令。
其中 delete 用於刪除一個 key。
incr/decr 用於對一個無符號長整型數字進行加或減。
touch、gat、gats 是 Mc 後來增加的指令,都可以用來修改 key 的過期時間。不同點是 touch 只修改 key 的過期時間,不獲取 key對應的value。
而 gat、gats 指令,不僅會修改 key 的過期時間,還會獲取 key 對應的 flag 和 value 資料。gats 同 gets,還會額外獲取 cas 唯一 id 值。
Slabs reassign 用於在 Mc 記憶體達到設定上限後,將 slab 重新在不同的 slabclass 之間分配。這樣可以規避 Mc 啟動後自動分配而產生隨機性,使特殊 size 的資料也得到較好的命中率。Slabs automove 是一個開關指令,當開啟時,就允許 Mc 後臺執行緒自行決定何時將 slab 在slabclass 之間重新分配。
lru 指令用於 Mc LRU 的設定和調優。比如 LRU tune 用於設定 HOT、WARM LRU 的記憶體佔比。LRU mode 用來設定 Mc 只使用 COLD LRU,還是使用新版的 4 個 LRU 的新策略。LRU TEMP_TTL 用來設定 Mc 的 TEMP LRU 的TTL值,預設是 61s,小於這個 TMEP_TTL 的 key會被插入到 TEMP LRU。
Stats 用於獲取 Mc 的各種統計資料。Stats 後面可以跟 statistics、slabs、size 等引數,來進一步獲取更多不同的詳細統計。
陳波 新浪微博平臺架構技術專家 《300 分鐘吃透分散式快取》
本作品採用《CC 協議》,轉載必須註明作者和本文連結