注册 登录

清河洛

redis的通信协议(protocol)

qingheluo2019-09-17清河洛1306
Redis客户端使用名为RESP(REdis序列化协议)的协议与Redis服务器通信。虽然该协议是专为Redis设计的,但它可以用于其他客户端-服务器软件项目RESP是以下事项之间的妥协:易于实施、快速解析、人类可读RESP实际上是一个支持以下数据类型的序列化协议:简单字符串,错误,整数,批量字符串和数组。RESP是二进制安全的,不需要处理从一个进程传输到另一个进程的批量数据,因为它使用前缀长度来传输批量数据注意:此处概述的协议仅用于客户端 - 服务器通信。Redis Cluster使用不同的二进制协议,以便在节点之间交换消息虽然RESP在技术上是非TCP特定的,但在Redis的上下文中...

Redis客户端使用名为RESP(REdis序列化协议)的协议与Redis服务器通信。虽然该协议是专为Redis设计的,但它可以用于其他客户端-服务器软件项目

RESP是以下事项之间的妥协:易于实施、快速解析、人类可读

RESP实际上是一个支持以下数据类型的序列化协议:简单字符串,错误,整数,批量字符串和数组。

RESP是二进制安全的,不需要处理从一个进程传输到另一个进程的批量数据,因为它使用前缀长度来传输批量数据

注意:此处概述的协议仅用于客户端 - 服务器通信。Redis Cluster使用不同的二进制协议,以便在节点之间交换消息

虽然RESP在技术上是非TCP特定的,但在Redis的上下文中,协议仅用于TCP连接或类似的面向流的连接(如Unix套接字)

客户端和服务器发送的命令或数据一律以\r(CRLF)结尾

请求协议:

新版统一请求协议在Redis 2.0版本成为Redis服务器通信的标准方式。在这个协议中,所有发送至Redis服务器的参数都是二进制安全(binary safe)的。

以下是这个协议的一般形式:

    *<参数数量> CR LF
    $<参数 1 的字节数量> CR LF
    <参数 1 的数据> CR LF
    ...
    $<参数 N 的字节数量> CR LF
    <参数 N 的数据> CR LF
    注:命令本身也作为协议的其中一个参数来发送

举个例子:

命令set mykey myvalue的请求协议为

    命令set mykey myvalue的请求协议为
    *3
    $3
    SET
    $5
    mykey
    $7
    myvalue
    这个命令的实际协议值如下:
    "*3\r$3\rSET\r$5\rmykey\r$7\rmyvalue\r"

回复协议:

Redis命令会返回多种不同类型的回复。通过检查服务器发回数据的第一个字节,可以确定这个回复是什么类型:

    简单字符串(Simple Strings)的第一个字节是 "+"
    错误(Errors)的第一个字节是 "-"
    整数(Integers)的第一个字节是 ":"
    增大字符串(Bulk Strings)的第一个字节是 "$"
    数组(Arrays)的第一个字节是 "*"

简单字符串回复

简单字符串回复按以下方式编码:加号字符("+"),后跟不能包含CR或LF字符的字符串(不允许换行),由CRLF终止("\r")

简单字符串回复用于以最小的开销传输非二进制安全字符串,通常由那些不需要返回数据的命令返回

当Redis使用简单字符串回复时,客户端库应该向调用者返回一个字符串,该字符串由‘+‘之后的第一个字符开始,直到字符串结尾,不包括最终的CRLF字节

如:"+OK\r",客户端就应该返回字符串"OK"

错误回复

错误回复和简单字符串回复非常相似, 不同的是错误回复的第一个字节是"-"

客户端库应该在收到错误回复时产生一个异常。

基本格式是:"-ERR/WRONGTYPE message\r"

在"-"之后,直到遇到第一个空格或新行为止,这中间的内容表示所返回错误的类型(这只是Redis使用的约定,不是RESP错误格式的一部分)。

ERR是一个通用错误类型,而WRONGTYPE则是一个更特定的错误类型。

客户端可以为不同类型的错误产生不同的异常,或者提供一种通用的方式,让调用者可以通过提供字符串形式的错误名来捕捉不同的错误。

整数回复

整数回复就是一个以":"开头,字符串表示的整数在中间,CRLF结尾的字符串表示的整数。

返回值的唯一限制是返回的整数保证在有符号的64位整数范围内。

被返回的整数没有什么特殊的含义, 如:INCR返回键的一个自增后的整数值,而LASTSAVE则返回一个UNIX时间戳

整数回复也被广泛地用于表示逻辑真和逻辑假: 如返回值1表示真,0表示假

还有一些命令,只在操作真正被执行了的时候(如SADD、SREM和SETNX),才返回1,否则返回0

以下命令都返回整数回复: SETNX、DEL、EXISTS、INCR、INCRBY、DECR、DECRBY、DBSIZE、LASTSAVE、RENAMENX、MOVE、LLEN、SADD、SREM、SISMEMBER、SCARD

增大字符串回复(Bulk Strings)

Bulk Strings用于表示长度最大为512MB的单个二进制安全字符串,如get命令

增大字符串按回复以以下方式编码:

    第一字节为 "$" 符号
    接下来跟着的是表示实际回复长度的数字值
    之后跟着一个CRLF
    再后面跟着的是实际字符串数据
    最末尾是另一个 CRLF

如果被请求的值不存在, 那么特殊值-1用作回复的长度值,并且没有数据:"$-1\r",这种回复称为空增大字符串(Null Bulk String)。

当服务器使用Null Bulk String回复时,客户端应该返回空对象(nil),而不是空字符串。

数组回复

数组回复类型将元素集合返回给客户端。如LRANGE命令

数组回复是由多个回复组成的,数组中的每个元素都可以是任意类型的回复

数组回复的第一个字节为"*",后跟一个字符串表示回复元素数量的整数值,再后面是一个CRLF,再后面跟着的则是回复的所有元素

    *3
    $3
    foo
    :7
    $5
    Hello

空白的数组回复:"*0\r",如lrange一个不存在的key

无内容的数组回复:"*-1\r",如命令超时

客户端库应该区别对待空白多条回复和无内容多条回复: 当Redis返回一个无内容多条回复时,客户端库应该返回一个null对象,而不是一个空数组



网址导航