Redis 通讯协议的疑问

浏览:41日期:2022-09-03

问题描述

关于通讯协议,见https://redis.readthedocs.org/en/latest/topic/protocol.html

1)命令 set mykey myvalue 对应 要发送到Redis的字符串(要转化为二进制数据)是

'*3rn$3rnsetrn$5rnmykeyrn$7rnmyvaluern'

2)命令 get mykey 对应字符串是 '*2rn$3rngetrn$5rnmykeyrn'3)最后得到Redis发回的响应是 '+OKrn$7rnmyvaluern'我的问题是,Redis这样的响应格式,是否意味者 客户端发完命令(需要得到返回

值的命令如get)后,必须要等待回应到达之后才能发送下一个命令? 这样对客户端来说效率是否低了点?

问题解答

回答1:

这是普通的TCP流传输方式。

回答2:

你对于”客户端来说 效率低“ 只是你空想而已吧?有数据做支持吗?没有任何数据做支持,只凭主观的感觉能够判断正确?

还有就是效率与业务的关系,一般而言,只有当效率不支持业务的时候,才会开始考虑效率的问题,你现在什么都还没做就考虑这个效率,是不是有点过早了?

最后补充一下。。这个就是tcp协议里面定义,如果还有什么不清楚,http://en.wikipedia.org/wiki/Transmission_Control_Protocol 到这里了解一下tcp规范。。

回答3:

可能这个问题变成:redis一次请求中是否只能发送一个命令? 会更好

结论: 无论采用哪种redis请求协议,都支持在一个请求中发送多个命令

redis请求协议

非标准redis请求协议格式(又称Inline):

命令名 参数1 参数2 ... 参数N

set name diaocow

标准的redis请求协议格式:

*<参数数量>CR LF $<参数1的字节数量>CR LF <参数1的数据>CR LF ... $<参数N的字节数量>CR LF <参数N的数据>CR LF

*3rn$3rnsetrn$4rnnamern$7rndiaocowrn

所以当我们需要把键name的值设置成diaocow,可以使用上述两种协议格式完成(有兴趣的读者可以自己使用telnet或者nc命令测试)

Redis请求协议如何支持批量执行?(也就是大家常说的pipeline模式)

譬如,我需要批量执行如下两个命令:

set name diaocow

set country china

那么在一次请求中数据会是这样(假设我们使用标准协议): *3rn$3rnsetrn$4rnnamern$7rndiaocowrn*3rn$3rnsetrn$7rncountryrn$5rnchinarn

然后在redis内部,它会这样解析,伪代码:

def processInputBuffer(client): while (len(client.querybuf) > 0): # 获取命令名,参数个数,参数数组以及当前读取到querybuf位置 cmd, argc, argv, pos = parseCommandInfo(client.querybuf) # 执行命令 processCommand(cmd, argc, argv) # 切换到下一个命令 client.querybuf = client.querybuf[pos:-1]

parseCommandInfo会根据不同协议来解析:若第一个字节为’*’,则采用标准协议

备注: 所有redis客户端在实现批量发送命令功能,无非就是把多个命令按照我们刚才说的格式,一并发送给redis,有兴趣的读者可以参看自己熟悉语言的客户端

相关文章: