摘自官方文档 Redis Protocol specification
一、简介
RESP 是 REdis Serialization Protocol (Redis序列化协议)的简称。
您可以选择在HELLO命令中使用 RESP3,该命令从 Redis v6.0 开始提供。Redis的 RESP3 规范草案目前由 redis-specifications 维护。
Redis客户端使用 RESP协议 与Redis服务器通信。虽然该协议是专门为Redis设计的,但它也可以用于其他客户机-服务器软件项目。
RESP可以序列化不同的数据类型,如整数、字符串和数组。还有一种特定类型————错误。请求以字符串数组的形式从客户端发送到Redis服务器,这些字符串表示要执行的命令的参数。Redis使用特定于命令的数据类型进行回复。
RESP是二进制安全的,不需要处理从一个进程传输到另一个进程的批量数据,因为它使用前缀长度来传输批量数据。
注意:此处概述的协议仅用于客户机-服务器通信。Redis Cluster使用不同的二进制协议在节点之间交换消息。
二、详细描述
RESP协议是在Redis v1.2中引入的,但直到Redis v2.0,它才成为(客户端)与Redis服务器通信的标准协议。
RESP实际上是一个序列化协议,支持以下数据类型:简单字符串、错误、整数、大容量字符串和数组。
RESP在Redis中用作请求-响应协议的方式如下:
- 客户端将命令作为批量字符串的RESP数组发送到Redis服务器。
- 服务器根据命令实现使用一种RESP类型进行响应。
- 在RESP中,某些数据的类型取决于第一个字节:
- 对于简单字符串,应答的第一个字节是
+
- 对于错误,回复的第一个字节为
-
- 对于整数,回复的第一个字节是
:
- 对于大容量字符串(Bulk String),应答的第一个字节是
$
- 对于数组,应答的第一个字节是
*
- 对于简单字符串,应答的第一个字节是
此外,RESP协议能够使用大容量字符串或数组的特殊变体来表示空值(Null)。
- Bulk字符串可以用以下特殊格式来表示值不存在(即表示空值)。
$-1\r\n
: 在这种特殊格式中,长度为-1,并且没有数据 - 空数组的概念也存在,并且是指定空值的另一种方式(通常使用空批量字符串,但出于历史原因,我们有两种格式)。
*-1\r\n
: 例如,当BLPOP命令超时时,它返回一个长度为-1的空数组
在RESP中,协议的不同部分始终以\r\n
(CRLF)终止。
五种数据类型的第一个字节,你都记清楚了么?
+
:简单字符串,-
:错误,$
:Bulk字符串,:
:整数,*
:数组
三、示例:
-
首先,在CMD中,输入
telnet localhost 6379
回车,以TCP方式访问Redis服务器 -
接着,按下
Ctrl
+]
,进入如图所示的 Telnet Client:
-
如果,此时直接按下回车(Enter),则你粘贴的内容可以正常显示在 CMD 窗口中;
-
如果在第2步之后,输入
quit
,再按下回车(Enter)可以退出 Telnet Client;
3.1 字符串
设置字符串的命令,例如 set abc 12345
:
*3
$3
set
$3
abc
$5
12345
拷贝以上内容,然后用 鼠标右键 在 telnet 中粘贴内容,然后回车,操作结果如图所示:
服务器的响应报文是 +OK\r\n
。
查询字符串的命令,例如 get abc
:
*2
$3
get
$3
abc
拷贝以上内容,然后用 鼠标右键 在 telnet 中粘贴内容,然后回车,结果如下图所示;
服务器的响应报文是 $5\r\n12345
。
3.2 列表
将一个或多个值 value 插入到列表 key 的表尾(最右边),例如 rpush language c
:
*3
$5
rpush
$8
language
$1
c
拷贝以上内容,然后用 鼠标右键 在 telnet 中粘贴内容,然后回车,结果如图所示:
服务器响应报文为 :1\r\n
接着,返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。例如 lrange language 0 -1
。
*4
$6
lrange
$8
language
$1
0
$2
-1
拷贝以上内容,然后用 鼠标右键 在 telnet 中粘贴内容,结果如图所示:
返回结果也是一个数组,响应报文为 *1\r\n$1\r\nc\r\n
Java实现 Redis客户端实战可以参考这篇 Redis系列(五):Redis的RESP协议详解