Redis中RESP 協議的作用是什么,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
RESP 協議簡介
Redis 的客戶端和服務端之間在 TCP 協議的上層采用一種獨立名為 RESP(REdis Serialization Protocol) 協議作為進行通訊的標準方式。
Redis 協議在以下幾點之間做出了折衷:
簡單的實現
快速地被計算機解析
簡單得可以能被人工解析
新的統一協議已在Redis 1.2中引入,但是在Redis 2.0中,這就成為了與Redis服務器通訊的標準方式。在這個統一協議里,發送給Redis服務端的所有參數都是二進制安全的。Redis用不同的回復類型回復命令。它可以從服務器發送的第一個字節開始校驗回復類型:
單行回復(單行字符串回復),回復的第一個字節將是“+”
錯誤消息(單行字符串回復的另外展示形式),回復的第一個字節將是“-”
整型回復(正整形數字回復),回復的第一個字節將是“:”
批量回復(多行字符串回復),回復的第一個字節將是“$”
多個批量回復(數組回復),回復的第一個字節將是“*”
傳輸層及網絡層
傳輸層仍然是底層 TCP 傳輸。Redis在TCP端口6379上監聽到來的連接,客戶端連接到來時,Redis服務器為此創建一個TCP連接。在客戶端與服務器端之間傳輸的每個Redis命令或者數據都以\r\n結尾。Redis接收由不同參數組成的命令。一旦收到命令,將會立刻被處理,并回復給客戶端。
關于校驗回復類型
單行回復(單行字符串回復):"+"
狀態回復(或者單行回復)以“+”開始以“\r\n”結尾的單行字符串形式。例如:
> set name leeprince +OK\r\n # 服務端實際返回 --- OK # redis-cli 客戶端顯示
錯誤消息(單行字符串回復的另外展示形式):"-"
錯誤回復發送類似于狀態回復。唯一的不同是第一個字節用“-”代替“+”。
錯誤回復僅僅在一些意料之外的事情發生時發送,例如:如果你試圖執行一個操作來應付錯誤的數據類型,或者如果命令不存在等等。所以當收到一個錯誤回復時,客戶端將會出現一個異常。例如:
> leeprince -(error) ERR unknown command `leeprince`, with args beginning with:\r\n # 服務端實際返回 --- (error) ERR unknown command `leeprince`, with args beginning with: # redis-cli 客戶端顯示
整型回復(正整形數字回復):":"
這種回復類型只是用CRLF結尾字符串來表示整型,用一個字節的“:”作為前綴。例如:“:0\r\n”,或者“:1000\r\n”是整型回復。
像INCR或者LASTAVE命令用整型回復作為實際回復值,此時對于返回的整型沒有特殊的意思。它僅僅是為INCR、LASTSAVE的UNIX時間等增加數值。
一些命令像EXISTS將為true返回1,為false返回0。
其它命令像SADD、SREM和SETNX如果操作實際完成了的話將返回1,否則返回0。例如:
>rpush intkey intvalue01 intvalue02 intvalue03 :3\r\n # 服務端實際返回 --- (integer) 3 # redis-cli 客戶端顯示
以下命令都是回復一個整型:
SETNX、DEL、EXISTS、INCR、INCRBY、DECR、DECRBY、DBSIZE、LASTSAVE、RENAMENX、MOVE、LLEN、SADD、SREM、SISMEMBER、SCARD。
批量回復(多行字符串回復):”$“
批量回復被服務器用于返回一個單二進制安全字符串。服務器發送第一行回復,該行以“$”開始后面跟隨實際要發送的字節數,隨后是CRLF,然后發送實際數據,隨后是2個字節的額外數據用于最后的CRLF。例如:
>get bulkkey $9\r\nbulkvalue\r\n # 服務端實際返回 --- "bulkvalue" # redis-cli 客戶端顯示
如果請求的值不存在,批量回復將使用特殊的值-1來作為數據長度,例如:
>get bulkkey_ $-1 # 服務端實際返回 --- (nil) # redis-cli 客戶端顯示
多個批量回復(數組回復):”*“
像命令LRNGE需要返回多個值(列表的每個元素是一個值,而LRANGE需要返回多于一個單元素)。使用多批量寫是有技巧的,用一個初始行作為前綴來指示多少個批量寫緊隨其后。批量回復的第一個字節總是*,例如:
127.0.0.1:6379> rpush arraykey a01 a0101 (integer) 2 # redis-cli 客戶端顯示 127.0.0.1:6379> lrange arraykey 0 -1 # 服務端實際返回 *2\r\n$3\r\na01$5\r\na0101\r\n --- # redis-cli 客戶端顯示 1) "a01" 2) "a0101"
正如您可以看到的多批量回復是以完全相同的格式使用Redis統一協議將命令發送給服務器。
服務器發送的第一行是*4\r\n,用于指定緊隨著4個批量回復。然后傳送每個批量寫。
如果指定的鍵不存在,則該鍵被認為是持有一個空的列表,且數值0被當作多批量計數值來發送,例如:
127.0.0.1:6379> LRANGE nokey 0 1 # 服務端實際返回 *0 --- # redis-cli 客戶端顯示 (empty list or set)
當BLPOP命令超時時,它返回nil多批量回復。這種類型多批量回復的計數器是-1,且值被當作nil來解釋。例如:
127.0.0.1:6379> BLPOP nokey 1 # 服務端實際返回 *-1 --- # redis-cli 客戶端顯示 (nil) (1.09s)
當這種情況發生時,客戶端庫API將返回空nil對象,且不是一個空列表。這必須有別于空列表和錯誤條件(例如:BLPOP命令的超時條件)。
多命令和管道(pipelining)
客戶端能使用同樣條件為了發出多個命令。管道用于支持多命令能夠被客戶端用單寫操作來發送,它不需要為了發送下一條命令而讀取服務器的回復。所有回復都能在最后被讀出。
通常Redis服務器和客戶端擁有非??焖俚倪B接,所以在客戶端的實現中支持這個特性不是那么重要,如果一個應用需要在短時間內發出大量的命令,管道仍然會非???。
管道(Pipelining) VS 腳本(Scripting)
大量 pipeline 應用場景可通過 Redis 腳本(Redis 版本 >= 2.6)得到更高效的處理,后者在服務器端執行大量工作。腳本的一大優勢是可通過最小的延遲讀寫數據,讓讀、計算、寫等操作變得非??欤╬ipeline 在這種情況下不能使用,因為客戶端在寫命令前需要讀命令返回的結果)。
應用程序有時可能在 pipeline 中發送 EVAL 或 EVALSHA 命令。Redis 通過 SCRIPT LOAD 命令(保證 EVALSHA 成功被調用)明確支持這種情況。
Redis 大量數據插入
pipe mode的工作原理是什么?
難點是保證redis-cli在pipe mode模式下執行和netcat一樣快的同時,如何能理解服務器發送的最后一個回復。
這是通過以下方式獲得:
redis-cli –pipe試著盡可能快的發送數據到服務器。 讀取數據的同時,解析它。 一旦沒有更多的數據輸入,它就會發送一個特殊的ECHO命令,后面跟著20個隨機的字符。我們相信可以通過匹配回復相同的20個字符是同一個命令的行為。 一旦這個特殊命令發出,收到的答復就開始匹配這20個字符,當匹配時,就可以成功退出了。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。