Redis中RESP 协议的作用是什么

发布时间:2021-08-05 16:09:20 作者:Leah
来源:亿速云 阅读:175

Redis中RESP 协议的作用是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

RESP 协议简介

Redis 的客户端和服务端之间在 TCP 协议的上层采用一种独立名为 RESP(REdis Serialization Protocol) 协议作为进行通讯的标准方式。

Redis 协议在以下几点之间做出了折衷:

新的统一协议已在Redis 1.2中引入,但是在Redis 2.0中,这就成为了与Redis服务器通讯的标准方式。在这个统一协议里,发送给Redis服务端的所有参数都是二进制安全的。Redis用不同的回复类型回复命令。它可以从服务器发送的第一个字节开始校验回复类型:

传输层及网络层

传输层仍然是底层 TCP 传输。Redis在TCP端口6379上监听到来的连接,客户端连接到来时,Redis服务器为此创建一个TCP连接。在客户端与服务器端之间传输的每个Redis命令或者数据都以\r\n结尾。Redis接收由不同参数组成的命令。一旦收到命令,将会立刻被处理,并回复给客户端。

关于校验回复类型

单行回复(单行字符串回复):"+"

状态回复(或者单行回复)以“+”开始以“\r\n”结尾的单行字符串形式。例如:

> set name leeprince
+OK\r\n  # 服务端实际返回
---
OK # redis-cli 客户端显示

错误消息(单行字符串回复的另外展示形式):"-"

错误回复发送类似于状态回复。唯一的不同是第一个字节用“-”代替“+”。

错误回复仅仅在一些意料之外的事情发生时发送,例如:如果你试图执行一个操作来应付错误的数据类型,或者如果命令不存在等等。所以当收到一个错误回复时,客户端将会出现一个异常。例如:

> leeprince
-(error) ERR unknown command `leeprince`, with args beginning with:\r\n  # 服务端实际返回
---
(error) ERR unknown command `leeprince`, with args beginning with:  # redis-cli 客户端显示

整型回复(正整形数字回复):":"

这种回复类型只是用CRLF结尾字符串来表示整型,用一个字节的“:”作为前缀。例如:“:0\r\n”,或者“:1000\r\n”是整型回复。

像INCR或者LASTAVE命令用整型回复作为实际回复值,此时对于返回的整型没有特殊的意思。它仅仅是为INCR、LASTSAVE的UNIX时间等增加数值。

一些命令像EXISTS将为true返回1,为false返回0。

其它命令像SADD、SREM和SETNX如果操作实际完成了的话将返回1,否则返回0。例如:

>rpush intkey intvalue01 intvalue02 intvalue03
:3\r\n   # 服务端实际返回
---
(integer) 3 # redis-cli 客户端显示

以下命令都是回复一个整型:

SETNX、DEL、EXISTS、INCR、INCRBY、DECR、DECRBY、DBSIZE、LASTSAVE、RENAMENX、MOVE、LLEN、SADD、SREM、SISMEMBER、SCARD。

批量回复(多行字符串回复):”$“

批量回复被服务器用于返回一个单二进制安全字符串。服务器发送第一行回复,该行以“$”开始后面跟随实际要发送的字节数,随后是CRLF,然后发送实际数据,随后是2个字节的额外数据用于最后的CRLF。例如:

>get bulkkey
$9\r\nbulkvalue\r\n   # 服务端实际返回
---
"bulkvalue"  # redis-cli 客户端显示

如果请求的值不存在,批量回复将使用特殊的值-1来作为数据长度,例如:

>get bulkkey_
$-1 # 服务端实际返回
---
(nil) # redis-cli 客户端显示

多个批量回复(数组回复):”*“

像命令LRNGE需要返回多个值(列表的每个元素是一个值,而LRANGE需要返回多于一个单元素)。使用多批量写是有技巧的,用一个初始行作为前缀来指示多少个批量写紧随其后。批量回复的第一个字节总是*,例如:

127.0.0.1:6379> rpush arraykey a01 a0101
(integer) 2 # redis-cli 客户端显示
127.0.0.1:6379> lrange arraykey 0 -1
# 服务端实际返回
*2\r\n$3\r\na01$5\r\na0101\r\n  
---
# redis-cli 客户端显示    
1) "a01"
2) "a0101"

正如您可以看到的多批量回复是以完全相同的格式使用Redis统一协议将命令发送给服务器。

服务器发送的第一行是*4\r\n,用于指定紧随着4个批量回复。然后传送每个批量写。

如果指定的键不存在,则该键被认为是持有一个空的列表,且数值0被当作多批量计数值来发送,例如:

127.0.0.1:6379> LRANGE nokey 0 1
# 服务端实际返回
*0
---
# redis-cli 客户端显示    
(empty list or set)

当BLPOP命令超时时,它返回nil多批量回复。这种类型多批量回复的计数器是-1,且值被当作nil来解释。例如:

127.0.0.1:6379> BLPOP nokey 1
# 服务端实际返回
*-1
---
# redis-cli 客户端显示
(nil)
(1.09s)

当这种情况发生时,客户端库API将返回空nil对象,且不是一个空列表。这必须有别于空列表和错误条件(例如:BLPOP命令的超时条件)。

多命令和管道(pipelining)

客户端能使用同样条件为了发出多个命令。管道用于支持多命令能够被客户端用单写操作来发送,它不需要为了发送下一条命令而读取服务器的回复。所有回复都能在最后被读出。

通常Redis服务器和客户端拥有非常快速的连接,所以在客户端的实现中支持这个特性不是那么重要,如果一个应用需要在短时间内发出大量的命令,管道仍然会非常快。

管道(Pipelining) VS 脚本(Scripting)

大量 pipeline 应用场景可通过 Redis 脚本(Redis 版本 >= 2.6)得到更高效的处理,后者在服务器端执行大量工作。脚本的一大优势是可通过最小的延迟读写数据,让读、计算、写等操作变得非常快(pipeline 在这种情况下不能使用,因为客户端在写命令前需要读命令返回的结果)。

应用程序有时可能在 pipeline 中发送 EVAL 或 EVALSHA 命令。Redis 通过 SCRIPT LOAD 命令(保证 EVALSHA 成功被调用)明确支持这种情况。

Redis 大量数据插入

pipe mode的工作原理是什么?

难点是保证redis-cli在pipe mode模式下执行和netcat一样快的同时,如何能理解服务器发送的最后一个回复。

这是通过以下方式获得:

redis-cli –pipe试着尽可能快的发送数据到服务器。
读取数据的同时,解析它。
一旦没有更多的数据输入,它就会发送一个特殊的ECHO命令,后面跟着20个随机的字符。我们相信可以通过匹配回复相同的20个字符是同一个命令的行为。
一旦这个特殊命令发出,收到的答复就开始匹配这20个字符,当匹配时,就可以成功退出了。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

推荐阅读:
  1. 为什么 Redis 6 只支持 RESP3 ?
  2. redis协议指的是什么

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

redis resp

上一篇:HDFS中fs.defaultFS端口的作用是什么

下一篇:如何解决某些HTML字符打不出来的问题

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》