前面講到了memcached的文字協定,雖然文字協定看起來非常簡單,但是對於使用者端來說一般還是會選擇效率更高的二進位制協定。
二進位制協定的本質和文字協定是一樣的,只是他們的表現方式不同而已。本文將會詳細介紹memcached中二進位制協定的實現細節。
對於memcached的請求包和響應包來說,除了請求頭有所區別之外,其他的格式都是一樣的。
所以對memcached的請求和響應都可以用同一個包的格式來表示:
前面的24個byte是包頭部分,接下來的是命令列的額外資料extra,memcached中的key和value。
上面也提到了,請求包和響應包的區別就是header,下面是請求包頭和響應包頭的定義:
請求包頭:
響應包頭:
包頭中各個欄位的含義如下:
如果是請求,那麼對應的Magic= 0x80,如果是響應,那麼對應的Magic= 0x81。
在最初的設計中,Magic應該和協定的版本相對應的,當版本升級之後,對應的Magic也要進行相應的調整。但是到目前為止,binary協定的magic值還沒有變化過。
memcached協定中有下面這些操作符:
其中帶星號的表示該命令未定,未來可能會有修改。
以Q結尾的命令,表示這個命令是一個quiet的版本,它會忽略不感興趣的返回資料。
Key length: key的長度
Status: 請求響應response的狀態
response的值有下面幾種:
Extras length: command extras的長度
Data type:保留欄位
data type是一個保留欄位,目前只有一個固定的值:0x00。
vbucket id: 命令對應的virtual bucket
Total body length:extra + key + value的總長度
Opaque: 請求生成的一個資料,會被原封不動在對應的響應中返回
CAS:資料的一個唯一標記
為了更好的理解memcached的二進位制協定,我們以幾個常用的命令為例,來看一下memcached具體的請求和響應流程。
最常用的就是get請求,用於向伺服器端請某個key對應的值。
假如現在使用者端要向伺服器端get一個key=hello的資料,那麼請求的包如下所示:
其中Magic=0x80, Opcode=0x00,Key length=0x0005,Total body=0x00000005,Key="Hello"
如果伺服器端存在對應的key的值,那麼將會返回如下的封包:
我們要注意下面幾個跟request值不同的欄位:
其中Magic=0x81表示這個是一個response, 因為這是一個response,所以對應的Key length=0x0000。
另外response中包含了get請求中並不存在的Extra length和Extras Flags,這裡他們的值分別是0x04和0xdeadbeef,表示Extra length是4個bytes,它的值是0xdeadbeef。
那麼這個Extras Flags值是哪裡來的呢?如果對比之前講到的text協定,就可以知道,Extras Flags是在set key value的時候傳入的,這個Flags會存放到伺服器端,並在get請求中返回。
最後,response中包含了要返回的值"World"。
如果伺服器端並沒有這個key的值,那麼對應的返回包可能是這樣的:
其中Status=0x0001,表示是一個異常返回。
對應的value是:"Not found"。
之前還提到了一個以Q結尾的命令列版本,比如getQ,它和get的區別是getQ會把請求的key也放在response包中返回:
因為最後的值中包含了key,所以這裡的Key length是有值的,他就是key的長度=0x0005。
最後的返回資料部分包含了兩部分,分別是Key="Hello",value="World"。
以上我們介紹了memcached二進位制協定的基本格式,並舉例說明了get請求的具體使用和包的內容。有了這些知識,我們就可以開發一個支援memcached二淨值協定的使用者端了。
更多內容請參考 http://www.flydean.com/24-memcached-binary-protocol/
最通俗的解讀,最深刻的乾貨,最簡潔的教學,眾多你不
歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!