Redis通信机制:简介RESP协议
RESP(Redis serialization protocol)是Redis客户端与服务端通信的协议。本文简单介绍了RESP协议的内容。官方文档
简述
RESP支持传输五种数据:简单字符串、错误、整数、大容量字符串和数组。
当客户端向服务器发送请求时,将命令存放在数组中;对于这些命令,服务端返回以上五种数据中的一种作为响应。
在RESP中,第一个字节确定了数据类型:
- 简单字符串:
+
- 错误:
-
- 整数:
:
- 大容量字符串:
$
- 数组:
*
RESP可以使用大容量字符串或数组的特殊形式作为Null
值。
在RESP中,消息总是以\r\n
结尾。
简单字符串
简单字符串以+
开头,不准出现\r
或\n
(只能有一行),以\r\n
结尾。
简单字符串用于以最小开销表示简单数据。例如,对于OK
消息,它的编码为:
1 | "+OK\r\n" |
简单的字符串是二进制不安全的。如果需要加密,使用大容量字符串。
当客户端收到简单字符串时,应当以字符串内容作为响应。它包括除了+
与CRLF
以外的内容。
错误
错误消息类似于简单字符串,它以-
开头,后跟的数据为错误消息。
1 | "-Error message\r\n" |
只有当出现异常时才应该发送错误消息。为了方便,从-
到第一个空格或结尾的字符串表示错误的类型,称为错误前缀,使得接收方能够区分错误的类型。
1 | "-ERR unknown command 'helloworld'" |
整数
整数的格式为:
后跟一个数字,这个数字必须在64位有符号整数的表示范围内。
除了用来传输数字,整数还可以作为消息执行成功与否的回应,或用来表示布尔值。有一些指令规定使用数字作为回复,如INCR
、LLEN
等。
大容量字符串
大容量字符串可以用于传输二进制安全的,最大512MB的字符串。它按如下方式编码:
$
是第一个字节的内容,后跟一个数字,表示字符串的长度(单位为字节),以CRLF
结尾。- 实际内容
- 结尾的
CRLF
例如
1 | "$5\r\nhello\r\n" |
空字符串表示为
1 | "$0\r\n\r\n" |
要用大容量字符串表示空值,只需要将前缀长度设置为-1,例如
1 | "$-1\r\n" |
数组
客户端使用数组向服务端发送指令。当服务器需要返回一系列数据时,使用数组作为响应,例如LRANGE
。
数组的格式为:
- 第一个字节是
*
,后跟一个数字表示数组元素的数量,以CRLF
结尾。 - 后跟附加的元素。对于每一个元素,其格式参考之前的内容。
一个空数组的格式为:
1 | "*0\r\n" |
["hello", "world"]
表示为:
1 | "*2\r\n$5\r\nhello\r\n$5\r\nworld\r\n" |
数组可以保存不同类型的数据,例如
1 | *5\r\n |
数组同样可以表示为Null
值:
1 | *-1\r\n |
数组支持层次结构,例如,由两个数组组成的一个数组可以表示为:
1 | *2\r\n |
向Redis服务端发送命令
客户端使用数组类型向服务端发送指令,且指令中所有字符串都是大容量字符串;服务端可以向客户端发送任意数据。
例如,客户端向服务器端发送指令LLEN mylist
1 | C: *2\r\n |
多个指令与流水线
RESP支持流水线机制,客户端可以使用相同的连接发送多个指令。
内置指令
Redis支持一些内置指令,这些指令只需要通过TCP发送,不需要使用客户端。
1 | C: PING |