redis超时排查

现象:服务起不来, log显示在初始化时从redis加载数据失败,程序自动退出

1. 问题确认

先查看服务连接的那台redis的slowlog 看看是不是读取数据超时

指令格式为 redis-cli.exe -p xxxx sloglog get num
-p表示指定端口,缺省值为6379
num缺省值为10

[root@slave1(101) ~]# /homed/redis/bin/redis-cli.exe -p 8888 sloglog get
...
7) 1) (integer) 186509
   2) (integer) 1557194683
   3) (integer) 80199888      #耗时ms
   4) (integer) 2
   5) "fd=162,peerip=192.168.2.113,peerport=48740,SrvTypeID=41612"
   6) 1) "processHValsCommand"
      2) "dtvs_column_program"
...

从redis日志查到失败的这条获取指令耗时 80199888ms, 就是80s,远大于程序设置的40s等待时间. 确认是redis读取数据超时导致.

2.问题排查

先确认数据大小, 是否是海量数据导致

[root@slave1(101) ~]# /homed/redis/bin/redis-cli.exe -p 8888 hlen dtvs_column_program
[redisFormatCommandArgv] send ipanel protocol msg(39 bits):
("*2\r\n$4\r\nhlen\r\n$19\r\ndtvs_column_program\r\n")
[redisBufferRead] read ipanel protocol msg(10 bytes):
(":1669675\r\n")
(integer) 1669675

发现数据量是百万级不算多, 并且返回长度的时候有将近一秒钟的卡顿,

再确认服务器cpu和内存情况

[root@slave1(101) ~]# top
top - 10:32:59 up 225 days, 23:06,  1 user,  load average: 0.09, 0.28, 0.32
Tasks: 244 total,   2 running, 241 sleeping,   0 stopped,   1 zombie
Cpu(s):  9.6%us,  2.8%sy,  0.0%ni, 82.9%id,  4.5%wa,  0.0%hi,  0.3%si,  0.0%st
Mem:   8010180k total,  6642364k used,  1367816k free,    41836k buffers
Swap:  8388600k total,  8321800k used,    66800k free,   143812k cached
#
#
[root@slave1(101) ~]# free -m 
             total       used       free     shared    buffers     cached
Mem:          7822       6487       1335          0         45        135
-/+ buffers/cache:       6306       1516
Swap:         8191       8126         65

发现服务器swap消耗很大, 由此怀疑是倒swap导致
Linux (以及其他一些操作系统) 可以把内存页存储在硬盘上,反之也能将存储在硬盘上的内存页再加载进内存,这种机制使得内存能够得到更有效的利用。
如果内存页被系统移到了swap文件里,而这个内存页中的数据恰好又被redis用到了(例如要访问某个存储在内存页中的key),系统就会暂停redis进程直到把需要的页数据重新加载进内存。这个操作因为牵涉到随机I/O,所以很慢,会导致无法预料的延迟。
所以更具redis进程的pid查询下redis进程的内存布局

[root@slave2(102) /home/redis/bin]# ps aux | grep redis
root      2946  1.5 11.1 27960492 896488 ?     Ssl  Mar17 1161:55 ./redis-server.exe slave pub8888Slave2 /homed/redis/bin/../config/redis-pub8888.conf
root      2952  0.5  0.0  51180  3372 ?        Ssl  Mar17 405:20 ./redis-sentinel.exe /homed/redis/bin/../config/sentinel-pub8887.conf
[root@slave2(102) /homed/redis/bin]# cd /proc/2946/
[root@slave2(102) /proc/2946]# ls
attr       cgroup      coredump_filter  environ  fdinfo  loginuid  mountinfo   net        oom_score      personality  schedstat  stack  status   wchan
autogroup  clear_refs  cpuset           exe      io      maps      mounts      numa_maps  oom_score_adj  root         sessionid  stat   syscall
auxv       cmdline     cwd              fd       limits  mem       mountstats  oom_adj    pagemap        sched        smaps      statm  task

在这里你会发现一个名为smaps 的文件,它描述了redis进程的内存布局 (假定你使用的是Linux 2.6.16或者更新的版本)。这个文件包括了很多进程所使用内存的细节信息,其中有一项叫做Swap的正是我们所关心的。不过仅看这一项是不够的,因为smaps文件包括有redis进程的多个不同的的内存映射区域的使用情况(进程的内存布局远不是线性排列那么简单)。
从我们对所有进程的内存交换情况感兴趣以来,我们首先要做的事情是使用grep命令显示进程的smaps文件

[root@slave2(102) /proc/2946]# cat smaps | grep 'Swap:'
Swap:                  0 kB
Swap:                  0 kB
Swap:                  4 kB
Swap:                  4 kB
Swap:            4459156 kB
Swap:                  0 kB
Swap:                 52 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:            1649036 kB
Swap:                 24 kB
Swap:                  0 kB
Swap:               6388 kB
Swap:                 24 kB
Swap:                496 kB
Swap:                  0 kB

假如所有的数据显示为0kb或者某些数据偶尔显示为4kb,表示当前一切正常。实际上我们的例子是一个真实的运行着Redis并每秒为数百的用户提供服务,会显示更多的交换页。为了研究是否存在一个严重的问题,我们改变命令打印出分配的内存尺寸

[root@slave2(102) /proc/2946]# cat smaps | egrep '^(Swap|Size)'
Size:               1200 kB
Swap:                  0 kB
Size:                 36 kB
Swap:                  0 kB
Size:                156 kB
Swap:                 52 kB
Size:                132 kB
Swap:                 24 kB
Size:               3628 kB
Swap:                496 kB
Size:                128 kB
Swap:                  0 kB
Swap:                  4 kB
Size:           18264064 kB
Swap:            4459172 kB
Size:                  4 kB
Swap:                  0 kB
Size:                680 kB
Swap:                  0 kB
Size:            7847936 kB
Swap:            1649572 kB
Size:                132 kB
Swap:                 24 kB
Size:              65404 kB
Swap:                  0 kB
Size:              24576 kB
Swap:               6392 kB
Size:                564 kB
Swap:                  0 kB
Size:                412 kB
Swap:                  0 kB

在输出信息中,你能看到有好些个较大的内存分配18264064kb(有4459172kb的交换),因此可能会产生任何的问题

假如进程的内存有相当部分花在了swap上,那么你的延迟可能就与swap有关。假如redis出现这种情况那么可以用 vmstat 命令来验证一下猜测:

[root@slave2(102) /proc/2946]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  1 8388600 1317960   7160  25988   10    4   822   332    0    0 21  8 64  7  0
 2  1 8388600 1317580   6460  25944    0    0  3384     0 34749 101745 21  6 55 18  0
 1  2 8388600 1318936   5384  26900    0    0  5684    36 35252 102194 21  7 53 20  0
 2  1 8388600 1316876   5792  28580   32    4  5860    52 35057 101769 20  6 53 20  0
 3  1 8388600 1322728   4128  23092    0    0  3288   296 35850 102399 20  8 51 21  0
 2  1 8388600 1324216   3896  21892    0    0  3132     4 35183 102094 20  6 55 19  0
 0  1 8388600 1324712   3872  21332    0    0  2792     0 35290 102133 20  7 54 19  0
 3  1 8388600 1324340   4036  21496    0    0  6096    12 35086 101848 20  7 51 22  0
 2  1 8388600 1327812   4032  18312    0    0  2220    56 35640 101922 21  6 53 20  0
 3  1 8388600 1331160   3632  15652    0    0  1828   132 35217 101961 21  6 52 21  0
 3  3 8388600 1331904   5148  14708   64    8  3056    52 35154 101981 20  8 44 28  0
 2  1 8388600 1324960   5756  20332    0    0 10296     4 35298 102324 20  6 55 19  0
 3  1 8388600 1325828   4596  20056    0    0  3248    16 34736 101586 20  7 54 19  0
 2  1 8388600 1326572   4208  19752   64    8  4360    72 35382 102168 20  7 52 21  0
 3  1 8388600 1329424   3668  20096    0    0  4808   464 35802 102230 20  7 50 23  0
 6  3 8388592 1323704   3968  25592   32    8 10420   264 36074 102460 21  7 46 26  0
 3  1 8388600 1323580   3572  25472    0    8  5828   168 35500 102488 21  7 49 23  0
 6  2 8388600 1320976   6528  26600   32    4  7836   184 35348 102614 22  6 46 26  0
 7  2 8388600 1321100   7432  24652   32    4  4148    40 35001 101978 20  7 53 20  0
 1  1 8388600 1326432   7280  19184    0    0  2616  1196 35605 102327 20  7 54 19  0
 0  2 8388600 1327912   5856  20424   32    4  5208   104 35453 102292 21  6 55 19  0
 4  1 8388600 1326904   5504  20324    0    0  3412    80 35506 102265 21  6 52 21  0

输出中我们最感兴趣的两行是si 和 so,这两行分别统计了从swap文件恢复到内存的数量和swap到文件的内存数量。如果在这两行发现了非0值那么就说明系统正在进行swap。
同时,可以用iostat命令来查看系统的全局I/O行为。

[root@slave2(102) /proc/2946]# iostat -xk 1
Linux 2.6.32-279.el6.x86_64 (slave2)    2019年05月07日  _x86_64_        (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          20.70    0.00    7.59    7.32    0.00   64.39

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sdf              10.35    51.54    8.10   22.02   172.65   294.28    31.00     0.09    2.96   3.28   9.88
sda              12.76    47.86   11.90    3.05   555.81   203.65   101.57     0.03    1.97   4.04   6.04
sdc              13.64    47.69   12.78    2.96   568.34   202.61    97.97     0.02    1.47   3.93   6.19
sdb              13.31    47.59   12.54    2.92   566.86   202.04    99.47     0.01    0.93   3.66   5.66
sde              13.13    47.58   12.45    2.93   565.38   202.06    99.76     0.02    1.00   3.88   5.97
sdd              52.61    46.87   28.04    3.20   794.41   200.30    63.68     0.10    3.18   2.53   7.92

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          21.52    0.00    6.58   31.65    0.00   40.25

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sdf               0.00    32.00    5.00    7.00    24.00   156.00    30.00     0.13   10.92   3.42   4.10
sda               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdc             439.00  1679.00  118.00   56.00  2452.00  6940.00   107.95     2.24   12.87   5.61  97.70
sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sde               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdd               0.00     0.00   20.00    0.00  2048.00     0.00   204.80     0.11    5.55   0.80   1.60

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          20.26    0.00    6.92   31.54    0.00   41.28

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sdf               0.00     0.00    3.00    0.00    12.00     0.00     8.00     0.01    5.00   5.00   1.50
sda               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdc             548.00     0.00  133.00    0.00  2948.00     0.00    44.33     1.15    8.69   7.42  98.70
sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sde               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdd               0.00     1.00   20.00    4.00  2048.00    20.00   172.33     0.57   23.88   4.00   9.60

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          20.67    0.00    6.20   28.17    0.00   44.96

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sdf               0.00    76.00    1.00    5.00     4.00   324.00   109.33     0.13   21.50   6.50   3.90
sda               0.00     0.00    0.00    1.00     0.00     4.00     8.00     0.00    3.00   3.00   0.30
sdc             476.00     0.00  143.00    0.00  2656.00     0.00    37.15     1.28    8.85   6.83  97.70
sdb               0.00     0.00    0.00    1.00     0.00     4.00     8.00     0.00    3.00   3.00   0.30
sde               0.00     1.00    0.00   23.00     0.00    96.00     8.35     0.15    6.48   4.91  11.30
sdd               0.00     0.00   32.00    0.00  2096.00     0.00   131.00     0.64   20.12   2.72   8.70

发现sdc的负载经常在90%以上, 同时再看了下服务的内存情况,发现swap已经耗完了.

[root@slave2(102) /proc/2946]# free -m
             total       used       free     shared    buffers     cached
Mem:          7822       6532       1289          0          6         46
-/+ buffers/cache:       6479       1343
Swap:         8191       8191          0

于是查一下哪个进程在占用磁盘io

方法 iotop -oP
命令的含义:只显示有I/O行为的进程

Total DISK READ: 8.82 M/s | Total DISK WRITE: 22.09 K/s
  PID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                                                                                                                                      
   58 be/4 root        0.00 B/s    0.00 B/s  0.00 % 99.99 % [kswapd0]
29732 be/4 root        4.87 M/s    0.00 B/s  0.00 %  1.94 % ./filebeat
 1148 be/4 root        7.36 K/s    7.36 K/s  0.00 %  1.44 % [kjournald]
28869 be/4 root        7.36 K/s    0.00 B/s  0.00 %  0.45 % top
 2946 be/4 root       18.41 K/s   11.05 K/s  0.00 %  0.19 % ./redis-server.exe slave pub8888Slave2 /homed/redis/bin/../config/redis-pub8888.conf
13034 be/4 root        0.00 B/s    7.36 K/s  0.00 %  0.03 % java -Dproc_journalnode -Xmx24000m -Djava.net.preferIPv4Stack=true -Dhadoop.log.dir=/wo~FA -Dhadoop.security.logger=INFO,RFAS org.apache.hadoop.hdfs.qjournal.server.JournalNode

发现有个和swap相关的[kswapd0]基本占用了所有io

$ pidstat -d 1
命令的含义:展示I/O统计,每秒更新一次

[root@slave2(102) /proc/2946]# pidstat -d 1
Linux 2.6.32-279.el6.x86_64 (slave2)    2019年05月07日  _x86_64_        (4 CPU)

14时20分31秒       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
14时20分32秒        58      0.00    461.54      0.00  kswapd0
14时20分32秒       576      7.69      0.00      0.00  flush-8:80
14时20分32秒      2278      0.00      3.85      0.00  zabbix_agentd
14时20分32秒      2946     23.08     19.23      0.00  redis-server.ex
14时20分32秒      2952      0.00      3.85      0.00  redis-sentinel.
14时20分32秒      2973      0.00      3.85      0.00  redis-server.ex
14时20分32秒     13034    973.08    138.46      0.00  java
14时20分32秒     20972   2092.31    580.77      0.00  java

14时20分32秒       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
14时20分33秒        58      0.00     28.00      0.00  kswapd0
14时20分33秒      2946      0.00     12.00      0.00  redis-server.ex
14时20分33秒      3033      0.00      4.00      0.00  redis-sentinel.
14时20分33秒     20972   2048.00      0.00      0.00  java
14时20分33秒     28869      8.00      0.00      0.00  top

14时20分33秒       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
14时20分34秒        58      0.00    572.00      0.00  kswapd0
14时20分34秒      2946      0.00      4.00      0.00  redis-server.ex
14时20分34秒      2952      0.00      4.00      0.00  redis-sentinel.
14时20分34秒      3054      0.00      4.00      0.00  redis-server.ex
14时20分34秒      3081      0.00      4.00      0.00  redis-server.ex
14时20分34秒     13034      8.00    160.00      0.00  java
14时20分34秒     20972   2304.00    176.00      0.00  java

14时20分34秒       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
14时20分35秒        58      0.00    196.00      0.00  kswapd0
14时20分35秒      1148      0.00      4.00      0.00  kjournald
14时20分35秒      1151      0.00     20.00      0.00  jbd2/sdf8-8
14时20分35秒      1581    172.00      0.00      0.00  rpcbind
14时20分35秒      2354     96.00      0.00      0.00  master
14时20分35秒      2946      0.00      4.00      0.00  redis-server.ex
14时20分35秒      3000      0.00      4.00      0.00  redis-server.ex
14时20分35秒      3087      0.00      4.00      0.00  redis-sentinel.
14时20分35秒      9780    232.00      0.00      0.00  pickup
14时20分35秒     20972   2076.00      0.00      0.00  java

14时20分35秒       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
14时20分36秒        58      0.00   4952.00      0.00  kswapd0
14时20分36秒       481      0.00     16.00      0.00  kjournald
14时20分36秒      1161      0.00     16.00      0.00  jbd2/sdb1-8
14时20分36秒      1992    128.00      0.00      0.00  snmpd
14时20分36秒      2946      0.00      4.00      0.00  redis-server.ex
14时20分36秒      2952      0.00      4.00      0.00  redis-sentinel.
14时20分36秒      2979      0.00      4.00      0.00  redis-sentinel.
14时20分36秒     20972    504.00   4356.00      0.00  java
14时20分36秒     28869      8.00      0.00      0.00  top
14时20分36秒     29732   2840.00      0.00      0.00  filebeat

14时20分36秒       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
14时20分37秒        58      0.00    472.00      0.00  kswapd0
14时20分37秒      1166      0.00     36.00      0.00  jbd2/sde1-8
14时20分37秒      1176      0.00     16.00      0.00  jbd2/sda1-8
14时20分37秒      2946      0.00      4.00      0.00  redis-server.ex
14时20分37秒     13034    104.00     20.00      0.00  java
14时20分37秒     20972   7152.00    616.00      0.00  java

发现除了kswapd0以外还有一个java进程在读io
再回到sdc所在的目录看看

root@slave2(102) /proc/2946]# df -h
文件系统              容量  已用  可用 已用%% 挂载点
/dev/sdf5              30G   20G  8.9G  69% /
tmpfs                 3.9G     0  3.9G   0% /dev/shm
/dev/sdf1             485M   37M  423M   8% /boot
/dev/sdf6              30G  3.4G   25G  12% /home
/dev/sdf2              40G  9.0G   29G  24% /usr
/dev/sdf3              40G  999M   37G   3% /var
/dev/sdf8             404G  319G   65G  84% /work
/dev/sdd1             1.8T  869G  873G  50% /data5
/dev/sdb1             1.9T  896G  875G  51% /data2
/dev/sde1             1.9T  893G  878G  51% /data4
/dev/sdc1             1.9T  889G  881G  51% /data3
/dev/sda1             1.9T  889G  881G  51% /data1
[root@slave2(102) /proc/2946]# cd /data3/
[root@slave2(102) /data3]# ll
总用量 28
-rw-r--r--. 1 root root    10 5月   7 14:24 disk_test.txt
-rw-rw-r--. 1 root root    20 9月  15 2017 zb_disk_check.txt
drwxr-xr-x. 3 root root  4096 2月  18 2014 hadoopdata
drwx------. 2 root root 16384 2月  15 2014 lost+found

发现有一个disk_test.txt的文件一直都在刷新. 由此怀疑是其他同事在做磁盘测试导致

你可能感兴趣的:(redis超时排查)