10分钟就理解Redis序列化协议,你也能编写redis客户端( 二 )


RESP简单字符串-Simple String
简单字符串的编码方式如下:

  • (1)第一个字节为+ 。
  • (2)紧接着的是一个不能包含CR或者LF字符的字符串 。
  • (3)以CRLF终止 。
简单字符串能够保证在最小开销的前提下传输非二进制安全的字符串 。例如很多Redis命令执行成功后服务端需要回复OK字符串,此时通过简单字符串编码为5字节的数据报如下:
+OKrn复制代码如果需要发送二进制安全的字符串,那么需要使用定长字符串 。
当Redis服务端用简单字符串响应时,Redis客户端库应该向调用者返回一个字符串,该响应到调用者的字符串由+之后直到字符串内容末尾的字符组成(其实就是上面提到的第(2)部分的内容),不包括最后的CRLF字节 。
RESP错误消息-Error
错误消息类型是RESP特定的数据类型 。实际上,错误消息类型和简单字符串类型基本一致,只是其第一个字节为- 。错误消息类型跟简单字符串类型的最大区别是:错误消息作为Redis服务端响应的时候,对于客户端而言应该感知为异常,而错误消息中的字符串内容应该感知为Redis服务端返回的错误信息 。错误消息的编码方式如下:
  • (1)第一个字节为- 。
  • (2)紧接着的是一个不能包含CR或者LF字符的字符串 。
  • (3)以CRLF终止 。
一个简单的例子如下:
-Error messagern复制代码Redis服务端只有在真正发生错误或者感知错误的时候才会回复错误消息,例如尝试对错误的数据类型执行操作或者命令不存在等等 。Redis客户端接收到错误消息的时候,应该触发异常(一般情况就是直接抛出异常,可以根据错误消息的内容进行异常分类) 。下面是错误消息响应的一些例子:
-ERR unknown command 'foobar'-WRONGTYPE Operation against a key holding the wrong kind of value复制代码-之后的第一个单词到第一个空格或换行符之间的内容,代表返回的错误类型 。这只是Redis使用的约定,不是RESP错误消息格式的一部分 。
例如,ERR是通用错误,WRONGTYPE则是更具体的错误,表示客户端试图针对错误的数据类型执行操作 。这种定义方式称为错误前缀,是一种使客户端能够理解服务器返回的错误类型的方法,而不必依赖于所给出的确切消息定义,该消息可能会随时间而变化 。
客户端实现可以针对不同的错误类型返回不同种类的异常,或者可以通过将错误类型的名称作为字符串直接提供给调用方来提供捕获错误的通用方法 。
但是,不应该将错误消息分类处理的功能视为至关重要的功能,因为它作用并不巨大,并且有些的客户端实现可能会简单地返回特定值去屏蔽错误消息作为通用的异常处理,例如直接返回false 。
RESP整型数字-Integer
整型数字的编码方式如下:
  • (1)第一个字节为: 。
  • (2)紧接着的是一个不能包含CR或者LF字符的字符串,也就是数字要先转换为字符序列,最终要输出为字节 。
  • (3)以CRLF终止 。
例如:
:0rn:1000rn复制代码【10分钟就理解Redis序列化协议,你也能编写redis客户端】许多Redis命令返回整型数字,像INCR,LLEN和LASTSAVE命令等等 。
返回的整型数字没有特殊的含义,像INCR返回的是增量的总量,而LASTSAVE是UNIX时间戳 。但是Redis服务端保证返回的整型数字在带符号的64位整数范围内 。
有些情况下,返回的整型数字会指代true或者false 。如EXISTS或者SISMEMBER命令执行返回1代表true,0代表false 。
有些情况下,返回的整型数字会指代命令是否真正产生了效果 。如SADD,SREM和SETNX命令执行返回1代表命令执行生效,0代表命令执行不生效(等价于命令没有执行) 。
下面的一组命令执行后都是返回整型数字:SETNX, DEL, EXISTS, INCR, INCRBY, DECR, DECRBY, DBSIZE, LASTSAVE, RENAMENX, MOVE, LLEN, SADD, SREM, SISMEMBER, SCARD 。
RESP定长字符串-Bulk String
定长字符串用于表示一个最大长度为512MB的二进制安全的字符串(Bulk,本身有体积大的含义) 。定长字符串的编码方式如下:
  • (1)第一个字节为$ 。
  • (2)紧接着的是组成字符串的字节数长度(称为prefixed length,也就是前缀长度),前缀长度分块以CRLF终止 。
  • (3)然后是一个不能包含CR或者LF字符的字符串,也就是数字要先转换为字符序列,最终要输出为字节 。
  • (4)以CRLF终止 。
举个例子,doge使用定长字符串编码如下:
第一个字节 前缀长度 CRLF 字符串内容 CRLF 定长字符串 $ 4 rn doge rn ===> $4rndogern foobar使用定长字符串编码如下:


推荐阅读