Linux性能优化实战 28-29:sql 和 redis 导致磁盘I/O故障的两个例子

例子一、调用查询sql处理时, iowait 超过了 60%

1. top命令查询状态

 发现CPU0的 wa (iowait)很大,但CPU很小,属于异常。

2. iostat 查询磁盘状态

磁盘 sda 每秒的读数据为 32 MB, 而 I/O 使用率高达 97%,这说明磁盘sda遇到了性能瓶颈。

3. pidstat 查询进程状态

找到了磁盘 I/O 瓶颈的根源,即 mysqld 进程

4. 分析:这有可能是个慢查询问题。

    但是慢查询的现象大多是 CPU 使用率高,但这里的CPU并不高,而是IO高。

    那么,有必要分析一下 MySQL 读取的数据。

5. strace 命令查看进程运行堆栈。mysqld 的进程号是 27458

线程 28014 正在读取大量数据,且读取文件的描述符编号为38

6. lsof 命令,看看进程 27458都打开了哪些文件

而根据文件描述符(FD)的编号38,确认打开的文件是  /var/lib/mysql/test/products.MYD

MYD 文件,是 MyISAM 引擎用来存储表数据的文件; 

文件名product是数据表的名字;

而这个文件的父目录test,是数据库的名字。

所以, mysqld 在读取数据库 test 中的 products表。

7. 确认数据库使用的文件路径

上面查出来的路径就是正在使用的路径,没错。

8. 执行mysql的 show processlist 查看mysql正在做什么

可看到 select * from products where productName=‘geektime’ 这条 SQL 语句的执行时间比较长。

9. MySQL 的慢查询问题,很可能是没有利用好索引导致的。 确认这条语句是不是没有利用索引:

    使用explain 命令查看

possible_keys 表示可能选用的索引,这里是 NULL;

key 表示确切会使用的索引,这里也是 NULL;

10. 给 productName 建立索引

11. 确认结果

查询时间已经从 15 秒缩短到了 3 毫秒。

 

例子二、redis响应严重延迟, iowait 超过了 60%

1. top命令查询状态

CPU0 的 iowait 比较高,已经达到了 84%。而CPU使用率都不高,只有8.6%和5%

2. iostat 查询磁盘状态

磁盘 sda 每秒的写数据(wkB/s)为 2.5MB,I/O 使用率(%util)是 0。

虽然有些 I/O 操作,但并没导致磁盘的 I/O 瓶颈。

CPU 和内存使用没问题,I/O 也没有瓶颈,那问题在哪里呢?

思考:该例子只有查询操作,不应该有磁盘写。

虽说 I/O 本身并没有性能瓶颈,但这里的磁盘写也是比较奇怪的。

3. pidstat 查询进程状态

写文件的进程是redis-server

4. strace 命令查看进程运行堆栈

跟磁盘写有关的,就应该是write和fdatasync 这些系统调用

5. lsof 命令,看看进程 9085 都打开了哪些文件

只有 7 号普通文件才会产生磁盘写,而它操作的文件路径是/data/appendonly.aof

相应的系统调用包括 write 和 fdatasync。

6. appendonly.aof 文件对应 Redis 持久化配置中的 appendonly 和 appendfsync 选项

appendfsync 配置的是 always,意味着每次写数据时,都会调用一次 fsync,从而造成比较大的磁盘 I/O 压力。

7. 使用trace查看调用fdatasync的情况,(通过 -e 选项指定 fdatasync)

可以看到,每隔 10ms 左右,就会有一次 fdatasync 调用,并且每次调用本身也要消耗 7~8ms。

这就找出了 Redis 正在进行写入的文件,也知道了产生大量 I/O 的原因。

8. 再来审查一下 strace -f -T -tt -p 9085 的结果

编号为 8 的是 TCP socket,对应的 TCP 读写,是一个标准的“请求 - 响应”格式

从 socket 读取 GET uuid:53522908-… 后,响应 good;

再从 socket 读取 SADD good 535… 后,响应 1。

对 Redis 来说,SADD 是一个写操作,所以 Redis 还会把它保存到用于持久化的 appendonly.aof 文件中。

每当 GET 返回 good 时,随后都会有一个 SADD 操作,这也就导致了,明明是查询接口,Redis 却有大量的磁盘写。

9. 解决办法:

(1) 把 appendfsync 改成 everysec:

(2) 不要执行SAdd,把临时和中间数据放内存。

 

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值