在官网http://redis.io/topics/protocol有对redis通信协议有做说明。
基于下面的一些原因,我想解析redis client protocol:
1、足够了解通信协议,有助于做出更好的系统设计。
2、学习RESP的设计思想,不仅能扩展我的思维,也许将来能应用于我的代码中。
3、因为有些人想将redis client直接并入自己已有的系统中;包括我在内。这个将在我下一篇文章再做说明。
下面我翻译一下http://redis.io/topics/protocol一些我认为重要的内容:
Redis clients communicate with the Redis server using a protocol called RESP (REdis Serialization Protocol). While the protocol was designed specifically for Redis, it can be used for other client-server software projects.
RESP is a compromise between the following things:
- Simple to implement.
- Fast to parse.
- Human readable.
RESP can serialize different data types like integers, strings, arrays. There is also a specific type for errors. Requests are sent from the client to the Redis server as arrays of strings representing the arguments of the command to execute. Redis replies
with a command-specific data type.
RESP is binary-safe and does not require processing of bulk data transferred from one process to another, because it uses prefixed-length to transfer bulk data.
Note: the protocol outlined here is only used for client-server communication. Redis Cluster uses a different binary protocol in order to exchange messages between nodes.
译:
redis客户端和redis服务端用一种名叫RESP(REdis Serialization Protocol)的协议通信。虽然这种协议专门为redis设计,但是它能被用于其它基于C/S模型的软件项目中。
RESP是基于下面一些事实的一种折衷方案:
- 易于实现
- 快速解释
- 人类可读
RESP能序列化不同的数据类型,例如整型,字符串,数组,还有专门的错误类型。客户端发送字符串数组请求到服务端,而字符串数组表示命令参数去执行。Redis会用专门的命令类型回复。
RESP是二进制安全的,同时过程转换中不需要大量的数据处理,因为它使用了前缀长度去转换批量数据。
注意:在这里概述的协议只用于客户端-服务端通信。而Redis集群为了不同节点交换消息使用了一种不同的二进制协议。
RESP is actually a serialization protocol that supports the following data types: Simple Strings, Errors, Integers, Bulk Strings and Arrays.
The way RESP is used in Redis as a request-response protocol is the following:
- Clients send commands to a Redis server as a RESP Array of Bulk Strings.
- The server replies with one of the RESP types according to the command implementation.
In RESP, the type of some data depends on the first byte:
- For Simple Strings the first byte of the reply is "+"
- For Errors the first byte of the reply is "-"
- For Integers the first byte of the reply is ":"
- For Bulk Strings the first byte of the reply is "$"
- For Arrays the first byte of the reply is "
*
"
Additionally RESP is able to represent a Null value using a special variation of Bulk Strings or Array as specified later.
In RESP different parts of the protocol are always terminated with "\r\n" (CRLF).
译:
RESP实际上是一种支持下面数据类型的序列化协议:短字符串,错误,整数,长字符串和数组。
RESP作为一种请求-回应协议,在Redis中的使用方法如下:
- 客户端发送一种犹如RESP中长字符串数组的命令到Redis服务端。
- Redis服务端根据命令实现回复其中一种RESP类型。
在RESP中,一种数据类型基于第一个字节:
- 对于短字符串,回复的第一个字节是"+"
- 对于错误,回复的第一个字节是"-"
- 对于整数,回复的第一个字节是":"
- 对于长字符串,回复的第一个字节是"$"
- 对于数组,回复的第一个字节是"*"
另外RESP能用指定的长字符串或数组的特殊变量来表示空值。
在RESP中,协议的不同部分总是以"\r\n"(CRLF)作为结束。
前面说到的协议,我有强调了是client,就是说server回复client请求时用到的协议;client请求server时,只需要在命令后面加上"\r\n"。
下面是5种类型的返回实例:
假设在redis server中存在以下键值对: name1 cat age1 10 短字符串 "set name2 fish\r\n" "+OK\r\n" 错误 "seet name3 dog" "-ERR unknown command 'seet'\r\n" 整数 "incr age1" ":11" 长字符串 ① "get name1\r\n" "$3\r\ncat\r\n" ② "get name3\r\n" "$-1\r\n" 数组 ① "mget name1 age1\r\n" "*2\r\n$3\r\ncat\r\n$2\r\n11\r\n" ② "mget name2 age2\r\n" "*2\r\n$4\r\nfish\r\n$-1\r\n" ③ 其它情况会返回"*-1\r\n"和"*0\r\n",具体参考redis官方文档;