首页 > Redis 通讯协议的疑问

Redis 通讯协议的疑问

关于通讯协议,见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)后,必须要等待回应到达之后才能发送下一个命令? 这样对客户端来说 效率是否低了点?


可能这个问题变成: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

*3\r\n$3\r\nset\r\n$4\r\nname\r\n$7\r\ndiaocow\r\n

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

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

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

  1. set name diaocow

  2. set country china

那么在一次请求中数据会是这样(假设我们使用标准协议): *3\r\n$3\r\nset\r\n$4\r\nname\r\n$7\r\ndiaocow\r\n*3\r\n$3\r\nset\r\n$7\r\ncountry\r\n$5\r\nchina\r\n

然后在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,有兴趣的读者可以参看自己熟悉语言的客户端


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

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

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


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

【热门文章】
【热门文章】