IO问题成顽疾,鹅厂专家来教你

在日常工作中,有时候会发现 MySQL 的状态不太对劲,这时候就会看看监控指标,可能会发现:写入 QPS 开始出现毛刺,或者 IO 的指标很高。这时候该怎么办呢?本文会从 Linux 层面入手,根据不同的 IO 特点来分析 MySQL 数据库可能遇到的问题,并给出一些可参考的优化/缓解思路。

一、怎么看懂 IO 指标?

检查 IO 的问题会使用iostat这个命令,这里展示一下命令的效果(iostat -x 1 -m,debian 10.2):

need-to-insert-img

iostat

avg-cpu 自然就是 CPU 相关的指标,判断 IO 问题时可以关注 %iowait,其他指标的意义如下:

·r/s 和 w/s:合并过后的读请求和写请求的每秒请求数,可以当做 IOPS 来理解。

·rMB/s 和 wMB/s:磁盘的读写吞吐量。

·rrqm/s 和 wrqm/s:每秒合并的读请求和写请求数量。

·%rrqm 和 %wrqm:合并的读请求和写请求百分比。

·r_await 和 w_await:读请求和写请求的平均响应时间,包含真正的处理时间和队列中的等待时间(ms)。

·aqu-sz:平均队列深度。

·rareq_sz 和 wareq_sz:一个读请求和写请求的平均物理大小(KB)。

·scvtm:计算出来的平均 IO 响应时间,目前已经不准确,不用再关注。

·%util:如果使用了 RAID 或者 SSD,则忽略这个指标,仅在单块机械盘上准确。

一般来说,评价一块 IO 设备(忽略机械盘的情况,没有评价的意义)是否达到了高负载情况,可以看这几个指标:r/s,w/s,rMB/s,wMB/s,r_await,w_await,aqu-sz。

二、MySQL 与 IO

由于 MySQL 涉及到 IO 相关的参数会比较多,因此这里仅一部分经常用到的参数以及在测试&模拟中使用默认设置:

参数

设置

备注

innodb_io_capacity

16000

定义了后台任务可用的 IOPS 量

innodb_io_capacity_max

32000

定义了后台任务可用的最大 IOPS 量

innodb_flush_log_at_trx_commit

1

控制事务的提交策略,具体信息请参考官方文档

sync_binlog

1

控制 binlog 落盘的频率,具体信息请参考官方文档

innodb_io_capacity 和 innodb_io_capacity_max 是最直接限制 IOPS 的指标,大多数时候,SSD 可以设置成 16000 或者更高的数值,如果是云主机或者其他的共享存储设备,则需要了解一下详细的 IOPS 上限再具体调整。trx_commit 和 sync_binlog 这两个参数也放进来的原因是不同的参数组合对 IO 的压力也会有区别。通常的用法是双 1 或者 20(二零),参考官方文档的描述,双 1 在每次提交事务的时候都会刷盘,对 IO 的压力要高不少;20 则是滞后刷盘,对 IO 的压力会较小,因此写入 QPS 会高一些。

另外,可以关注到一个细节,innodb_io_capacity 的描述对象是:后台任务。这代表着 MySQL 后台的 flush,purge 操作会受到这个参数设置的限制。

三、测试环境

本次测试使用腾讯云服务器的高 IO 型 IT3 实例,自带了 3TB 的本地 NVME。由于腾讯云平台限制了系统版本(debian 9),因此 iostat 在输出内容上稍有差异,但是不影响分析,简单用 fio 跑了一下 16k(innodb_page_size 的默认配置) 的 IO 性能:

类型

IOPS

吞吐量(MB)

随机读

121959

1905

随机写

98326

1536

随机读写(读部分)

47129

750

随机读写(写部分)

47152

754

那么,为什么测试环境要用一个完全不会有 IO 瓶颈的呢?这是为了方便展示调整 MySQL 之后的效果。如果整套系统的 IO 设备负载长期处于高水位的话,最佳优化策略是升级 IO 设备,而不是调整 MySQL。因此所有的分析和应对的场景都属于中、短时间内的高 IO 负载。

四、IO 分析

1. 纯写入

先看一种比较纯粹,但是较少出现的 IO 负载场景:

need-to-insert-img

iostat_wo

这种类型的指标有一个明显的特点:IO 负载中没有,或者几乎没有读取相关的压力。这种负载的特征一般是缓存足够放下所有的数据,因此不需要从磁盘上读数据,压力全部在写入上。

首先能想到的,显然是trx_commit 和 sync_binlog 这两个参数,把双 1 改成 20 的配置,产生 QPS 变化的原因也比较好理解:原本一个事务需要刷一次磁盘,变成多个事务刷盘操作合并到了一起,就像是提高了每个 IOPS 的“事务处理效率”,比如从 1 事务/IOPS 变成了 N 事务/IOPS。

除了提高“每个 IOPS 的事务处理效率”以外,其实还会有另外一种思路:适当限制后台任务的 IOPS。实际上 MySQL 的写入会涉及到非常多的 buffer,log,并产生后台任务相关的数据,出现中等时间的高写入场景时,后台任务一般会慢慢堆积需要 flush 和 purge 的数据,如果 innodb_io_capacity 和 innodb_io_capacity_max 的参数设置得比较高,可能会让后台任务消耗过多的 IO 资源,这时候适当调低一些可以在一段时间内稳住写入 QPS,等高写入的压力过去之后再回滚设置。

另外,如果有更加精细化的调整方式,应该会有更好的效果,目前只能靠这个参数一刀切,不过不要改得太低,因为当后台任务堆积的数据过多,触发强制刷脏/checkpoint 等机制时,会大幅度的侵占 IO 资源,导致非常剧烈的写入 QPS 波动,这一点需要注意。

这里给出“反向调整”的效果,日志数据取自于某一个 sysbench 客户端,在 2050s 左右的时候大幅度调高了 io_capacity:

2. 纯读取

另外一种比较纯粹的场景,自然就是纯读取了,例如:

need-to-insert-img

iostat_ro

纯读取的 IO 特征说明缓存不够大,需要从磁盘读取热数据。那么增加内存和调高 innodb_buffer_pool_size,把更多的数据放到内存中就是最好的解决方案。至于需要加多少内存,可以结合实际业务 SQL 的响应时间(做好索引优化之后)和 buffer_pool 的命中率,从经验值来看,命中率(show engine innodb status里面)高于 99.5% 是比较理想的,如果实际 SQL 的响应时间不满足业务的需求,那么就可以根据实际命中率来估算需要的内存大小。

由于从 5.7 开始,MySQL 支持动态调整 innodb_buffer_pool_size 这个参数了,因此变更带来的影响相对小了很多,不过调整还是有代价的,尽量在业务低峰期操作。

3. 读写混合

最常见的肯定是读写混合的场景,比如像这样子的:

need-to-insert-img

iostat_rw

分析起来会相对复杂一点,但是结合纯读取和纯写入的分析之后,可以比较容易想到如下的可能性:

场景一:读写混合的场景。

场景二:纯写入的场景,但是内存放不下所有的数据,需要从磁盘读取之后再修改。

先看比较简单的场景2,本质上还是类似于纯写入场景,但是由于内存不够大,因此在排查 MySQL 的读写 SQL 比例(global status 中的 com_xxx 系列数据)之后,可以参考纯写入这个章节的内容进行分析处理。

虽然场景 1 会复杂一些,但是结合纯写和纯读的内容,分析的思路就有了,比如依次思考如下问题:

业务读写比例大概是多少?

IO 系统的读性能问题比较大还是写性能问题比较大?

如果说:

业务读的比例高(例如 >4:1),IO 系统读的性能问题比较大:那么参考纯读取的内容,调高 buffer_pool_size 。

业务读的比例高(例如 >4:1),IO 系统写的性能问题比较大:那么参考纯写入的内容,调整事务提交策略或者 io_capacity。另外,此类场景可能是因为在大批量变更数据,也可以考虑一下优化这种业务行为。

业务写的比例高(例如<4:1),IO 系统读的性能问题比较大:那么参考纯读取的内容。

业务写的比例高(例如<4:1),IO 系统写的性能问题比较大:那么参考纯写入的内容。

业务的读写比例没有什么明显的特点,IO 系统读写的性能问题都比较严重:考虑以上所有的方法,包括升级硬件。

4.一些tips:

吞吐量,IOPS 和一些分散读写压力的手段

吞吐量和 IOPS ,一般情况下衡量 IO 系统性能最直观的指标,并没有特别的提及,主要原因还是判断起来很简单:如果iostat的指标已经达到或者接近了实际硬件的指标(比如达到了 75%),那么根据业务量增长的情况及早规划硬件升级或者其他的手段来分散读写压力。

常规的手段,可以简单的遵循以下场景来酌情使用:读多写少读写分离,写多读少拆库拆表加缓存。

判断 MySQL IO 情况的指标

如果 MySQL 在 IO 方面出现了阻塞的现象,那么可以观察以下几个指标:

参数名

意义

备注

Innodb_data_pending_fsyncs

当前阻塞的 fsync 操作

一般为 0,比较高的话,看一下 innodb_flush_method 的设置

Innodb_data_pending_reads

当前阻塞的 read 操作

一般为 0,如果指标较高且影响业务的话,参考读压力的应对方式

Innodb_data_pending_writes

当前阻塞的 write 操作

一般为 0,如果指标较高且影响业务的话,参考写压力的应对方式

Innodb_os_log_pending_fsyncs

写 redo log 时,当前阻塞的 fsync 操作

一般为 0,如果大于 0 的话,通常就是 IO 设备的瓶颈,考虑把 redo log 迁移到 SSD 或者做 IO 隔离,独占 IO 设备的性能

Innodb_os_log_pending_writes

写 redo log 时,当前阻塞的 write 操作

一般为 0,如果指标较高且影响业务的话,参考写压力的应对方式

InnoDB 还有很多其他的 read 和 write 的指标,通过show global status like '%innodb%read%'之类的操作都可以看到,但是这类指标一般是累计值,需要对比上一个取值时间的差值才能有比较实际的作用,通常也是用来判断 MySQL 的读写比例用,结合上表的 pending 数据和其他的系统指标来综合判断 IO 系统的负载。这些指标也是建议监控起来的。

五、总结

解决 IO 问题的手段是多样化的:最省事的升级硬件;最快捷的调整 MySQL(本文主要内容);比较常用的架构调整手段(读写分离,拆库拆表);结合实际情况来优化业务的行为(合并单行操作的 DML,拆分单个大量更新数据的 DML 语句等)。

虽然不能对上述手段进行全面的介绍,但是iostat提供的信息在分析 MySQL 瓶颈时还是非常有用的,本文仅从硬件的负载特点出发,简述了调整 MySQL 的一些思路。实际上需要多种手段结合起来才能比较好的应对 IO 方面的问题。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容