PHP Redis超时,连接时读取错误


PHP Redis timeout, read error on connection?

"PHP致命错误:未捕获异常'RedisException',消息为'read error on connection'"

这里的驱动程序是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不会关闭与客户端的连接:连接将永远保持打开状态。"

据我所知,目前的解决方案是禁用phpredis的持久连接,因为自2011年10月以来,这些连接一直被报告为有缺陷。如果您使用的是php-fpm或其他线程模型,库会专门禁用持久连接。

可以通过调整php.ini default_socket_timeout值来降低此错误的频率。

此外,phpredis中的读取超时配置并不是普遍支持的。标签2.2.3中介绍了该功能(查找OPT_READ_TIMEOUT)。

$redis->connect(host, port, timeout1);

$redis->blpop($key, timeout2);

其中timeout1必须长于timeout2。

经过大量的文章研究,并对redis和php进行了自己的研究,这个问题似乎很容易通过这个解决方案解决。在我的用例中,主要的问题是redis服务器无法将进程分叉为将内存中的写入保存到磁盘上的数据库。

我在php.ini和redis.conf中保留了所有的超时值,没有进行建议的修改,然后单独尝试了上面的解决方案,这个问题"连接时读取错误"使用了所有关于在php和redisconf文件中更改超时值的建议都无法解决。

我还看到了一些关于将文件描述符限制提高到100000等的建议。我在云服务器上运行我的用例,文件描述符限制为1024,即使有这个限制,我的用例也能完美运行。

我在php程序中添加了代码ini_set(‘default_socket_timeout’, -1),但我发现它不能立即工作。

然而,3分钟后,当我再次开始运行php程序时,我终于找到了原因:redis连接不持久

所以我在redis.conf中设置了timeout=0,问题就解决了!

如果你使用的是PHPRedis,在你的PHP代码中,在使用redis longer命令之前添加这一行:

ini_set('default_socket_timeout', -1);

并更改Redis配置文件(/etc/redis.conf)中的timeout

timeout 0