構成変更や障害対応で、RDSをスナップショットからリストアしたり、マルチAZ化したりすることもあるかもしれません。その際、パフォーマンスが低下することがあります。本記事では、その点について記載致します。
まとめ
RDSをスナップショットからリストアしたり、マルチAZ化してから、全ブロックにIOが発生するまでの間は、IOパフォーマンスが著しく低下する可能性があります。
これは、全てのストレージブロックがリストア時に物理的にロードされるわけではないためです。初回アクセス時には、S3からブロックをロードするというオーバーヘッドが発生する可能性があります。
パフォーマンスが元に戻らなければサービスが再開できないような場合は、テーブル全件走査等でブロックにIOを発生させ、S3からのロードを完了させるという手順を踏む必要があります。
また、本記事で詳細は記載しませんが、リストア後はキャッシュが空白となっているため、データがキャッシュの乗り切るまでパフォーマンスが低下することもあります。
なお、Auroraについては、その他のRDSと根本的にアーキテクチャが異なるものになっているため、本記事で記載しているような問題は発生しません。
RDSのスナップショットリストア
RDSのストレージ領域
まず、RDSは、各インスタンスがそれぞれストレージ領域として独立したEBSを利用する構成となっています(※)。これはマルチAZ構成にした場合のスタンバイ側も同じです。
※Auroraは、データのストレージについてはクラスタ内部のインスタンス間で共有しているため、個別に保有している領域としてはログや一時ファイルに利用する領域のみです。
したがって、RDSのスナップショットを取得する機能は、RDSが利用しているEBSのスナップショットを取得することと意味合い的には同じとなります。
MySQL、MariaDB、PostgreSQL、Oracle、および Microsoft SQL Server 用の Amazon RDS の DB インスタンスは、データベースおよびログのストレージに Amazon Elastic Block Store (Amazon EBS) ボリュームを使用します。
Amazon RDS DB インスタンスストレージ
EBSスナップショットのリストア
「EBSスナップショットのリストア」という文言になると思い当たる方もいらっしゃるかもしれませんが、リストアは全てのストレージブロックをロードするものではありません。実際には、ストレージブロックの初回アクセス時にS3から対象がロードされるような仕組みとなります。
当然、この初回アクセス時には、S3からのロードという比較的コストの高いオーバーヘッドが発生するため、通常のIOよりもパフォーマンスが低下します。
これが、RDSをスナップショットからリストアした際にパフォーマンスが低下する大きな原因の1つです(その他、キャッシュやAZ変更等の要因もあり得ますが)。
スナップショットから作成されたボリュームの場合、アクセスする前に、ストレージブロックが Amazon S3 からプルダウンされてボリュームに書き込こまれる必要があります。この事前処理には一定の時間がかかるため、各ブロックへの初回アクセス時には、I/O 操作のレイテンシーが著しく増加する可能性があります。ボリュームのパフォーマンスは、すべてのブロックがダウンロードされてボリュームに書き込まれると正常値に達します。
Amazon EBS ボリュームの初期化
マルチAZ構成
また、RDSのマルチAZ構成は、プライマリ側のスナップショットを作成し、そのスナップショットを別のAZにリストアすることで実現します。つまり、ここでも「EBSスナップショットのリストア」が発生します。
マルチAZ構成の場合、プライマリとスタンバイのレプリケーションは「同期」方式となるため、スタンバイ側のIOパフォーマンスが低下すると、プライマリ側のパフォーマンスもあわせて低下します。
これが、マルチAZ構成に変更した直後のパフォーマンス低下の大きな原因の1つです(もちろん、AZ間通信等のオーバーヘッドもあるため、一般的にシングルAZ構成よりもパフォーマンスは低下します)。
DB インスタンスでマルチ AZ を有効にするため、RDS はプライマリ DB インスタンスの EBS ボリュームのスナップショットを取得し、新しく作成されたスタンバイレプリカに復元してから、両方のボリュームを同期します。既存の EBS スナップショットを基に作成された新しいボリュームは、バックグラウンドで時間をかけて読み込まれます。この機能を使用すると、スナップショットから大量のボリュームをすばやく復元できますが、変更中および変更完了後にレイテンシーが高くなる可能性があります。
DB インスタンスをマルチ AZ 配置にする
スナップショットリストア後のパフォーマンス改善
通常インスタンス
スナップショットからリストアした通常のインスタンスの場合(マルチAZ構成のスタンバイインスタンスでない場合)、ユーザはデータベースにログインすることが可能です。
したがって、SELECT * FROM {table_name};
等のSQLにより、全件走査を行うことで、ストレージブロックをS3からロードすることができます。
クイックアクセスが必要なテーブルに対する遅延ロードの影響を軽減するには、SELECT * など、テーブル全体をスキャンするようなオペレーションを実行します。これにより、Amazon RDS はバックアップされたテーブルデータをすべて S3 からダウンロードできます。
DB スナップショットからの復元
Oracleの場合は、DBMS_STATS.GATHER_SCHEMA_STATS
やANALYZE(現在は非推奨)
等を利用して統計情報を取得することでIOを発生させることもできます。
※経験則的に、なぜかDBMS_STATS.GATHER_SCHEMA_STATS
だとパフォーマンスが改善しないこともありましたが、効率的なIOのため、全件走査に至らなかったのかもしれません。
PostgreSQLの場合は、VACUUM FREEZE ANALYZE
等でIOを発生させることもできます。
※FREEZE
を付けないと効率的なIOが選択され、全件走査に至らない可能性があります。
スタンバイインスタンス
通常インスタンスと異なりユーザはログインすることができません。したがって、考えられる対応としては次のようなものに限られます。
- フェイルオーバーを伴う再起動を行い、プライマリに昇格させて、全件走査を行う
- プライマリ側でデータを全件削除後、再度挿入を行う
対応自体に手間と時間を要するので、おとなしくパフォーマンスが改善するまで待つ方が現実的かもしれません。
最後に
知っていれば当たり前のことではありますが、スナップショットからのリストアやマルチAZ化は手軽であるがために、リストア後のパフォーマンス低下については考慮されていないケースも見かけます。
経験上、リストア直後の処理に通常の3倍以上の時間を要したこともありますので、リストアやマルチAZ化を行う際は、バッチ処理等の時間が延びることも考えた上で、計画を立てた方が良いかもしれません。
コメント