Redis 的通信协议 RESP

Redis 作者认为数据库系统瓶颈不在网络流量, 而在数据库自身逻辑处理上, 所以使用了浪费流量的文本协议, 来换取即可的访问性能

RESP

RESP (Redis Serialization Protocol) 是一种直观的文本协议, 优势是过程简单, 解析极好, 劣势是耗费流量

RESP 将传输的结构数据分为 5 种最小单元类型, 单元结束时统一加上回车换行符 \r\n

  • 单行字符串以 + 符号开头
// 单行字符串 Hello World
+Hello World\r\n
  • 多行字符串以 $ 符号开头, 后跟字符串的长度
// 多行字符串 Hello World
$11Hello World\r\n
  • 整数值以 : 符号开头, 后跟整数的字符串形式
// 1024
:1024\r\n
  • 错误消息以 - 符号开头
-WRONGTYPE Operation against a key holding the wrong kind of value\r\n
  • 数组以 * 号开头, 后跟数组的长度
// 数组 [1,2,3]
*3\r\n:1\r\n:2\r\n:3\r\n
  • NULL
// NULL 用多行字符串表示, 长度写成 -1
$-1\r\n
  • 空字符串
// 空字符串用多行字符串表示, 长度填 0
// 两个 \r\n 之间表示空字符串
$0\r\n\r\n

客户端 -> 服务端

客户端向服务端发送执行只有一种格式, 多行字符串数组

// set author codehole
*3\r\n$3\r\nset\r\n$6author\r\n$8codehole\r\n

控制台输出的样式

*3
$3
set
$6
author
$8
codehole

服务端 --> 客户端

单行字符串响应

127.0.0.1:6379> set author codehole
OK

服务端响应内容

+OK

错误响应

// 试图对一个字符串进行自增的错误
127.0.0.1:6379> incr author
(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

多行字符串

// 双引号括起来的字符串其实是多行字符串
127.0.0.1:6379> get author
"codehole"

服务端响应内容

$8
codehole

数组响应

127.0.0.1:6379> hset info name testname
(integer) 1
127.0.0.1:6379> hset info age 30
(integer) 1
127.0.0.1:6379> hgetall info
1) "name"
2) "testname"
3) "age"
4) "30"

hgetall 响应内容

*4
$4
name
$8
testname
$3
age
$2
30

嵌套

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

服务端响应内容

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

总结

RESP 使用大量冗余的回车换行符, 已然是一个非常受欢迎的协议. 在技术领域, 性能并不是总是一切, 还有简单性, 易理解性和易实现性, 总之需要学会平衡.

标签: redis, 协议, RESP