【问题标题】:Consecutive MySQL queries from Go become MUCH slower after some point在某个时间点后,来自 Go 的连续 MySQL 查询变得慢得多
【发布时间】:2015-07-17 20:45:16
【问题描述】:

我正在编写一个遍历一些 MySQL 表的工作,根据一些标准选择一些行,从中提取电子邮件地址并向每个表发送一封电子邮件。

过滤过程查看一个相当大的表(我们称之为storage)(转储约6gb),如下所示:

Columns:
id      varchar(64) PK
path    varchar(64) PK
game    varchar(64)
guid    varchar(64)
value   varchar(512)
timestamp   timestamp

有两个索引:(id, path)(如上所示的 PK)和guid

该作业首先从一个表中检索一长串 guid,然后对它们进行批处理并在 storage 表上执行类似这样的连续查询:

SELECT guid, timestamp FROM storage 
WHERE game = 'somegame' 
AND path = 'path' AND value = 'value' AND timestamp >= '2015-04-22 00:00:00.0' AND timestamp <= '2015-04-29T14:53:07+02:00' 
AND guid IN ( ... )

IN 子句包含一个 guid 列表。

我需要检索时间戳才能进一步过滤。

在我的本地 MySQL 上运行时,一切正常,查询需要大约 180 毫秒,批量 1000 个 guid。

在 Amazon RDS 上针对同一数据库运行时,查询开始很快,但在某个时间点之后,它们突然开始需要大约 30 秒,并继续这样做直到作业结束。

我尝试了很多方法来解决此问题,但无法找出原因。一些注意事项:

  • 作业仅使用一个sql.DB 对象。另外,我准备了一次上述语句并大量重复使用它。
  • 起初,我以为是因为RDS DB运行的是MySQL 5.5,而我运行的是5.6。我制作了 RDS DB 的副本,升级到 5.6,再次运行该作业。问题又出现了。
  • 两个数据库中的数据量相同:我转储生产数据库并将其导入本地数据库并运行作业。相同的行为(它仍然在本地快速运行)。
  • RDS 节点的 AWS 监控未显示任何明显的峰值。 CPU 使用率从 1% 跃升至最高 10%,并且该作业似乎只打开了几个连接 (~4)。
  • 我让一位同事在他们的 PC 上运行该作业,指向 我的 MySQL 数据库,只是为了确保出色的性能并非源于本地连接这一事实。它的运行速度与在我的 PC 上一样快(诚然,通过 LAN)。
  • 从我的本地 PCAmazon EC2 节点 对 RDS 运行了该作业,该节点非常接近 RDS。从EC2开始,它的表现更好,但问题仍然出现。
  • 作业非常并发,每一步都有输入和输出通道(缓冲区大小为1000),工作由goroutines执行。在这两个步骤之间,我还有其他 goroutine 可以批量处理前一个 goroutine 的输出。
  • 速度突然变慢,一个查询需要几毫秒,下一个需要几十秒。

我完全不知道为什么会发生这种情况。任何建议,将不胜感激。

【问题讨论】:

  • 我在这里给出答案,但亚马逊会在您运行一定数量的查询后限制您的带宽。他们实际上是在更慢地运行您的每个查询,还是仅以特定间隔运行它们,这是任何人的猜测。
  • 我实际上可以回答这个问题,我在作业运行时在数据库上运行了 SHOW FULL PROCESSLIST,并且查询实际上花费了更长的时间,它们并没有间隔运行。但是他们怎样才能使查询运行时间更长呢?另外,我在哪里可以看到?是否有关于限制等的文档?
  • 好吧,如果查询与其他任务并行运行,那么它们似乎需要更长的时间。
  • 我什至在我专门为此目的委托的副本上运行了这个,它没有运行其他查询。 :-|
  • 这里只是在黑暗中拍摄...尝试将http://godoc.org/database/sql#DB.SetMaxIdleConns 设置为0。听起来您的联系可能正在停滞不前。最终他们被清理干净,但在此期间一切都在等待。 (github.com/go-sql-driver/mysql/issues/257)

标签: mysql amazon-web-services go amazon-rds


【解决方案1】:

所以,经过大量的实验,我找到了解决方案。

我在所涉及的 RDS 实例上使用磁性存储,可保证大约 100 IOPS。这限制了我们查询数据的速度。

我使用 2000 Provisioned IOPS 进行测试,作业一路跑得很快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    相关资源
    最近更新 更多