RDS Storage Auto Scaling は Write-heavy なデータベースでも使えるか?
Posted on
- #aws
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 % を下回ったあたりでストレージが拡張されているのがわかります。
RDS のイベントに記録された時間は次のとおりです。
- 18:24:30 - Applying autoscale initiated modification to allocated storage
- 18:27:35 - Finished applying autoscale initiated modification to allocated storage
注目すべきは Write に関するメトリクスです。
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 の方に改善要望を出しました。