redis的pipeline机制
主要的两个底层函数:
1.redisvAppendCommand将命令拷贝到context的obuf里
2.redisGetReply:
1)从reply队列里面返回最前面的reply,如果队列为空,继续后面的操作
2)如果发现obuf中有数据没有发送,那么发送cmd
3)等待回包(server会把cmd中所有的处理做完,然后回包,appand过几次,server就会返回几个reply);收到回包后,redisGetReply里面解析回包为reply(可能为多个,具体数量跟appand次数相同);然后返回最前面的reply
实现剖析:
1.非pipeline模式直接调用redisCommand也是变成redisvAppendCommand + __redisBlockForReply(redisGetReply)
2.pipeline模式就是N次redisvAppendCommand + N次redisGetReply
症结所在:
redisGetReply是纯粹的client行为,server并不知道。如果调用的appand次数与getreply次数不匹配,会引起混乱。
如果多调用了redisGetReply,那么就会直接block
抛砖引玉:
为了不让多一次的redisGetReply导致整个程序block挂住,可以修改hiredis的redisGetReply的实现:如果replylist为空并且outbuf中也没有数据的时候,直接返回数据为空的reply