最近碰到在REDIS执行一步get操作的时候报出错误:Uncaught RedisException: read error on connection,感觉不可理解,REDIS连接没有发现问题,但是就是get失败,在redis的日志中也没有找到慢查询,说明这个报错也不是超时。连接没有发生问题,又没有超时,什么会读失败呢?
在网上找了些答案,但基本都是千遍一律地认为是这行配置的问题:
default_socket_timeout = 60;
都建议把它改成-1.不超时
ini_set('default_socket_timeout', -1); //在php程序中修改
default_socket_timeout = -1; //或者修改配置文件
原因都写着:由于redis扩展也是基于php 的socket方式实现,因此该参数值同样会起作用。但想想如果是这个配置的问题的话,那意思就是说请求redis读时超时了是不是?可这个配置的单位是秒啊!你能超60秒?如果一个请求超过了60秒还没有执行成功,这个值改大了又有什么意思?不知道网上碰到这个问题并写着按这个方法解决的朋友是不是后面再也没有碰到这个问题。
但我就是怀疑是这个地方的问题!
在网上找了些相关的资料,也出去看了一些。看到了这么一篇讨论,里面有一个回答:
http://stackoverflow.com/questions/18072407/php-redis-timeout-read-error-on-connection
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. 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.
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.
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.
其中提到的 by this solution 链接到了这篇文章的这个位置:从上面的说法来看这个是可以解决这个问题,我还没有测试验证。文章链接
https://groups.google.com/forum/#!msg/redis-db/3Eh2hhsXQ1g/_nAzuK--nYYJ 提到的解决方法如下:
> Ok further investigations showed that probably this is due to
> /proc/sys/vm/overcommit_memory
> If it's zero in your system try to set it to 1 or 2 and check what
> happens. I'm going to try this in few hours.
echo 1 > /proc/sys/vm/overcommit_memory
works perfectly! So the problem was with the kernel _estimating_ how
much memory would the forked process need. Echoing "1" as I understand
disables the check and enables the process to fork.
Since "0" is default of overcommit_memory, perhaps the issue is much
more common on Linux boxes. It also looks like MacOSX is free of this
issue.
If confirmed, it would be nice to have it added to the FAQ.
Great job and many thanks again
----------------------------------------------------------------
关于内核参数overcommit_memory的值的意义:
overcommit_memory文件指定了内核针对内存分配的策略,其值可以是0、1、2。
0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
修改方法:
/etc/sysctl.conf
vm.overcommit_memory=1
或者
sysctl vm.overcommit_memory=1
或者
echo 1 > /proc/sys/vm/overcommit_memory
本文地址:http://www.04007.cn/article/376.html 未经许可,不得转载. 手机访问本页请扫描下方二维码:
在使用redis的时候,出现了Error: read error on connection.
找了一下相关资料,在官方也有很多人提出这个问题
phpredis的作者的意思是,是因为default_socket_timeout的问题,将它设为0就好了.
但很多人都说设为0,在60秒后还是会挂 ,只有设为-1才OK
于是,在命令行下subscribe的时候,先init_set('default_socket_timeout',-1);
问题解决 .
http://www.neatstudio.com/show-2357-1.shtml