我正在写一份工作,它通过一些 MySQL 表,根据一些标准选择一些行,从中提取电子邮件地址并向每个人发送电子邮件。过滤过程查看一个storage非常大(大约 6gb 转储)的表(我们称之为),看起来像这样:Columns:id varchar(64) PKpath varchar(64) PKgame 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)。我在本地 PC和Amazon EC2 节点上针对 RDS 运行了该作业,该节点与 RDS 非常接近。从EC2来看,它表现得更好,但问题仍然出现。作业是非常并发的,每一步都有输入和输出通道(缓冲区大小为 1000),工作由 goroutines 执行。在这些步骤之间,我还有其他 goroutine 可以批量处理前一个 goroutine 的输出。减速是突然的,一个查询需要几毫秒,下一个需要几十秒。我不知道为什么会发生这种情况。任何建议,将不胜感激。
1 回答
ITMISS
TA贡献1871条经验 获得超8个赞
所以,经过大量的实验,我找到了解决方案。
我在所涉及的 RDS 实例上使用磁性存储,这保证了大约 100 IOPS。这限制了我们查询数据的速度。
我使用 2000 Provisioned IOPS进行了测试,并且该作业一直运行得很快。
- 1 回答
- 0 关注
- 239 浏览
添加回答
举报
0/150
提交
取消