有没有人有一个快速的方法来“预热”从快照创build的RDS实例

我的理解是,一个新的RDS实例将根据需要从快照中“分页”,如此处所述的EC2卷。

这是目前造成我痛苦:我正在一个新的testing实例上运行一个大的查询; 运行需要10-15分钟,但最后一个小时才能运行。 这个实例具有1,000GB的存储容量,所以3000 IOPS,但是在控制台中我看到<100 IOPS(有时甚至小于20读取IOPS)。

通常我会使用mysqldump进行完整的数据库备份并将其发送到/dev/null – 但需要12-18个小时。 我过去曾经在多个表上做过表扫描查询,希望这些IO能够并行发生。

有谁知道更好的方法来预热音量?

不幸的是,强制块被分页的唯一方法是获取它们,并且已经有多种方法来实现这一点。

因为看起来没有比我已经使用的更简单的方法,所以我决定评估这些方法。

对于testing环境,我为每个方法创build了一个实例:r3.large(2个VCPU,15 GB RAM),每个实例使用相同的快照。 这些实例有1000 GB的磁盘,所以应该能够保持3000 IOPS。

整个数据库包含几百个表,从几百行到几百万行(主要用于logging的几个表,但可能涉及一些报告查询)。

我select了两张表格进行评估:我们的“用户”表,其中包含2000万行,过于宽,“联动”表也包含20MM行,但只有两列。

在加载之后,我对用户表运行了两个查询:一个通过合计非索引数字字段来强制进行表扫描,另一个对索引列(应该遍历整个索引)执行聚合操作。 我没有对链接表执行查询,因为它似乎没有提供更多的信息。

所有时间格式为H:MM:SS(小时:分钟:秒),并且来自单次运行。 我还使用Cloudwatch指标(通常平均5-15分钟)跟踪读写IOPS。

我们的数据库使用MySQL,但是我相信一般的方法都适用于任何DBMS。

途径

将表转储到/ dev / null

 mysqldump CONNECTION_OPTIONS --compress DATABASE TABLES > /dev/null 

mysqldump程序用于备份数据库或单个表。 它检索所有的表数据并将其写入StdOut以及DDL以重新创build表及其索引。

由于我不关心实际备份表,所以我将输出redirect到/dev/null 。 由于我不想被networking--compress ,我使用--compress选项。 即便如此,我运行在同一个亚马逊EC2实例上,以保持亚马逊数据中心内的所有networkingstream量。

这种方法的主要缺点是不会碰到索引块。

  Users Linkage --------------------------------------------- | time to touch blocks | 00:53:38 | 00:03:02 | | read IOPS | < 150 | 150+ | | table-scan | 00:01:29 | | | index aggregate | 00:00:15 | | 

强制表扫描查询

与testing查询非常相似,这种方法是从非索引字段中汇总数据的简单select。 我为“触摸”查询select了一个不同的字段,而不是“testing”查询。

与转储操作一样,这只访问表数据块。 我可以通过某种forms的索引聚合来扩展它以访问索引块,但是我认为这与我的需求不太相关。

  Users Linkage --------------------------------------------- | time to touch blocks | 00:59:12 | 00:03:31 | | read IOPS | 150 | 150 | | table-scan | 00:02:04 | | | index aggregate | 00:00:19 | | 

OPTIMIZE

OPTIMIZE TABLE命令将重buildInnoDB表和索引,释放进程中的空间。 这是特定于MySQL,但我会考虑Postgres VACUUM命令是相似的,我敢肯定有其他数据库系统的等效命令。

这对于我们的大桌子来说可能是一个不公平的考验,因为它有很多的更新,毫无疑问在多年的生活中从未被优化。 如果我们定期进行优化,数字可能会更低。

  Users Linkage ---------------------------------------------- | time to touch blocks | 02:01:36 | 00:03:44 | | read IOPS | 100 | 150 | | write IOPS | 500+ | 1000+ | | table-scan | 00:00:05 | | | index aggregate | 00:00:01 | | 

你会注意到我添加了一条写入IOPS的行。 而且,这些查询时间不是印刷错误:它们比其他的要快一个数量级以上。 我怀疑这是因为块被caching在内存中(我可能应该重新触摸块之间的实例和执行查询)。

概要

OPTIMIZE对于大型表格来说要慢得多,并且使用太多的写入IOPS。 但是,如果我在Postgres上,那么VACUUM可能是一个有效的select,假设源数据库是经常清理的。

所有行select和mysqldump之间的区别很小,可能是由于networking或虚拟机负载。 但是, mysqldump执行起来要容易得多,因为全行select需要一些思路来select合适的查询。

运行这些testing后,我创build了一个新的实例,并启动了10个并发的mysqldump会话(随机分配它们之间的表)。 一些观察:

  • 大多数会议在6小时内完成。 有一对跑到7,还有一个(有几张大桌子),大于8。
  • CPU一直保持在40%左右。 我怀疑这完全是由于压缩。
  • 读IOPS缓慢地从〜400增加到〜600(使用15分钟的平均期),并在接近结束时增加到> 1000。

正如我对这个问题进行了更多的思考,我认为我的痛苦主要是因为我正在使用这个实例来testing报告负载。 如果它是一个OLTP实例,我怀疑我可以将它转换成服务,尽量减less痛苦(尽pipe性能较慢)。 但是,同样的痛苦会影响到只读副本,也许更重要的是因为只有在系统负载很重时才会出现另一个副本。

长期以来,我只能希望亚马逊能够看到增加一个“快速初始化”操作,并行触及卷的块。