一文带你玩转 Redis 的 RESP 协议 !
Posted 天道酬勤——傻子王(AME)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文带你玩转 Redis 的 RESP 协议 !相关的知识,希望对你有一定的参考价值。
RESP 是 Redis 客户端与 Redis 服务器相互通信时使用的一个协议, 全称 REdis Serialization Protocol ,即 redis 串行协议,通俗易懂,也表明了 redis 的特点,串行化(单线程)
注意: RESP 协议是一个应用层协议,也就是说它的底层还是依赖于 tcp/ip
RESP 的设计哲学
Redis 的作者在设计 RESP 协议,制定了下面的三条原则:
- 实现要简单
- 对计算机来说,解析速度快
- 对人类来说,可读性强
请求报文格式
Redis 客户端请求服务器时,报文格式非常简单,模板如下(注意:这里为了方便查看,CRLF 后面我还进行了手动换行,实际上是没有的)
*<参数数量>CRLF
$<参数1的字节长度>CRLF
<参数1的数据>CRLF
...
$<参数N的字节长度>CRLF
<参数N的数据>CRLF
其实就3个要素,参数的总个数,参数的字节长度、参数数据
例如,启动 redis-cli 客户端,发送一条命令:
set key1 value1
则这条命令对应的 RESP 协议报文内容为
*3CRLF$3CRLFsetCRLF$4CRLFkey1CRLF$6CRLFvalue1
为了方便我们人类查看,我将 CRLF 控制字符打印出来
*3
$3
set
$4
key1
$6
value1
附上注释
*3 //* 表示报文的开始,3 表示有三个参数,分别是 set、key1、value1
$3 // $3 表示第一个参数长度为 3 个字节
set // 一个参数
$4 // 第二个参数长度为 4 个字节
key1 // 第二个参数
$6 // 第三个参数长度为 6 个字节
value1 // 第三个参数
客户端请求报文就是这么简单
响应报文格式
请求报文的格式只有一种,但响应报文的格式就多种多样了
简单字符串回复
简单字符串回复只有一行回复,回复的内容以 + 作为开头,不允许换行,并以 \\r\\n 结束。有很多指令在执行成功后只会回复一个 OK,使用的就是这种格式,能够有效的将传输、解析的开销降到最低。
例如上面的
set key1 value1
假设执行成功,返回报文为
+OKCRLF
错误回复
在 RESP 协议中,错误回复相当于简单字符串回复的变种形式,它们之间的格式也非常类似,区别只有第一个字符是以 - 作为开头,错误回复的内容通常是错误类型及对错误描述的字符串。
错误回复出现在一些异常的场景,例如当发送了错误的指令、操作数的数量不对时,都会进行错误回复。在客户端收到错误回复后,会将它视为异常。
例如
set1 key1 value1
由于没有 set1 这个命令,所以返回错误报文
-ERR unknown command `set1`, with args beginning with: `key1`, `value`,CRLF
整数回复
整数回复的报文非常简单
:数字CRLF
一般出现在用户执行 exists、 incr、llen 等返回结果是数值或布尔类型的命令时,例如
exists key1
的回复报文为
:1CRLF
批量回复
批量回复的报文,模板如下
$<内容长度>CRLF
<内容>CRLF
它以 $ 作为开头,后面是发送的字节长度,然后是 CRLF,然后发送实际的数据,最终以 CRLF 结束。如果没有要回复的信息,那么回复长度为 -1。
举例
get key1
的回复报文为
$6CRLF
value1CRLF
get key2
的回复报文为
$-1CRLF
多条批量回复
多条批量回复的报文与客户端请求报文一模一样
*<参数数量>CRLF
$<参数1的字节长度>CRLF
<参数1的数据>CRLF
...
$<参数N的字节长度>CRLF
<参数N的数据>CRLF
多见于获取 hash、set、list 等类型的相关数据时,例如
lrange key2 0 -1
的回复报文为
*2
$3
123
$6
123456
以上是关于一文带你玩转 Redis 的 RESP 协议 !的主要内容,如果未能解决你的问题,请参考以下文章