一、环境
1.服务器环境
Centos 7.3 16核64G AliCloud
2.问题
服务器的Iowait time达到60%
二、排查流程
1.通过top命令发现服务器的Iowait time非常高,严重影响服务器性能。
[root@zhangwan22222222 ~]# top
top - 15:07:40 up 2 days, 23:35, 10 users, load average: 5.02, 5.72, 6.97
Tasks: 560 total, 1 running, 558 sleeping, 0 stopped, 1 zombie
%Cpu0 : 8.7 us, 1.7 sy, 0.0 ni, 80.6 id, 9.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 19.5 us, 1.7 sy, 0.0 ni, 78.5 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 38.3 us, 2.7 sy, 0.0 ni, 57.0 id, 2.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 5.3 us, 0.3 sy, 0.0 ni, 94.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu4 : 40.1 us, 3.3 sy, 0.0 ni, 52.5 id, 4.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu5 : 1.3 us, 0.3 sy, 0.0 ni, 98.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu6 : 25.2 us, 3.0 sy, 0.0 ni, 71.2 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu7 : 2.0 us, 0.3 sy, 0.0 ni, 97.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu8 : 36.0 us, 3.0 sy, 0.0 ni, 60.7 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu9 : 11.3 us, 1.0 sy, 0.0 ni, 87.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu10 : 26.2 us, 2.7 sy, 0.0 ni, 70.8 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu11 : 8.7 us, 3.0 sy, 0.0 ni, 88.0 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
%Cpu12 : 25.3 us, 2.3 sy, 0.0 ni, 72.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu13 : 1.7 us, 7.3 sy, 0.0 ni, 91.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu14 : 28.7 us, 5.3 sy, 0.0 ni, 64.0 id, 2.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu15 : 2.3 us, 1.0 sy, 0.0 ni, 96.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 65808484 total, 467080 free, 14657588 used, 50683816 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 50511032 avail Mem
2.定位问题磁盘
[root@zhangwan22222222 xc]# iostat -x 2 5
Linux 3.10.0-514.26.2.el7.x86_64 (zhangwan22222222) 01/07/2018 _x86_64_ (16 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
33.53 0.00 5.00 25.59 0.00 35.89
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 25.03 1022.15 4257.57 734.19 196186.95 9116.98 82.26 15.91 3.18 3.16 3.33 0.16 79.69
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 21.14 0.00 0.00 0.00 0.00 0.00 0.00
avg-cpu: %user %nice %system %iowait %steal %idle
9.67 0.00 0.63 1.75 0.00 87.96
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 4.00 92.50 680.00 113.50 36380.00 856.00 93.85 1.61 2.03 2.27 0.60 0.40 31.60
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
avg-cpu: %user %nice %system %iowait %steal %idle
6.60 0.00 0.69 0.34 0.00 92.37
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.00 76.00 94.00 96.00 4070.00 690.00 50.11 0.24 1.25 1.74 0.78 0.42 8.05
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
avg-cpu: %user %nice %system %iowait %steal %idle
37.27 0.00 4.78 1.97 0.00 55.97
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.00 679.50 185.50 986.50 9398.00 6804.00 27.65 1.10 0.94 2.17 0.71 0.34 40.05
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
avg-cpu: %user %nice %system %iowait %steal %idle
56.36 0.00 6.56 2.16 0.00 34.92
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.00 1031.00 105.50 1325.00 5252.00 10276.00 21.71 1.08 0.75 2.00 0.65 0.30 42.60
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
上边的例子中,iostat 会每2秒更新一次,一共打印5次信息, -x 的选项是打印出扩展信息
第一个iostat 报告会打印出系统最后一次启动后的统计信息,这也就是说,在多数情况下,第一个打印出来的信息应该被忽略,剩下的报告,都是基于上一次间隔的时间。
在上面的例子中,vda的%util 是42.60%,说明了有进程正在写入到vda磁盘中。
3.查看哪个进程占用的I/O过高
使用iotop,ps,lsof
iotop
Total DISK READ : 51.40 M/s | Total DISK WRITE : 25.98 M/s
Actual DISK READ: 51.44 M/s | Actual DISK WRITE: 28.12 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
29746 be/4 mysql 50.51 M/s 122.75 K/s 0.00 % 40.81 % mysqld --basedir=/us~ysql.sock --port=3306
375 be/3 root 0.00 B/s 30.69 K/s 0.00 % 20.85 % [jbd2/vda1-8]
我没有记录当时的数据,这是解决后的。当时统计出来大量占用io读写的是mysql和[jbd2/vda1-8]
4.使用ps命令定位问题io进程
我们每5秒获取一次,一共获取10次。
[root@zhangwan22222222 xc]# for x in `seq 1 1 10`; do ps -eo state,pid,cmd | grep "^D"; echo "----"; sleep 5; done
D 375 [jbd2/vda1-8]
----
D 375 [jbd2/vda1-8]
----
D 375 [jbd2/vda1-8]
D 2747 sendmail: w0784B99002747 localhost [127.0.0.1]: DATA
----
D 375 [jbd2/vda1-8]
----
D 375 [jbd2/vda1-8]
----
D 375 [jbd2/vda1-8]
D 2878 php /web/phalcontest_2/task/run main main 24
----
D 375 [jbd2/vda1-8]
----
----
D 375 [jbd2/vda1-8]
----
----
D的状态一般是I/O出现了问题,说明进程在等待I/O,可以是磁盘I/O,网络I/O或者其他,详细:
https://blog.xupeng.me/2009/07/09/linux-uninterruptible-sleep-state/
到这里我们已经可以发现是pid为375的jbd2/vda1-8进程的问题。
5.lsof -p可以定位到进程写入的文件
[root@zhangwan22222222 xc]# lsof -p 375
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
jbd2/vda1 375 root cwd DIR 253,1 4096 2 /
jbd2/vda1 375 root rtd DIR 253,1 4096 2 /
jbd2/vda1 375 root txt unknown /proc/375/exe
这里定位到文件我不知道如何利用,但是我们已经知道了问题进程。
三、解决
1.
使用iotop发现这个进程 jdb2/sdb1-8 使用率高达40%到90%。
2.修改mysql参数
(1)第一步
修改sync_binlog=1为sync_binlog=10
因为sync_binlog=1导致事务写入太频繁,改为10后Iowait time明显下降。
可能还有个参数innodb_flush_log_at_trx_commit也会影响io性能,我设置的这个值是2,所以就没有修改
以下摘自网络:
sync_binlog”:这个参数是对于MySQL系统来说是至关重要的,他不仅影响到Binlog对MySQL所带来的性能损耗,而且还影响到MySQL中数据的完整性。对于“sync_binlog”参数的各种设置的说明如下:
sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘。
sync_binlog=n,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。
在MySQL中系统默认的设置是sync_binlog=0,也就是不做任何强制性的磁盘刷新指令,这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。而当设置为“1”的时候,是最安全但是性能损耗最大的设置。因为当设置为1的时候,即使系统Crash,也最多丢失binlog_cache中未完成的一个事务,对实际数据没有任何实质性影响。
从以往经验和相关测试来看,对于高并发事务的系统来说,“sync_binlog”设置为0和设置为1的系统写入性能差距可能高达5倍甚至更多。
这里的解决方法转自:
http://www.cnblogs.com/z-books/p/7324949.html
(2)第二步
这一步要根据自己服务器的情况修改,多核cpu可以通过这两个参数更有效的利用cpu性能
innodb_write_io_threads = 32
#脏页写的线程数,加大该参数可以提升写入性能.mysql5.5以上才有。
innodb_read_io_threads = 16
#读取