您好,欢迎访问一九零五行业门户网

SSD 下的 MySQL IO 优化尝试

在阅读这篇文章之前,读者需要注意的是,为了维护隐私,用 mysql 服务器的 d 段代替完整 ip,并且略去一些私密信息。a 项目,因
1、背景
在阅读这篇文章之前,读者需要注意的是,为了维护隐私,用 mysql 服务器的 d 段代替完整 ip,并且略去一些私密信息。
a 项目,因 i/o 出现规律性地剧烈波动。每 15 分钟落地一次,innodbbuffpoolpagesflushed 参数监控波峰和波谷交替出现,磁盘 i/o 同样如此,并且 until 达到 100%。经过排查,排除了触发器、事件、存储过程、前端程序定时器、系统 crontab 的可能性。最终定位为 innodb 日志切换,但是否完全是日志造成的影响,还有待进一步跟踪和分析。
找到问题的可能所在,试图在 24 主库上做了如下调整:
做了如上调整以后,i/o 趋于平稳,没有再出现大的波动。
为了保险起见,a 项目方面决定采用配有 ssd 的机型,对主库进行迁移,同时对 24 的从库 27 进行迁移。待迁移完成后,在新的主库 39 上,针对 ssd 以及 mysql innodb 参数进行优化。待程序切换完成后,再次对针对 ssd 以及 mysql innodb 参数进行优化。也就是说在上线前后进行优化,观察 i/o 状态。
2、ssd 特性众所周知,ssd 的平均性能是优于 sas 的。ssd 能解决 i/o 瓶颈,但互联网行业总要权衡收益与成本的。目前内存数据库是这个领域的一大趋势,一方面,越来越多的应用会往 nosql 迁移。另一方面,重要数据总要落地,传统的机械硬盘已经不能满足目前高并发、大规模数据的要求。总的来说,一方面,为了提高性能,尽可能把数据内存化,这也是 innodb 存储引擎不断改进的核心原则。后续的 mysql 版本已经对 ssd 做了优化。另一方面,尽可能上 ssd。
ssd 这么神秘,接下来我们看看它有哪些特性:
总结起来,也就是随机读性能较连续读性能好,连续写性能较随机写性能好,会有写入放大的问题,同一位置插入次数过多容易导致损坏。
3、基于 ssd 的数据库优化基于 ssd 的数据库优化,我们可以做如下事情:
具体来说,我们可以做如下调整:
针对系统 i/o 调度算法,做如下解释。系统 i/o 调度算法有四种,cfq(complete fairness queueing,完全公平排队 i/o 调度程序)、noop(no operation,电梯式调度程序)、deadline(截止时间调度程序)、as(anticipatory,预料 i/o 调度程序)。
下面对上述几种调度算法做简单地介绍。
cfq 为每个进程/线程,单独创建一个队列来管理该进程所产生的请求,也就是说每个进程一个队列,各队列之间的调度使用时间片来调度,以此来保证每个进程都能被很好的分配到 i/o 带宽,i/o 调度器每次执行一个进程的 4 次请求。
noop 实现了一个简单的 fifo 队列,它像电梯的工作主法一样对 i/o 请求进行组织,当有一个新的请求到来时,它将请求合并到最近的请求之后,以此来保证请求同一介质。
deadline 确保了在一个截止时间内服务请求,这个截止时间是可调整的,而默认读期限短于写期限,这样就防止了写操作因为不能被读取而饿死的现象。
as 本质上与 deadline 一样,但在最后一次读操作后,要等待 6ms,才能继续进行对其它 i/o 请求进行调度。可以从应用程序中预订一个新的读请求,改进读操作的执行,但以一些写操作为代价。它会在每个 6ms 中插入新的 i/o 操作,而会将一些小写入流合并成一个大写入流,用写入延时换取最大的写入吞吐量。
在 ssd 或者 fusion io,最简单的 noop 反而可能是最好的算法,因为其他三个算法的优化是基于缩短寻道时间的,而固态硬盘没有所谓的寻道时间且 i/o 响应时间非常短。
还是用数据说话吧,以下是 ssd 下针对不同 i/o 调度算法所做的 i/o 性能测试,均为 iops。
i/o typenoopanticipatorydeadlinecfq
sequential read222567955224678652
sequential write4090256013701996
sequential rw read63557605671149
sequential rw write63607605651149
random read17905208472093020671
random write7423808681138072
random rw read4994522153165275
random rw write4991522253215278
可以看到,整体来说,noop 算法略胜于其他算法。
接下来讲解需要调整的 innodb 参数的含义:
4、a 项目 mysql 主从关系图a 项目 mysql 主从关系如图一:
图一 a 项目 mysql 主从关系图yzone
5、程序切换之前调优程序切换之前,39 只是 24 的从库,所以 io 压力不高,以下的调整也不能说明根本性的变化。需要说明一点,以下调整的平均间隔在 30 分钟左右。
5.1 修改系统 io 调度算法系统默认的 i/o 调度算法 是 cfq,我们试图先修改之。至于为什么修改,可以查看第3节。
具体的做法如下,需要注意的是,请根据实际情况做调整,比如你的系统中磁盘很可能不是 sda。
如果想永久生效,需要更改 /etc/grub.conf,添加 elevator,示例如下:
此步调整做完以后,查看 39 i/o 状态,并没有显著的变化。
5.2 修改 innodb_io_capacity = 4000在做这个参数调整之前,我们来看看当前 mysql 的配置:
修改方法如下:
网络上的文章,针对 ssd 的优化,mysql 方面需要把 innodb_io_capacity 设置为 4000,或者更高。然而实际上,此业务 update 较多,每次的修改量大概有 20k,并且基本上都是离散写。innodb_io_capacity 达到 4000,ssd 并没有给整个系统带来很大的性能提升。相反,反而使 io 压力过大,until 甚至达到 80% 以上。
5.3 修改 innodb_max_dirty_pages_pct = 25修改方法如下:
修改之后的 mysql 配置:
之前已经将 innodb_max_dirty_pages_pct 设置为 30,此处将 innodb_max_dirty_pages_pct 下调为 25%,,目的为了查看脏数据对 i/o 的影响。修改的结果是,i/o 出现波动,innodbbuffpoolpagesflushed 同样出现波动。然而,由于 39 是 24 的从库,暂时还没有切换,所有压力不够大,脏数据也不够多,所以调整此参数看不出效果。
5.4 修改 innodb_io_capacity = 2000修改方法不赘述。
修改之后的 mysql 配置:
其它类似信息

推荐信息