iotop发现jdb2/sdb1-8 io使用过高解决办法

一、现象

复制代码
[root@push-5-221 ~]# iotop
otal DISK READ: 0.00 B/s | Total DISK WRITE: 6.26 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                           
  795 be/3 root        0.00 B/s    0.00 B/s  0.00 % 95.80 % [jbd2/dm-0-8]
22952 be/4 rabbitmq    0.00 B/s    4.04 M/s  0.00 % 50.10 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
 8597 be/4 mysql       0.00 B/s   90.05 K/s  0.00 % 16.08 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
22960 be/4 rabbitmq    0.00 B/s   52.53 K/s  0.00 % 13.40 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
22955 be/4 rabbitmq    0.00 B/s  105.06 K/s  0.00 % 11.76 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
22948 be/4 rabbitmq    0.00 B/s   41.27 K/s  0.00 % 10.10 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
22947 be/4 rabbitmq    0.00 B/s   48.78 K/s  0.00 %  7.44 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
22921 be/4 rabbitmq    0.00 B/s   48.78 K/s  0.00 %  6.55 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
22946 be/4 rabbitmq    0.00 B/s   45.03 K/s  0.00 %  6.30 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
23039 be/4 rabbitmq    0.00 B/s   26.27 K/s  0.00 %  6.07 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
23002 be/4 rabbitmq    0.00 B/s   45.03 K/s  0.00 %  6.02 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
22964 be/4 rabbitmq    0.00 B/s   48.78 K/s  0.00 %  4.67 % beam.smp -W w -A 128 -P 10~inet_dist_listen_max 25672
11655 be/4 mysql       0.00 B/s    0.00 B/s  0.00 %  2.77 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
30533 be/4 mysql       0.00 B/s    7.50 K/s  0.00 %  2.72 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
 4458 be/4 mysql       0.00 B/s    3.75 K/s  0.00 %  1.87 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
 6629 be/4 mysql       0.00 B/s    3.75 K/s  0.00 %  1.66 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
 6116 be/4 mysql       0.00 B/s    3.75 K/s  0.00 %  1.62 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
19645 be/4 mysql       0.00 B/s    3.75 K/s  0.00 %  1.44 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
25633 be/4 mysql       0.00 B/s    3.75 K/s  0.00 %  1.22 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
 8603 be/4 mysql       0.00 B/s    7.50 K/s  0.00 %  0.89 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
11659 be/4 mysql       0.00 B/s  180.11 K/s  0.00 %  0.43 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
22803 be/4 mysql       0.00 B/s   11.26 K/s  0.00 %  0.36 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
 4470 be/4 mysql       0.00 B/s    3.75 K/s  0.00 %  0.03 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
 8601 be/4 mysql       0.00 B/s    3.75 K/s  0.00 %  0.02 % mysqld --basedir=/usr --da~=/var/lib/mysql/mysql.sock
复制代码

发现[jbd2/dm-0-8]这个进程占用IO95%。

二、解决

进入mysql ,查看sync_binlog变量设置

复制代码
[root@hlsms-fensheng-4 ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2118462
Server version: 5.7.22 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like '%sync_binlog%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 1     |
+---------------+-------+
1 row in set (0.00 sec)

mysql>
复制代码

当前值为1,表示每次提交事务后,将binlog_cache中的数据强制写入磁盘。当设置为“1”的时候,是最安全但是性能损耗最大的设置。因为当设置为1的时候,即使系统Crash,也最多丢失binlog_cache中未完成的一个事务

当设置为0时,表示当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘。

在MySQL中系统默认的设置是sync_binlog=0,也就是不做任何强制性的磁盘刷新指令,这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。

sync_binlog=n,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。

所以sync_binlog=1,导致事务写入太频繁,从而出现[jbd2/dm-0-8]这个进程占用IO95%。

因此将sync_log设置为500

复制代码
mysql> set global sync_binlog=500;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%sync_binlog%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 500   |
+---------------+-------+
1 row in set (0.00 sec)

mysql>
复制代码

 三、设置innodb_flush_log_at_trx_commit变量

innodb_flush_log_at_trx_commit是配置MySql日志何时写入硬盘的参数:

0:log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行。该模式下在事务提交的时候,不会主动触发写入磁盘的操作。

1:每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去,该模式为系统默认。

2:每次事务提交时mysql都会把log buffer的数据写入log file,但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作\

一般设置为2

复制代码
mysql> show variables like '%innodb_flush_log_at_trx_commit%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.01 sec)

mysql> set global innodb_flush_log_at_trx_commit=2;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%innodb_flush_log_at_trx_commit%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set (0.01 sec)
复制代码

 四、验证

再次查看iotop

复制代码
Total DISK READ: 0.00 B/s | Total DISK WRITE: 781.51 K/s 
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                        
 1458 be/3 root        0.00 B/s    0.00 B/s  0.00 %  6.97 % [jbd2/dm-2-8]
26496 be/4 mysql       0.00 B/s   14.47 K/s  0.00 %  4.02 % mysqld --basedir=/usr --datadir=~ocket=/home/data/mysql/mysql.sock
26500 be/4 mysql       0.00 B/s  665.73 K/s  0.00 %  2.42 % mysqld --basedir=/usr --datadir=~ocket=/home/data/mysql/mysql.sock
26498 be/4 mysql       0.00 B/s    0.00 B/s  0.00 %  1.52 % mysqld --basedir=/usr --datadir=~ocket=/home/data/mysql/mysql.sock
26505 be/4 mysql       0.00 B/s    0.00 B/s  0.00 %  0.17 % mysqld --basedir=/usr --datadir=~ocket=/home/data/mysql/mysql.sock
26499 be/4 mysql       0.00 B/s    0.00 B/s  0.00 %  0.00 % mysqld --basedir=/usr --datadir=~ocket=/home/data/mysql/mysql.sock
14668 be/4 mysql       0.00 B/s   21.71 K/s  0.00 %  0.00 % mysqld --basedir=/usr --datadir=~ocket=/home/data/mysql/mysql.sock
16970 be/4 mysql       0.00 B/s   18.09 K/s  0.00 %  0.00 % mysqld --basedir=/usr --datadir=~ocket=/home/data/mysql/mysql.sock

nginx做负载均衡,引起写io大的优化

服务器:DELL R710  Xeon E5620 *2/16G/300G SAS*5 raid5
系统:centos5.7 64bit
服务架构:  nginx –> squid —>存储
现在的问题:晚高峰单机流量跑到150Mbit/s 服务器的负载就上到40-50 .
1.负载高的是io引起的,用io软件分析一下,主要是io写操作. 查了一下squid命中率到80% 应该读操作大于写操作才对,百思不解.
用dstat命令分析大部份写操作原来是nginx引起的,nginx只是做转发呀并没有做cache呀,为什么会产生这么大的写io.
网上查了nginx相关资料.如下:
nginx 每次request都要先在proxy本地找一下缓存,没有的时候才去请求真实服务器,其实配置中我并没有设置proxy_stroe之类的参数,因为本身就是要负载I/O ,如果都Cache到proxy上 那就达不到真正的目的了,更何况Cache不太适合大量的不算小的文件。

proxy_buffering

syntax: proxy_buffering on|off
default: proxy_buffering on
context: http, server, location
This directive activate response buffering of the proxied server.
If buffering is activated, then nginx assumes the answer of the proxied server as fast as possible, preserving it in the buffer, assigned by directiveproxy_buffer_size and proxy_buffers.
If the response can not all be placed in memory, then parts of it will be written to disk.
If buffering is switched off, then the response is synchronously transferred to client immediately as it is received.
nginx do not attempt to count entire answer of the proxied server, maximum size of data, which nginx can accept from the server it is assigned by directiveproxy_buffer_size.
For Comet applications based on long-polling it is important to set proxy_buffering to off, otherwise the asynchronous response is buffered and the Comet does not work.
总算发现问题所在了,设置off 后reload一下, 负载从50降到5,这也太夸张了吧,不敢想像。
如果是单纯拿来做负载均衡而不做代理,此项应该是必关的,否则只有无谓的消耗。

Nginx写IO占用高故障处理

问题描述

突然收到一台服务器负载过高告警,网站打开缓慢

问题分析

(1)使用 top 命令看到cpu行的 iowait 达到了70%以上,断定是IO负载过高的原因

(2)使用 iotop -o 命令发现Nginx的写IO特别大,并且在上一步的top命令看到Nginx的进程状态为D,表示Nginx在等待IO已经为僵死状态

这时候可以知道是Nginx产生大量写操作导致的系统负载过高了,但还不能知道具体Nginx在写什么文件

(3)找到其中一个nginx worker进程的pid,使用 lsof -p pid 列出来的文件发现除了一些系统库文件及日志文件,还有相当多的fastcgi_temp/xxx文件,有可能与这些文件有关联

(4)使用 strace -p pid 追踪,发现nginx进程对某个fd进行大量的写操作,与 lsof 命令列出来的文件刚好符合

(5)使用 iostat 1 输出的大量写io的分区与fastcgi_temp所在分区相符合

猜测可能是外部正在上传大量的大文件给php-fpm,于是通过EZHTTP的小工具来查看实时流量,发现入站流量其实不大

解决方案

知道了是 fastcgi_temp io 压力大,目前无法短时间从根本上解决问题,决定先紧急处理一下,把 fastcgi_temp 指向 /dev/shm,也就是映射到了内存,重启nginx之后服务恢复了正常,之后再找开发人员协同查找解决根本问题

关于Nginx均衡磁盘IO极高的问题

http://hi.baidu.com/chancey/blog/item/9b5d480ace7f2c1495ca6bc3.html

关于Nginx均衡磁盘IO的问题解决

2009-12-16 18:54
由于某WEB业务I/O比较高 于是考虑使用nginx来均衡I/O负载
数据在服务器之间使用lsyncd进行实时同步(效果相当不错)

前端使用nginx proxy来做load balance 配置相当简单, 过程具体就不说了

部署完毕后,功能上一切正常,唯独proxy服务器的load average巨高,查看发现Proxy服务器的Write I/O 占总消耗的90%以上。

这里比较纳闷, 因为业务本身很少有写操作,iotop查看消耗全在nginx上,但怎么也想不通什么东西如此消耗I/O,于是打开nginx error log并设置等级为debug。

观察了一段时间,发现每次request都要先在proxy本地找一下缓存,没有的时候才去请求真实服务器,其实配置中我并没有设置proxy_stroe之类的参数,因为本身就是要负载I/O ,如果都Cache到proxy上 那就达不到真正的目的了,更何况Cache不太适合大量的不算小的文件。

看了一下nginx wiki proxy章发现以下选项:

proxy_buffering

syntax: proxy_buffering on|off

default: proxy_buffering on

context: http, server, location

This directive activate response buffering of the proxied server.

If buffering is activated, then nginx assumes the answer of the proxied server as fast as possible, preserving it in the buffer, assigned by directive proxy_buffer_size and proxy_buffers.

If the response can not all be placed in memory, then parts of it will be written to disk.

If buffering is switched off, then the response is synchronously transferred to client immediately as it is received.

nginx do not attempt to count entire answer of the proxied server, maximum size of data, which nginx can accept from the server it is assigned by directive proxy_buffer_size.

For Comet applications based on long-polling it is important to set proxy_buffering to off, otherwise the asynchronous response is buffered and the Comet does not work.

总算发现问题所在了,设置off重启, 一切正常。

这么说来如果是单纯拿来做负载均衡而不做代理,此项应该是必关的,否则只有无谓的消耗。
但我在google上搜索 “proxy_buffering”, 结果只有3000+条, 除了nginx中文wiki之外,其他再无中文介绍,搜索 “nginx load balance” 确有3W+ , 大多数都讲proxy如何配置,千篇一律 。对这样的参数只字未提, 很是费解…..

iftop 用法个人实例 查看指定端口流量

我想要看指定端口的流量,找了好多好多工具,就是没有。某次在用iftop的时候,瞎按到。。发现一个可以将就查看的方法

iftop 进入界面,先按小写的t , p , 来往的数据合并成一行(t),显示来往双方端口号(p)

再让左边的机器名与端口号服务名,,解析一下  按大小写n

屏蔽中间的IP,端口号,这样会让左边的端口号去重。按大小写D

或许,不够好,但有时是可以将就将就的。

如果这么多个端口号,都看不到你想看的那个端口,证明你想看的端口,实在没啥流量(98%的场景应该是这样),那么你搞个抓包的吧。。这样更实际点。