支持Laravel.io持续发展 →

RDS MySQL 性能调优 - 加快缓慢的插入

2020年6月26日 阅读时间 2 分钟 阅读次数 159

如果你正在运行一个以 MySQL 数据库为主的写操作密集型应用程序,你可能会注意到当服务器上的写负载增加时,性能会大幅度降低。在我们的案例中,我们运行的是一个基于 Laravel 的基于事件源的服务,它将传入的事件写入读取表中。在高负载写入下,简单的插入和更新操作(负载较小)的执行时间达到了 250ms。以下是加快这些慢速写入的方法。

使用高性能 SSD 存储作为服务器支持

MySQL(默认设置)在每次事务后将日志缓冲区写入磁盘。在高负载下,这会导致大量的小写入操作,这些操作在传统的硬盘驱动器上尤其缓慢。

在我们的案例中,我们低估了 Amazon RDS 实例的磁盘大小,这对写性能有直接影响(更高的容量意味着更多的配置 IOPS/写入带宽)。增加磁盘大小将写入的平均时间降低了约 50ms。

TL;DR:确保你服务器的磁盘尽可能快

增加日志文件大小限制

默认的 innodb_log_file_size 限制设置为仅为 128M,这并不适合高插入负载的环境。将其增加到更大的值,如 500M,可以减少日志刷新(日志刷新比较慢,因为你是在写入磁盘)。这对于插入大量数据尤其重要。

在我们的案例中,增加日志文件大小并没有真正帮助到我们,因为我们有大量的较小读取(不足以频繁地溢出日志文件)。

通过较少刷新日志来延迟磁盘写入

默认情况下,MySQL会在每次事务后都将日志写入磁盘。在我们的情况下,我们无法将插入批次包裹在事务中,因此每次插入查询都会导致磁盘写入。

您可以通过将innodb_flush_log_at_trx_commit设置为2,将日志写入磁盘的间隔改为定时。将此设置从默认的1分开的主要问题是可能丢失数据。尽管您仍然受到MySQL崩溃导致数据丢失的保护,但整个服务器失去电力可能会导致潜在的数据丢失。例如,如果您的刷新间隔设置为默认的1,服务器故障可能会导致一秒的写入丢失。

innodb_flush_log_at_trx_commit设置为2,我们能够将插入时间平均从超过200毫秒降低到不到50毫秒。这是一个相当大的改进,但如果您愿意冒更多秒数的潜在数据丢失风险,可以进一步压缩速度。

您可以通过将innodb_flush_log_at_timeout设置为所需的间隔(秒)来增加刷新间隔。在我们的案例中,我们选择了5秒,这导致插入时间平均下降到5毫秒以下!与原始的250毫秒相比,这是一个巨大的差异,并且在我们的情况下,值得冒5秒潜在数据丢失的风险。

最后更新时间:1年前。

driesvints, ssatz, chrisbjr, rufflesaurus, ostap 点赞了这篇文章

5
喜欢这篇文章吗?让作者知道并给他们点赞!

你可能还会喜欢的其他文章

2024年3月11日

如何使用Larastan将您的Laravel应用程序从0到9进行升级

借助Larastan,在您的Laravel应用程序执行之前寻找bug是可能的,因为...

阅读文章
2024年7月19日

无需特性即可规范化API响应

我注意到大多数用于API响应的库都是使用特性实现的,并且...

阅读文章
2024年7月17日

在您的Laravel项目中通过Discord通知收集反馈

如何在Laravel项目中创建反馈模块,并在收到消息时接收到Discord通知...

阅读文章

我们想感谢这些 令人惊叹的公司 对我们的支持

您的标志在这里吗?

Laravel.io

问题解决、知识共享和社区建设的Laravel门户。

© 2024 Laravel.io -版权所有。