1. 程式人生 > 實用技巧 >redis傳輸協議規範(翻譯)-上(Redis Protocol specification)

redis傳輸協議規範(翻譯)-上(Redis Protocol specification)

Redis客戶端使用一個稱為RESP的協議與Redis伺服器通訊。雖然該協議是專門為Redis設計的,但它也可以用作其他客戶端-伺服器軟體專案的通訊協議。 RESP協議在以下幾點之間做了折中:
  • 易於實現
  • 方便計算機快速解析
  • 方便人閱讀
RESP協議可以序列化不同的資料型別,如整數、字串、陣列。錯誤也有一個特定的型別。帶有引數的請求從客戶端以字串陣列的形式傳送到Redis伺服器。Redis以命令對應的資料型別進行回覆。 RESP是二進位制安全的,並且不需要處理從一個程序傳輸到另一個程序的大塊資料,因為它使用預定義的長度來傳輸大塊資料。 注意:這裡列出的協議僅用於客戶端-(單例項)伺服器通訊。Redis叢集在節點之間交換資訊則使用了不同的協議。

網路層面

客戶端使用TCP協議連線到Redis伺服器的6379埠。 雖然RESP並非只能在TCP上使用,但在Redis相關的文件裡,如果沒有特殊說明,RESP預設使用TCP協議(或等效的面向流的連線,如Unix socket)。

請求-響應模型

Redis接收由不同引數組成的命令。一旦接收到命令,redis就會對其進行處理,並將回覆傳送回客戶端。 這可能是最簡單的模型,但是有兩個例外:
  • Redis支援pipelining(稍後將在本文件中介紹)。所以客戶端可以一次傳送多個命令,然後等待伺服器的響應。
  • 當一個Redis客戶端訂閱一個Pub/Sub通道時,該協議會改變語意而變成一個推送協議,也就是說,客戶端不再需要傳送命令,因為伺服器一旦接收到新訊息(針對客戶端訂閱的通道),就會自動傳送給客戶端。
除了以上兩個例外,Redis協議就是一個簡單的請求-響應協議。

RESP協議規範

RESP協議是在Redis 1.2中引入的,但在Redis 2.0中它成為了與Redis伺服器通訊的標準方式。RESP協議是你應該在Redis客戶端實現的協議。 RESP實際上是一個序列化協議,它支援以下資料型別:簡單字串、錯誤、整數、大塊字串和陣列。 RESP在Redis中用作請求-響應協議的方式如下:
  • 客戶端使用大塊字串(bulk strings也可翻譯為大容量字串,本文使用大塊字串)陣列格式傳送命令到Redis伺服器。
  • 伺服器根據命令實現的RESP型別進行響應。
在RESP協議中,資料的型別取決於第一個位元組:
  • 對於簡單字串,回覆的第一個位元組是“+”
  • 對於錯誤,回覆的第一個位元組是“-”
  • 對於整數,回覆的第一個位元組是“:”
  • 對於大塊字串(大容量字串bulk strings),回覆的第一個位元組為"$"
  • 對於陣列回覆的第一個位元組是"*”
此外,RESP還能夠使用後面指定的批量字串或陣列的特殊變體來表示空值。 RESP協議以“\r\n”(CRLF)來區分協議中不同的部分。

RESP協議字串

簡單字串按以下方式編碼:一個加號,後跟緊跟著不能包含CR或LF字元(不允許換行)的字串,以CRLF結束(即"\r\n")。 簡單字串用於以最小的開銷傳輸非二進位制安全字串。例如,許多Redis命令回覆只是“OK”成功,那作為一個簡單的RESP字串編碼以下5個位元組:
"+OK\r\n"

  

redis使用RESP批量字串傳送二進位制安全的字串。 當Redis回覆一個簡單的字串時,客戶端庫應該返回給呼叫者一個字串,該字串由'+'後面的第一個字元到字串的結尾,不包括最後的CRLF位元組。

RESP協議錯誤

RESP給錯誤定義了一個特定的資料型別。實際上,錯誤就像RESP簡單字串型別,但是第一個字元是一個減號而不是加號。在RESP中,簡單字串和錯誤之間的真正區別在於,錯誤被客戶端視為異常,而組成錯誤型別的字串就是錯誤訊息本身。 基本格式是:
"-Error message\r\n"

  

錯誤響應只在發生錯誤時傳送,例如,如果您試圖對錯誤的資料型別執行操作,或者請求的命令不存在,等等。當收到錯誤回覆時,客戶端庫應該引發異常。 下面是一些錯誤回覆的例子:
-ERR unknown command 'foobar' 
-WRONGTYPE Operation against a key holding the wrong kind of value

  

  “-”之後的第一個單詞,一直到第一個空格或換行符,表示返回的錯誤型別。這只是Redis使用的一個約定,並不是RESP錯誤格式的一部分。 例如,ERR是通用錯誤,而WRONGTYPE是更具體的錯誤,它意味著客戶端試圖對錯誤的資料型別執行操作。這被稱為錯誤字首,是一種允許客戶端理解伺服器返回的錯誤型別的方法,而不需要依賴於所給出的確切訊息,這可能會隨著時間的推移而改變。 客戶端實現可以為不同的錯誤返回不同型別的異常,也可以通過直接將錯誤名稱作為字串提供給呼叫者來提供捕獲錯誤的通用方法。 然而,這樣的功能不應該被認為是至關重要的,因為它很少有用,而且縮減版的客戶端實現可能僅僅返回一個通用的錯誤條件,比如false。

RESP整數

RESP整數型別只是一個以CRLF結尾的字串,表示一個整數,字首為“:”位元組。例如,":0\r\n"或":1000\r\n"都是整數回覆。 很多Redis命令返回RESP整數,如INCR,LLENLASTSAVE. 返回的整數沒有特殊意義,它只是INCR的一個增量數,LASTSAVE的UNIX時間,等等。但是,返回的整數保證在有符號的64位整數的範圍內。 整數響應也被廣泛用於返回真或假。例如,像EXISTS或SISMEMBER這樣的命令將返回true為1,false為0。 其他命令,如SADD,SREMandSETNX,如果實際執行了操作,則返回1,否則返回0。 下面的命令將用一個整數回覆:SETNX,DEL,EXISTS,INCR,INCRBY,DECR,DECRBY,DBSIZE,LASTSAVE,RENAMENX,MOVE,LLEN,SADD,SREM,SISMEMBER,SCARD。 RESP大塊字串(bulk strings) 使用大塊字串(bulk strings)是為了表示長度不超過512 MB的單個二進位制安全字串。 大塊字串的編碼方式如下:
  • 一個"$"位元組,後面跟著組成字串的位元組數(有字首的長度),以CRLF結束。
  • 實際的字串資料。
  • 最後一個CRLF。
因此字串foobar編碼如下:
"$6\r\nfoobar\r\n"

  

當一個空字串為:
"$0\r\n\r\n"

  

RESP大塊字串也可以用來表示值不存在,使用一種特殊的格式來表示空值。在這種特殊格式中,長度為-1,沒有資料,因此Null表示為:
"$-1\r\n"

  

這被稱為空大塊字串。 當伺服器返回給客戶端一個空的大塊字串時,客戶端庫API不應該返回給呼叫者一個空字串,而應該返回一個nil物件。例如,Ruby庫應該返回'nil',而C庫應該返回NULL(或者在應答物件中設定一個特殊的標誌),等等。 原文地址:https://redis.io/topics/protocol 參考資料: https://www.cnblogs.com/lijianxing/p/9186593.html https://blog.csdn.net/xtydtc/article/details/90902298