我们目前遇到了很多Redis错误信息
无法连接:连接时读取错误,尝试下一台服务器
我们使用PHP Redis在FreeBSD上运行Redis,而且我们很难在Ubuntu上重现错误,所以这可能是一个暗示。 在github上这个话题有一个长期的问题 。
基本上我们通过调用phpredis中的connect(host, port, timeout)来从操作系统中获得一个套接字,但是当我们做了一个select(db_index)之后,我们会得到一个exception。 难道持续存在问题吗? 我假设连接在后台不做任何事情,并select尝试访问连接,这实际上是closures的。
我们不会遇到超时。 我们尝试调整TIME_WAIT没有成功。
关于问题可能来自哪里的任何其他想法? 跟踪这个问题的最好方法是什么? dtrace也许?
更新
我们正在研究我们的BGSAVE设置。 有趣的是,它花费了半秒多的时间来为定期将数据写入磁盘(持久化)的进程创build一个fork,并且redis在该时间段内无法响应connect()请求。
我们用下面的redis命令将错误率降低了90%:
CONFIG SET save ""
这会禁用BGSAVE,它会定期将所有数据库更改存储在磁盘上。 连接错误的原因很可能来自主Redis进程的阻塞fork()操作以启动BGSAVE进程。
redis.conf说:
# Redis may block too long on the fsync() call. Note that there is no fix for # this currently, as even performing fsync in a different thread will block # our synchronous write(2) call.
另请参阅此处如何使用简单的fork()实现该机制。 我们考虑从我们的池中使用一个专门的redis服务器,这个服务器负责BGSAVE操作,并且只使用其他的读/写。
从IRC聊天来看,似乎有一些其他公司遇到了同样的错误。 Bump也使用主/从系统。 奴隶不接受连接,只是坚持数据(见这里的黑客新闻的讨论 )
Hulu说:“为了保持分片上的性能一致,我们禁止在所有分片上写入磁盘,并且我们每天早上4点运行一个cron作业,在每个单独的实例上执行滚动”BGSAVE“命令。 ( 见这里 )
编辑:
事实certificate,这只是一个临时的解决办法。 负载增加,我们又回到了高错误率。 不过,我相当确信后台操作(例如分叉或短期后台进程)正在导致错误,因为错误消息总是出现在块中。
EDIT2:
由于Redis是单线程的,所以请始终关注长时间运行的操作,因为它们会阻塞其他所有操作。 一个例子是keys *命令。 避免它,并使用scan