Loading... <p>前一段时间redis客户端在使用php connect 连接redis 的经常报一个redis server went away 等信息。</p> <p>首先想到的想到的是reids超时设置的问题,timeout、tcp-keepalive、以及php的default_socket_timeout时间</p> <pre> 127.0.0.1:6381> CONFIG GET * 17) "timeout" 18) "0" 19) "tcp-keepalive" 20) "0" vim xxx/php_path/php.ini default_socket_timeout = 300</pre> <p>注意这个socket时间不能改成0 要是0的话你会悲剧的。</p> <p>测试 不解决还是ent away</p> <p>php改 pconnect不解决。好吧,这个诡异的问题已经越来越严重了。</p> <pre> # vmstat 1 3 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 0 6022256 383340 10371320 0 0 0 25 0 0 0 0 100 0 0 0 0 0 6022380 383340 10371368 0 0 0 116 6401 3463 0 0 100 0 0 0 0 0 6022380 383340 10371368 0 0 0 16 5880 3022 0 0 100 0 0 # iostat -x -k 1 Linux 2.6.18-308.el5 (yq-bbsrqueue1) 12/24/2015 avg-cpu: %user %nice %system %iowait %steal %idle 0.07 0.00 0.05 0.00 0.00 99.87 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util cciss/c0d0 0.00 2.52 0.00 0.51 0.20 12.12 48.39 0.00 0.47 0.25 0.01 cciss/c0d0p1 0.00 2.52 0.00 0.51 0.20 12.12 48.39 0.00 0.47 0.25 0.01 cciss/c0d1 0.00 91.90 0.00 3.32 0.44 380.88 229.15 0.03 9.40 0.19 0.06 cciss/c0d1p1 0.00 91.90 0.00 3.32 0.44 380.88 229.15 0.03 9.40 0.19 0.06</pre> <p>好吧检查网络<br style="margin: 0px;padding: 0px" />没问题…</p> <p>哪还有什么能造成延迟呢?<br style="margin: 0px;padding: 0px" />AOF 和硬盘I/O操作延迟、数据过期造成的延迟、redis看门狗的延迟</p> <p>从iostat上来看aof基本不会造成这方面的延迟可以排除掉</p> <p>key过期:<br style="margin: 0px;padding: 0px" />好吧我们看看文档</p> <pre> Latency generated by expires Redis evict expired keys in two ways: One lazy way expires a key when it is requested by a command, but it is found to be already expired. One active way expires a few keys every 100 milliseconds.</pre> <p>就是说有两种方式:<br style="margin: 0px;padding: 0px" />lazy 在key被请求的时候才检查是否过期<br style="margin: 0px;padding: 0px" />active 每0.1秒进行一次过期检查<br style="margin: 0px;padding: 0px" />好吧问问拍黄片的哥哥是否有大面积过期的key。咨询木有。</p> <p>那找找看门狗吧</p> <pre> 127.0.0.1:6381> config get watchdog (empty list or set)</pre> <p>木有….</p> <p>难道就真的没有办法了嘛<br style="margin: 0px;padding: 0px" />(当时没有抓包)苦恼的只能看配置 看日志找问题了</p> <p>那就在重新浏览配置吧</p> <p>能出问题的配置项只有:<br style="margin: 0px;padding: 0px" />timeout<br style="margin: 0px;padding: 0px" />tcp-keepalive<br style="margin: 0px;padding: 0px" />tcp-backlog<br style="margin: 0px;padding: 0px" />maxclients</p> <p>查看一下当前的连接数 :</p> <pre> # redis-stat host 10.xx.xxx.xxx port 6381 ------- data ------ --------------------- load -------------------- - child - keys mem clients blocked requests connections 4325509 2.00G 25 0 526898898 (+526898898) 100841471 4325510 2.00G 14 0 526899989 (+1091) 100841670 4325511 2.00G 20 0 526901583 (+1594) 100841933 4325509 2.00G 16 0 526903336 (+1753) 100842128 4325511 2.00G 9 0 526904748 (+1412) 100842328</pre> <p>出问题的timeout tcp-keepalive 。<br style="margin: 0px;padding: 0px" />哪还有什么地址配置的呢?<br style="margin: 0px;padding: 0px" />sysctl<br style="margin: 0px;padding: 0px" />那查看一下 tcp方面的配置 主要是时间和队列长度的<br style="margin: 0px;padding: 0px" />net.ipv4.tcp_fin_timeout = 30<br style="margin: 0px;padding: 0px" />net.ipv4.tcp_keepalive_time = 150<br style="margin: 0px;padding: 0px" />net.ipv4.tcp_max_tw_buckets = 20000</p> <p>那只能改一下这俩个试试了</p> <p>测试解决</p> <p>最后改成<br style="margin: 0px;padding: 0px" />net.ipv4.tcp_fin_timeout = 60<br style="margin: 0px;padding: 0px" />最后这个问题应该是应用层和内核层 连接时间不匹配导致的。<br style="margin: 0px;padding: 0px" />内核层超时断开了,应用层以为还能用,请求就过不去,只能再重新走一遍,就会间接性延迟。</p> <p>可惜当时没有抓包。</p> <p>http://www.redis.io/topics/latency<br style="margin: 0px;padding: 0px" />官方文档</p> <p></p> 最后修改:2021 年 12 月 10 日 10 : 53 AM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 赞赏作者 支付宝微信