天天看點

Redis的通信協定RESP用戶端請求服務端服務端響應用戶端結

RESP

RESP(Redis Serialization Protocol)是Redis序列化協定的簡寫,該協定是純文字協定,實作過程簡單,解析性能較好。

5種單元類型

Redis協定将傳輸的資料結構分為5種最小的單元類型,單元結束時統一加上回車換行符号\r\n。

1. 單行字元串以 + 符号開頭

例:+hello world\r\n
           

2. 多行字元串以 $ 符号開頭,後跟字元串長度

例:$11\r\nhello world\r\n
           

多行字元串也可以用于表示單行字元串

3. 整數值以 : 符号開頭,後跟整數的字元串形式

例::1024\r\n
           

4. 錯誤資訊以 - 符号開頭

參數類型錯誤

例: -WRONGTYPE Operation against a key holding the wrong kind of value\r\n


           

5. 數組以 * 号開頭,後跟數組的長度

例:*3\r\n:l\r\n:2\r\n:3\r\n
           

兩種特殊類型

1. NULL

NULL使用多行字元串表示,長度為-1

例:$-1\r\n

           

2. 空字元串

空串用多行字元串表示,長度填0

例:$0\r\n\r\n
           

空字元串有兩個\r\n,因為兩個\r\n之間的就是空串

用戶端請求服務端

用戶端向伺服器發送的指令隻有一種格式,就是多行字元串數組。

例如一個簡單的set指令 set x x 會被序列化成下面的字元串

*3\r\n$3\r\nset\r\n$1\r\nx\r\n$1\r\nx\r\n
           

控制台展示如下

*3
$3
set
$1
x
$1
x           

服務端響應用戶端

服務端響應用戶端資訊時,将會使用多種資料結構,比用戶端發送到服務端時複雜很多,不過即便很複雜,也是上面提到的5種基本類型的組合。

單行字元串響應

127 . 0 .0.1: 6379> set x x 
OK           

上面的OK就是單行字元串響應(沒有雙引号),即 +OK

錯誤響應

127 . 0 . 0.1:6379> incr x 
(error} ERR value is not an integer or out of range           

對一個字元串進行自增,伺服器抛出錯誤提醒

-ERR value is not an integer or out of range

整數響應

127.0.0.1:6379> incr books 
(integer} 1           

1就是整數響應 :1

多行字元串響應

127.0.0.1:6379> get x

"x"           

上面用括号引起來的x就是多行字元串響應,即:

$1

x

數組響應

127.0.0.1:6379> hset info name bibabo

(integer) 1

127.0.0.1:6379> hset info age 18

(integer) 1

127.0.0.1:6379> hset info sex male

(integer) 1

127.0.0.1:6379> hgetall info

1) "name"

2) "bibabo"

3) "age"

4) "18"

5) "sex"

6) "male"
           

上面的hgetall指令傳回的就是一個數組,第0、2、4的字元串是hash表的key,1、3、6則是value,用戶端負責将數組組裝成字典傳回。

*6 
$4 
name 
$6 
bibabo 
$3 
age 
$2 
18 
$3 
sex 
$4 
male           

嵌套

127.0.0.1:6379> scan 0 
1 )"0" 
2) 1 ) "info" 
2 )"books"
3 )"author"
           

scan指令用來掃描伺服器包含的所有key清單,通過遊标的形式一次擷取一部分,該指令傳回的是一個嵌套數組,

數組第一個值表示遊标的值,如果這個值為0,說明已經周遊完畢,如果不為0,使用這個值作為下一次scan時的參數,

數組的第二個值又是一個數組,這個數組就是key的清單。

*2 
$1
0
*3
$4 
info
$5 
books 
$6 
author           

Redis作為文本協定中含有大量的回車換行符,這會占用網絡流量,不過依然有很多項目使用RESP作為通訊協定,因為性能并不是評分的全部,簡單性、易了解性、易實作性都需要進行權衡,

一般資料庫的瓶頸很少在協定上,而是内部的邏輯處理,Redis使用一個單線程對外提供服務,在CPU跑滿的情況下,可以達到10w/s的QPS。