解决Redis 延迟故障
前一段时间redis客户端在使用php connect 连接redis 的经常报一个redis server went away 等信息。
首先想到的想到的是reids超时设置的问题,timeout、tcp-keepalive、以及php的default_socket_timeout时间
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
注意这个socket时间不能改成0 要是0的话你会悲剧的。
测试 不解决还是ent away
php改 pconnect不解决。好吧,这个诡异的问题已经越来越严重了。
# 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
好吧检查网络
没问题…
哪还有什么能造成延迟呢?
AOF 和硬盘I/O操作延迟、数据过期造成的延迟、redis看门狗的延迟
从iostat上来看aof基本不会造成这方面的延迟可以排除掉
key过期:
好吧我们看看文档
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.
就是说有两种方式:
lazy 在key被请求的时候才检查是否过期
active 每0.1秒进行一次过期检查
好吧问问拍黄片的哥哥是否有大面积过期的key。咨询木有。
那找找看门狗吧
127.0.0.1:6381> config get watchdog
(empty list or set)
木有….
难道就真的没有办法了嘛
(当时没有抓包)苦恼的只能看配置 看日志找问题了
那就在重新浏览配置吧
能出问题的配置项只有:
timeout
tcp-keepalive
tcp-backlog
maxclients
查看一下当前的连接数 :
# 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
出问题的timeout tcp-keepalive 。
哪还有什么地址配置的呢?
sysctl
那查看一下 tcp方面的配置 主要是时间和队列长度的
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 150
net.ipv4.tcp_max_tw_buckets = 20000
那只能改一下这俩个试试了
测试解决
最后改成
net.ipv4.tcp_fin_timeout = 60
最后这个问题应该是应用层和内核层 连接时间不匹配导致的。
内核层超时断开了,应用层以为还能用,请求就过不去,只能再重新走一遍,就会间接性延迟。
可惜当时没有抓包。