前段时间写了个文章详细描述了在什么场景下会出现redis的protocol error错误,但是手抽筋, 不小心点错给删了,而且还原不了,没办法了,只能重写一下,但是没上次那么详细了,如果不太明白就看源代码吧!首先呢,这种错误是基于使用了phpredis的的长连接和multi功能才会出现!这里有两个问题
1、当你开了事务,做了N次写操作,然后又discard之后又做了M次操作(M小于N),这样请求就会被阻塞住,具体看代码:
$redis->multi();
$redis->set('test', 10);
$redis->zIncrBy('test2', 1, 'bbb');
$redis->discard();
$redis->multi();
$redis->zIncrBy('test2', 2, 'bbb');
$redis->exec();//操作会阻塞在这里
因为phpredis在discard成功后,没有清理callback list,所以卡住了。
2、开事务,做N次操作,discard之后再做M次操作(但这里M大于N),多刷几次就会出现protocol error!
redis->multi();
redis->set('test', 10);
redis->discard();
redis->multi();
redis->zIncrBy('test2', 2, 'bbb');
redis->zIncrBy('test2', 1, 'bbb');
redis->exec();
跟上面原因一样,discard没的清理callback list, 就会出现stream里面的数据没读完!协议就完全乱掉了,
本想着提个bug给phpredis就好了,结果提了也不见他们修改,于是就自己改了,修改的地方:
原文地址:http://my.oschina.net/scgywx/blog/296755
阅读(4445) | 评论(0) | 转发(0) |