
redis客户端通过使用一种叫resp(redis serialization protocol, redis序列化协议)协议与redis服务器交互。虽然这个协议是为redis而设计的,但它也可以用于其他client-server架构的软件系统。(译注: 从一些公开的资料来看,陌陌的im协议设计就参考了redis协议)
RESP 权衡了以下几个方面:
实现要简单解析要快方便人阅读
RESP可以序列化不同的数据类型,像integers、strings、arrays,对于错误也设计了特殊的类型。客户端以字符串参数数组的请求形式发送给Redis服务器执行,Redis返回命令相关的数据类型。
RESP是二进制安全(binary-safe)的,并且不需要解析由一个进程发送给另一个进程的bulk 数据,因为它使用长度前缀来传输bulk 数据。
注意:这里所说的协议只用于client-server的通信。Redis Cluster使用不同的二进制协议在node间进行消息交互。
网络层
客户端通过建立端口为6379的TCP连接与Redis通信。
虽然RESP从技术上来说并不是TCP相关的,但对Redis来说该协议只用于TCP(或者其他流式协议如Unix域协议)。 (译注:反观memcached, 既支持tcp, 也支持udp, 但实际上生产环境基本只用tcp。我认为这是一种过度设计了,搞不好还可能被骇客利用来做 memcached udp 反射攻击。。。)
请求响应模型
Redis 接收不同参数构成的命令。当命令接收到后就会被处理,然后响应发送给客户端。
这是最简单的模型了,但有两点例外:
Redis支持 pipelining (后文会提及)。所以客户端可以一次发送多个命令,然后等待响应。当客户端订阅了一个 Pub/Sub channel, 该协议会改变语意而变成一个推送协议,也就是说客户端不用发送命令,因为服务端在收到消息后会自动给客户端发送新的消息(对客户端订阅了的channel)。
除了这两点,Redis协议就是一个简单的请求-响应协议。
RESP协议描述
RESP协议在Redis 1.2引入,但它现在成为Redis 2.0的标准交互协议。你应该实现Redis客户端时采用该协议。
RESP事实上是一个支持以下类型的序列化协议:Simple Strings, Errors, Integers, Bulk Strings 和 Arrays。
RESP作为一种请求响应协议,在Redis中使用的方式如下:
客户端发送命令到Redis服务器,以RESP Bulk Strings数组的方式。服务器根据不同的命令实现,返回相应的RESP实现。
在RESP中,一些数据的类型由第一个字节确定:
对于SImple Strings 响应的第一个字节是“+”对于Errors 响应的第一个字节是 "-"对于Integers 响应第一个字节是 ":"对于Bulk Strings 响应第一个字节是 "$" 对于Arrays 响应第一个字节是 "*"
另外RESP可以用特殊的Bulk String或数组来表示 Null 值,后文会提及。
在RESP中协议不同部分总是用 "\r\n" (CRLF) 分隔。
RESP Simple Strings
Simple Strings通过以下方式编码:一个加号,后跟一个字符串, 字符串不包含CR或LF字符(不能有换行),以CRLF ("\r\n")结束。
SImple Strings 以最小的代价来传输非二进制安全的字符串。例如很多Redis命令在成功时响应"OK",就是用RESP Simple String 来编码的5个字节:
"+OK\r\n"
为了传输二进制安全的字符串,要用RESP Bulk Strings。
当Redis响应一个Simple String时,客户端库应该给调用者返回从第一个"+"字符到字符串结尾的字符串,不包括CRLF 字节。
RESP Errors
RESP 对于error有一种特殊的数据类型。实际上error就像RESP Simple String一样,但第一个字符串是"-"而不是加号。在RESP中 Simple Strings和Errors两者的真正区别在于errors被客户端作为异常,构成Error类型的字符串就是字符串本身。基本格式是:
"-Error message\r\n"
Error响应只会在有错误发生时才会发送,例如你操作了错误的数据类型,或者命令不存在等。当收到Error响应时,客户端应该抛出一个异常。
以下是error响应的例子:
-ERR unknown command 'foobar'-WRONGTYPE Operation against a key holding the wrong kind of value
在"-"到第一个空格或新行间的第一个词,表示返回的错误类型。这只是Redis自己的一种约定,并不是RESP Error 所规定的格式。
例如,ERR 是通用错误,而 WRONGTYPE 是一种更加具体的错误,表示客户端尝试操作错误的数据类型。这称为 Error Prefix (Error前缀),客户端可从此得知服务器返回错误的类型而不需依赖于那个确切的消息描述,后者会随时改变。
一个客户端的实现可能对不同的error返回不同类型的异常,或者向调用者返回代表错误的字符串。然而这种特性并不是必须的,因为这并没什么卵用,一些精简的客户端实现可能简单的返回一般的错误情况,例如 false。
RESP Integers
这种类型就是一个代表整数的以CRLF结尾的字符串,并以“:”字节开头。例如 ":0\r\n", 或 ":1000\r\n" 都是整数响应。
很多Redis命令返回RESP Integers, 像 INCR, LLEN 和 LASTS*E。
返回的整数并没什么特殊的含义,它就是 INCR 增加后的数字,LASTS*E 的UNIX时间戳等。但返回的整数可以保证是在64位有符号整数的范围内。
整数响应也被大量的用于表示true或false。例如EXISTS和 SISMEMBER 等命令会返回1表示true, 0表示false。
以下命令会返回一个整数: SETNX, DEL, EXISTS, INCR, INCRBY, DECR, DECRBY, DBSIZE, LASTS*E, RENAMENX, MOVE, LLEN, SADD, SREM, SISMEMBER, SCARD。
Android配合WebService访问远程数据库 中文WORD版
采用HttpClient向服务器端action请求数据,当然调用服务器端方法获取数据并不止这一种。WebService也可以为我们提供所需数据,那么什么是webService呢?,它是一种基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合到一起。 实现Android与服务器端数据交互,我们在PC机器j*a客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,
0
查看详情
RESP Bulk Strings
Bulk Strings 用于表示一个二进制安全的字符串,最大长度为512M。
Bulk Strings 的编码格式如下:
“$” 后跟字符串字节数(prefix length),以CRLF结束实际的字符串CRLF结束
所以字符串"foobar" 被编码成:
"$6\r\nfoobar\r\n"
空字符串:
"$0\r\n\r\n"
RESP Bulk String 也可以用一种代表Null值的特殊格式来表示不存在的值。这种特殊格式的长度值为-1, 并且没数据,所以Null表示为:
"$-1\r\n"
这称为 Null Bulk String。
当服务器返回Null Bulk String时,客户端API不应该返回空串,而是nil 对象。例如Ruby库应该返回 'nil' 而 C 库应该返回 NULL (或在返回的对象设置特殊的标记),等等。
RESP Arrays
客户端用RESP Arrays向Redis服务器发送命令。同样某些Redis命令要返回一个元素集合时也使用RESP Arrays作为返回的类型。一个例子是LRANGE 命令返回一个元素列表。
RESP Arrays使用以下格式发送:
“*” 为第一个字节,后跟数组的元素个数,然后CRLF。然后是数组中的每一个RESP类型表示的元素。
例如一个空数组表示为:
"*0\r\n"
而有两个RESP Bulk Strings "foo" 和 "bar" 的数组编码为:
"*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"
正如你所见,在数组前面的 *
"*3\r\n:1\r\n:2\r\n:3\r\n"
数组可以包含混合类型,它不要求所有的元素都是相同的类型。例如,一个有4个interges和1个bulk string的数组可以编码为:
*5\r\n :1\r\n :2\r\n :3\r\n :4\r\n $6\r\n foobar\r\n
(为清晰起见响应被分为多行)。
服务器发送的第一行 *5\r\n 表示后跟有5个响应,然后每个代表元素的响应被发送。
Null 数组的概念同样存在,它是Null值的替代方式 (通常使用Null Bulk String,但由于历史原因我们有两种格式)。
例如当BLPOP命令超时,它返回一个长度为-1的Null 数组,如下所示:
"*-1\r\n"
在服务端返回Null数组时,客户端库API应该返回null对象而不是空数组。区分返回空的列表与其他的情况(如BLPOP命令超时的情况)是有必要的。
RESP允许数组的数组。例如一个含两个数组的数组编码如下:
*2\r\n *3\r\n :1\r\n :2\r\n :3\r\n *2\r\n +Foo\r\n -Bar\r\n
高效解析Redis协议
尽管Redis协议非常可读并且容易实现,它却可以兼得二进制协议的高效。
RESP使用长度前缀来传输bulk 数据,所以不需要像JSON一样扫描数据负载中的特殊符号,或者用引号括住数据负载。
Bulk和Multi Bulk长度的处理可以一次处理一个字符,同时可以扫描CR字符,像如下的C代码:
#include <stdio.h>
int main(void) {
unsigned char *p = "$123\r\n";
int len = 0;
p++;
while(*p != '\r') {
len = (len*10)+(*p - '0');
p++;
}
/* Now p points at '\r', and the len is in bulk_len. */
printf("%d\n", len);
return 0;
}当第一个CR被识别后,后面的LF可以忽略不处理。然后bulk数据可以一次读取而不需要分析 数据负载。最后剩下的CR和LF字符串可以丢弃不处理。
与二进制协议比较性能时,Redis协议在大部分的高级语言实现起来足够简单,减少了客户端软件的bug数量。
注:
1. 协议中的CR和LF相当于分割符,命令间存在多个CRLF不应影响后续解析,应为多个CRLF应被忽略掉。例如:
$> (printf "PING\r\nPING\r\nPING\r\n\r\n\rPING\r\n"; sleep 1) | nc localhost 6379 +PONG +PONG +PONG +PONG
2. 对比一下memcached的协议,redis的协议确实设计得比较精简:
(1) 一致的请求形式。redis的请求都是以 Bluk String 数组发送,不同命令只是数组的元素个数不同,所有命令的处理可以先读取完整个数组再根据不同命令解析数组的参数;而不是像mc协议一样,不同请求的命令格式不同,那么在读取网络字节流的过程中就要对不同命令做不同的处理,增加了协议解析的难度。
(2) 长度前缀是高效解析协议的关键。字段长度信息并不是二进制协议的专利,文本协议也可以有。
更多Redis相关知识,请访问Redis使用教程栏目!
以上就是redis协议是什么意思的详细内容,更多请关注其它相关文章!
# 序列化
# 国际物流广告营销推广语
# 随州网站优化怎么样做好
# 网站建设规划书实例
# 高端网站建设免费分析
# 东莞微信网站建设品牌
# 外贸seo营销推广方案
# 做网站推广自己可以做吗
# 企业怎么建设自己的网站
# 河源优化网站公司
# 娄底网站优化推广教程
# redis协议是什么意思
# 不存在
# 发送给
# 它是
# 而不是
# 可以用
# 都是
# 多个
# 第一个
# 客户端
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
漫蛙漫画官方网站使用_漫蛙manwa网页版在线入口教程
抖音商城官网是什么_抖音商城官方网址与访问方法
冬季去寒冷地区旅游,以下哪种做法有助于缓解冻伤
Win11怎么开启HDR_Windows 11显示器画质增强设置
5G和6G的连接密度有什么区别 6G每平方公里能连接多少设备
Pandas中基于动态偏移量实现DataFrame列值位移的策略
《友玩*》创建群聊方法
抖音手机分身两个账号怎么切换?分身两个系统是一样的吗?
Dagster资产间数据传递与用户配置管理教程
C++怎么实现一个红黑树_C++高级数据结构与平衡二叉搜索树
奥克斯空调不制热啥毛病_奥克斯空调不制热原因分析及解决技巧
Python中处理嵌套字典与列表的数据提取与过滤教程
易车网官网直达入口 易车网在线登录入口
解决SQLAlchemy模型跨文件关联的Linter兼容性指南
win11资源管理器标签页怎么用 Win11文件管理器多标签高效操作【新功能】
漫蛙漫画官方版直通入口 2025漫蛙漫画免注册访问说明
J*aScript与HTML元素交互:图片点击事件与链接处理教程
曝《丝之歌》DLC有望开发!开发商还有神秘新企划
搜狗浏览器如何查找页面中的文字 搜狗浏览器Ctrl+F页面搜索功能
BunnyStream TUS视频上传指南:解决401认证错误与参数配置
服装短视频如何起号推广?服装短视频起号推广有什么要求?
《米姆米姆哈》米姆获取及技能攻略
《原神》月之一版本新增书籍一览
J*a中逻辑运算符如何使用_逻辑与或非的基础用法讲解
TikTok视频播放中断怎么办 TikTok播放异常修复方法
Firefox OS应用开发:解决XMLHttpRequest跨域请求阻塞问题
Google Drive API服务器端访问指南:服务账户认证详解
C++ switch case字符串_C++如何实现字符串switch匹配
PHP多语言网站的实现:会话管理与翻译函数优化教程
WooCommerce 新客户订单自动添加管理员备注教程
《随手记》关闭首页消息推送方法
如何取消数字签名
4399造梦西游3无敌版_4399游戏入口
Excel如何快速合并单元格内容_Excel文本合并与函数操作技巧
消除网页顶部意外空白线:CSS布局常见问题与解决方案
企查查官网和爱企查 企查查企业查询官网入口
Python定时发送QQ消息
芒果TV官网登录入口 芒果TV官方网站登录入口
PDF文件去水印平台入口 PDF水印删除网址
uc浏览器官网网页版使用 uc浏览器官网免费在线首页
重返未来:1999卡戎全方位攻略
快递优选如何查优选物流_快递优选专属物流渠道查询与配送时效
Lar*el 中高效执行多列更新:单次查询实现
《土豆雅思》修改密码方法
《KARDS》冬季扩展包“国土阵线”上线!全新“协力”机制改变战场格局
使用Google服务账号实现Google Drive API无缝集成与文件访问
Symfony路由参数转换器:实体存在性验证与错误处理策略
猫眼电影app如何筛选支持退改签的影院_猫眼电影退改签影院筛选方法
《全民k歌》音乐怎么下载到本地2025
win11关机几秒又自己开机 Win11关机自动重启问题修复
2019-07-04
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。