国漫手机壁纸

MySQL 性能优化:性能提升 50%,延迟降低 60%

从年初起,我们的高峰吞吐量增加了 50%,所以我们不仅在处理相当大的负载(仍然在我们估计的容量里),同时我们还拥有更好、更可预计的吞吐量。而且,对于每个想睡个安稳觉的人而言的好消息是,与系统性能或通用服务器负载相关的换页事件从三月的 300 降至四月和五月两个月加起来的几个。

NetSmell 出品

当我进入 Pinterest 时,我的头三个星期是在本部度过的,在那里最新工程把解决生产问题的成果应用到了整个软件栈中。在本部,我们通过构建 Pinterest 来学习 Pinterest 是怎样被构建的,并且,仅仅在几天里就提交代码、做出有意义的贡献也不是不常见。在 Pinterest ,新进来的工程师可以灵活地选择参加哪个组,而且作为在本部工作经历的一部分,编写不同部分的代码可以有助于做出这个选择。本部的人通常会做不同的项目,而我的项目则是深入研究 MySQL 的性能优化。

Pinterest, MySQL 和 AWS,我的天!

我们的 MySQL 完全运行在 AWS 中。尽管使用了相当高性能的实例类型(配备 SSD RAID-0 阵列),和相当简单的工作负载(很多基于主键或简单范围的单点查询),峰值大约 2000 QPS,我们还是无法达到期望的 IO 性能水平。

写 IOPS 一旦超过800,就会导致无法接受的延迟和复制滞后。复制滞后或者从库的读性能不足减慢 ETL 和批处理任务,依靠这些批处理任务的任何小组都会受到负面影响。唯一可行的选项是要么选择一个更大的实例,这样会使我们的开销翻倍、消除我们的效率,或者找办法使现存的系统运行地更好。

我从我的同事 Rob Wultsch 那接手了这个项目,他已做出很重要的发现:当在 AWS 的 SSD 上运行时,Linux内核版本非常重要。Ubuntu 12.04 携带的默认 3.2 版本没有减少开销, AWS 推荐的最低 3.8 版本也没有(尽管 3.8 仍比 3.2 快了两倍多)。在一个 i2.2xlarge(双SSD RAID-0 阵列)实例、3.2 内核版本上运行 sysbench 勉强在 16 K 随机写时达到 100 MB/sec。将内核升级至 3.8 会使我们在同样的测试上达到 350 MB/sec,但这比期望值还是差了很多。看到这样一个简单的改变引起这样的提升,为我们揭示了许多新的关于低效和差的配置选项的问题和猜想:我们能否从一个更新的内核上获得更好的性能?我们应该改变 OS 级别的其他设置吗?有没有优化可以在 my.conf 中找到?我们怎样能使 MySQL 运行地更快?

在寻找答案中,我设计了 60 个基本不同的 sysbench 文件 IO 测试配置,配合不同的内核、文件系统、挂载选项和 RAID 块大小。一旦从这些实验中选取了最佳配置,我又运行另外 20 个左右的 sysbench OLTP ,使用其他的系统配置。基本的测试方法在所有的测试中是相同的:运行测试一个小时,每隔 1 秒收集数据,然后考虑缓存热身时间去掉开始的 600 秒的数据,最后处理剩下的数据。识别出最优配置后,我们重新构建了我们最大的、最重要的服务器,把这些改变放进了生产环境。

从 5000 QPS 到 26000 QPS : 扩展 MySQL 性能,无需扩展硬件

让我们看看这些改变对一些基本的 sysbench OLTP 测试的影响,我们在 16 线程、 32 线程和几个不同的配置下衡量 p99 响应时间和吞吐量两个指标来看看效果。

这里是每种数字代表的含义:

  • CURRENT : 3.2 内核和标准的 MySQL 配置
  • STOCK:3.18 内核和标准的 MySQL 配置
  • KERNEL:3.18 内核和少量的 IO/内存 sysctl 微调
  • MySQL:3.18 内核和优化过的 MySQL 配置
  • KERN + MySQL:3.18 内核和 #3、#4 中的微调
  • KERN + JE::3.18内核和 #3 中的微调和 jemalloc
  • MySQL + JE:3.18 内核和 #4 中的 MySQL 配置和 jemalloc
  • ALL:3.18 内核和 #3,#4 和 jemalloc

当我们启用所有的优化后,我们发现在 16 和 32 线程下取得了大概 500% 多的读写吞吐量,同时在读写两个方向上降低了 500 ms 的 p99 延迟。在读方面,我们从大概 4100 – 4600 QPS 达到 22000 – 25000以上,分值取决于并发数。在写方面,我们从大概 1000 QPS 达到 5100 – 6000 QPS。这些是在仅仅通过一些简单改变获得的巨大增长空间和性能提升。

当然,所有这些人工基准测试如果不能转换成实际成果,都是没有意义的。下图展示了从客户端和服务端的角度看,我们主要集群上的延迟,时间跨度为从升级前几天到升级后几天。这个过程花了一个星期才完成。

红线表示客户端感觉到的延迟,绿线表示服务端测到的延迟。从客户端看,p99 延迟从一个波动较大、有时超过 100 ms 的 15 – 35 ms 降至相当平稳的 15 ms、有时会有 80 ms 或更低的异常值。服务端测量的延迟也从波动较大的 5 – 15 ms降至基本平稳的 5 ms,其中每天会有一个由系统维护引起的 18 ms 的尖值。此外,从年初起,我们的高峰吞吐量增加了 50%,所以我们不仅在处理相当大的负载(仍然在我们估计的容量里),同时我们还拥有更好、更可预计的吞吐量。而且,对于每个想睡个安稳觉的人而言的好消息是,与系统性能或通用服务器负载相关的换页事件从三月的 300 降至四月和五月两个月加起来的几个。

显示余下内容
相关文章:
  1. MySQL 8.0 将开始放弃 MyISAM 引擎
  2. 如何提高 Ruby On Rails 性能
  3. 10款最好用的MySQL数据库客户端图形界面管理工具
 

发表回复

您的电子邮箱地址不会被公开。