RDS Storage Auto Scaling は Write-heavy なデータベースでも使えるか?

Posted on

6 月に RDS Storage Auto Scaling という機能が発表されました。

その名のとおり、ストレージをダウンタイムなしでスケールアウトさせてくれる機能です。具体的には、ストレージの空き容量が 10 % 未満になり、その状態が 5 分以上継続すると、自動的にストレージサイズを 10 % 増やしてくれます。これまでも RDS のストレージはオンラインで拡張できましたが、それを自動的にやってくれるというのが RDS Storage Auto Scaling です。

この RDS Storage Auto Scaling を本番データベースで有効にするかどうか検証したので、その結果をまとめておきます。先に結果を書いておくと、Write-heavy なデータベースで使うのは厳しいと思います。逆に、それ以外では積極的に有効にしておきたいです。

検証環境

ストレージサイズは本番を想定して約 3 TB にしました。また、AZ 間のレイテンシによる影響を排除するため、今回は Single AZ で検証しました。

  • DB エンジン: MySQL 5.7
  • インスタンスタイプ: db.m5.large
  • ストレージタイプ: General Purpose
  • ストレージサイズ: 2800 GiB
  • Multi AZ: No

事前準備

ストレージの最大サイズを指定して RDS Storage Auto Scaling を有効にします。この変更は再起動なしで反映されます。

$ aws rds modify-db-instance --db-instance-identifier testdb --max-allocated-storage 5000

$ aws rds describe-db-instances --db-instance-identifier testdb --query 'DBInstances[].MaxAllocatedStorage'

メンテナンスウィンドウで反映したい場合は --no-apply-immediately オプションを付けることを忘れずに。これを付けないと即座に反映されるため、その時点で空き容量が 10 % を下回っているとストレージの拡張が始まってしまいます。

検証方法

ストレージの空き容量を意図的に減らすため、1000 (10^7) 万行のダミーデータを INSERT します。空き容量が 10 % 程度になるまでひたすらテーブルを作っていきます。

create database test_db;
use test_db;

create table test_table (
  id bigint not null auto_increment,
  dummy varchar(512),
  primary key (id)
);

insert into test_table (dummy) values
  ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
  ('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'),
  ('cccccccccccccccccccccccccccccccc'),
  ('dddddddddddddddddddddddddddddddd'),
  ('eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'),
  ('ffffffffffffffffffffffffffffffff'),
  ('gggggggggggggggggggggggggggggggg'),
  ('hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh'),
  ('iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii'),
  ('jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj')
;

insert into test_table (dummy) (
  select
    concat(t1.dummy, ' ', t2.dummy, ' ', t3.dummy, ' ', t4.dummy, ' ', t5.dummy, ' ', t6.dummy, ' ', t7.dummy)
  from
    test_table t1,
    test_table t2,
    test_table t3,
    test_table t4,
    test_table t5,
    test_table t6,
    test_table t7
);

検証結果

実際に Storage Auto Scaling がトリガーされたときの CloudWatch メトリクスです。空き容量が 10 % を下回ったあたりでストレージが拡張されているのがわかります。

Free storage space

RDS のイベントに記録された時間は次のとおりです。

  • 18:24:30 - Applying autoscale initiated modification to allocated storage
  • 18:27:35 - Finished applying autoscale initiated modification to allocated storage

注目すべきは Write に関するメトリクスです。

Write IOPS

Write latency

Storage Auto Scaling がトリガーされると Write のスパイクが数分間継続します。インスタンスタイプやストレージサイズなど条件を変えながら何度か試してみましたが、この時間は概ね一定で 2 〜 3 分程度です。 RDS のファイルシステムに何が使われているかわかりませんが、おそらく resize2fs のような処理が実行されるときだと思います。

その間はディスク I/O 操作にかかる時間が伸びるため、ピークタイムにトリガーされると事故る可能性があります。 Storage Auto Scaling がトリガーされる条件は「ストレージの空き容量が 10 % 未満の状態が 5 分以上継続する」場合なので、Write-heavy なサービスだとピークタイムにトリガーされる可能性のほうが高いはずです。

この結果を踏まえて、freee の主要プロダクトでは RDS Storage Auto Scaling を有効にするのはやめて、深夜の負荷が低い時間に手動で対応することにしました。

まとめ

AWS に限った話ではありませんが、キャッチーな機能には落とし穴があることが多いので、自分でちゃんと技術検証して判断することが大切ですね。

ちなみに、Write のスパイクについては AWS の SA の方に改善要望を出しました。