最近碰到在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