简体   繁体   English

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

[英]PHP Redis timeout, read error on connection?

"PHP Fatal error: Uncaught exception 'RedisException' with message 'read error on connection'" “PHP 致命错误:未捕获的异常 'RedisException' 带有消息 '读取连接错误'”

The driver here is phpredis这里的驱动程序是phpredis

$redis->blpop('a', 0);

This always times out after ~1 minute.这总是在大约 1 分钟后超时。 My redis.conf says timeout 0 and $redis->getOption(Redis::OPT_READ_TIMEOUT) returns double(0)我的 redis.conf 说 timeout 0 和$redis->getOption(Redis::OPT_READ_TIMEOUT) redis- $redis->getOption(Redis::OPT_READ_TIMEOUT)返回double(0)

If I do this it has never timed out $redis->setOption(Redis::OPT_READ_TIMEOUT, -1);如果我这样做,它永远不会超时$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);

Why do I need -1?为什么我需要-1? Redis documentation says timeout 0 in redis.conf should never time me out. Redis 文档说 redis.conf 中的timeout 0不应该让我超时。

"By default recent versions of Redis don't close the connection with the client if the client is idle for many seconds: the connection will remain open forever." “默认情况下,如果客户端空闲几秒钟,Redis 的最新版本不会关闭与客户端的连接:连接将永远保持打开状态。”

The current solution I know of is to disable persistent connections for phpredis, as they have been reported as buggy since October 2011 .我所知道的当前解决方案是禁用 phpredis 的持久连接,因为它们自 2011 年 10 月以来就被报告为有问题。 If you're using php-fpm or other threaded models, the library specifically disables persistent connections .如果您使用 php-fpm 或其他线程模型,该库会专门禁用持久连接

Reducing the frequency of this error might be possible by adjusting the php.ini default_socket_timeout value .通过调整 php.ini default_socket_timeout可能会降低此错误的频率。

Additionally, read timeout configurations in phpredis are not universally supported.此外,phpredis 中的读取超时配置并非普遍支持。 The feature (look for OPT_READ_TIMEOUT ) was introduced in tag 2.2.3 .该功能(查找OPT_READ_TIMEOUT )是在标签 2.2.3引入的

After a lot of study of articles and doing my own strace's of redis and php, it seemed the issue was easily fixed by this solution .经过大量的文章研究和我自己的 redis 和 php 的 strace 的研究,似乎这个问题很容易被这个解决方案解决 The main issue in my use case was that redis server is not able to fork a process towards saving the in-memory writes to the on-disk db.我的用例中的主要问题是 redis 服务器无法分叉将内存写入保存到磁盘数据库的进程。

I have left all the timeout values in php.ini and redis.conf as they were without making the hacky changes suggested and then tried the above solution alone, and this issue 'read error on connection' that was unfixable using all the suggestions around changing timeout values across php and redis conf files went away.我将所有超时值保留在 php.ini 和 redis.conf 中,因为它们没有进行建议的hacky更改,然后单独尝试了上述解决方案,并且使用有关更改的所有建议无法修复此问题“连接时读取错误” php 和 redis conf 文件中的超时值消失了。

I also saw some suggestions around increasing limit on file descriptors to 100000 etc. I am running my use case on a cloud server with file descriptor limit at 1024 and my use case runs even with that limit perfectly.我还看到了一些关于将文件描述符限制增加到 100000 等的建议。我在云服务器上运行我的用例,文件描述符限制为 1024,我的用例即使在该限制下也能完美运行。

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

..... .....

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

In which timeout1 must be longer than timeout2.其中 timeout1 必须比 timeout2 长。

I added the code ini_set('default_socket_timeout', -1) in my php program, but I found it didn't work immediately.我在我的 php 程序中添加了代码ini_set('default_socket_timeout', -1) ,但我发现它并没有立即起作用。

However after 3 minutes when I started to run the php program again, at last I found the reason: the redis connection is not persistent但是3分钟后我再次开始运行php程序,终于找到原因: redis连接不持久

So I set timeout=0 in my redis.conf , and the problem is solved!所以我在我的redis.conf设置了timeout=0 ,问题解决了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM