关于通讯协议,见https://redis.readthedocs.org/en/latest/topic/protocol.html
1)命令 set mykey myvalue 对应 要发送到Redis的字符串(要转化为二进制数据)是
"*3\r\n$3\r\nset\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n"
2)命令 get mykey 对应字符串是 "*2\r\n$3\r\nget\r\n$5\r\nmykey\r\n"
3)最后得到Redis发回的响应是 "+OK\r\n$7\r\nmyvalue\r\n"
我的问题是,Redis这样的响应格式,是否意味者 客户端发完命令(需要得到返回
值的命令如get)后,必须要等待回应到达之后才能发送下一个命令? 这样对客户端来说 效率是否低了点?
阿神2017-04-21 10:59:48
你对于”客户端来说 效率低“ 只是你空想而已吧?有数据做支持吗?没有任何数据做支持,只凭主观的感觉能够判断正确?
还有就是效率与业务的关系,一般而言,只有当效率不支持业务的时候,才会开始考虑效率的问题,你现在什么都还没做就考虑这个效率,是不是有点过早了?
最后补充一下。。这个就是tcp协议里面定义,如果还有什么不清楚,http://en.wikipedia.org/wiki/Transmission_Control_Protocol 到这里了解一下tcp规范。。
迷茫2017-04-21 10:59:48
可能这个问题变成: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命令测试)
譬如,我需要批量执行如下两个命令:
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,有兴趣的读者可以参看自己熟悉语言的客户端