“PHP致命错误:未捕获异常'RedisException',消息'连接时读取错误'”
这里的驱动程序是phpredis
$redis->blpop('a', 0);
这在1分钟后总是超时。我的redis.conf说超时0而$redis->getOption(Redis::OPT_READ_TIMEOUT)
返回double(0)
如果我这样做,它从未超时$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
为什么我需要-1? Redis文档说redis.conf中的timeout 0
永远不会让我失望。
“默认情况下,如果客户端闲置很多秒,则Redis的最新版本不会关闭与客户端的连接:连接将永远保持打开状态。”
答案 0 :(得分:10)
我所知道的当前解决方案是禁用phpredis的持久连接,因为它们已经reported as buggy since October 2011。如果您使用的是php-fpm或其他线程模型,那么库specifically disables persistent connections。
adjusting the php.ini default_socket_timeout
value可能会降低此错误的发生频率。
此外,phpredis中的读取超时配置并非普遍支持。功能(查找OPT_READ_TIMEOUT
)为introduced in tag 2.2.3。
答案 1 :(得分:2)
在对文章进行了大量研究并完成了我自己的redis和php之后,似乎这个问题很容易被solution修复。我的用例中的主要问题是redis服务器无法分叉进程以保存对磁盘数据库的内存中写入。
我已将所有超时值保留在php.ini和redis.conf中,因为它们没有进行建议的hacky更改,然后单独尝试上述解决方案,并且此问题“连接时读取错误”使用所有的无法修复围绕php和redis conf文件更改超时值的建议消失了。
我还看到了一些关于将文件描述符的限制增加到100000等的建议。我在云服务器上运行我的用例,文件描述符限制为1024,我的用例甚至可以完美地运行。
答案 2 :(得分:2)
$redis->connect(host, port, timeout1);
.....
$redis->blpop($key, timeout2);
其中tiemout1必须长于timeout2。
答案 3 :(得分:1)
我在我的php程序中添加了代码ini_set(‘default_socket_timeout’, -1)
,但我发现它确实无法正常工作。
然而,当我再次开始运行php程序3分钟后,终于找到了原因, redis连接不持久
然后我在timeout=0
中设置redis.conf
,问题解决了!