Amazon RDS for PostgreSQL インスタンスをバージョン 11 以上にアップグレードした後、書き込みレイテンシーのスパイクが 5 分ごとに表示されるのはなぜですか?
最終更新日: 2021 年 9 月 23 日
PostgreSQL を実行している Amazon Relational Database Service (Amazon RDS) インスタンスをバージョン 11 以上にアップグレードしました。Amazon CloudWatch で書き込みレイテンシーのスパイクが 5 分ごとに表示されるのはなぜですか?
解決方法
PostgreSQL インスタンスの Amazon Relational Database Service (Amazon RDS) がアイドル状態の場合、Amazon CloudWatch メトリクスの書き込みレイテンシーが 5 分ごとにスパイクすることがあります。このスパイクは、PostgreSQL バージョン 11 以上にアップグレードした後、拡張モニタリングメトリクスの書き込み合計が約 64 MB にスパイクすることと相関しています。wal_segment_size パラメータの値は、アップグレード後に 64 MB になります。これらのスパイクは、wal_segment_size の値が 16 MB であるため、バージョン 10 以前では目立たない場合があります。詳細については、2018 年 9 月 7 日に更新された Amazon RDS - ドキュメントの履歴を参照してください。
RDS for PostgreSQL のarchive_timeout は 5 分に設定されています。この設定は、アーカイブプロセスが 5 分ごとに Amazon Simple Storage Service (Amazon S3) にアーカイブされる先行書き込みログ (WAL) のセグメントをコピーすることを意味します。アイドル状態のシステムでは、通常、このコピープロセスが唯一の I/O オペレーションであるため、CloudWatch グラフではこのオペレーションが目に見えて優勢になる可能性があります。ただし、ビジー状態のシステムではこのパターンが表示されない場合があります。たとえば、db.t3.small インスタンスで次のワークロードを 30 分間実行して、20 GB の Amazon Elastic Block Store (Amazon EBS) ボリュームを持つ RDS for PostgreSQL インスタンスでビジー状態のシステムをシミュレートするとします。
#pgbench --host=$HOST --username=$USER --port=$PORT --protocol=simple --progress=2 --client=1 --jobs=1 $DB -T 1800
#pgbench --initialize --fillfactor=90 --scale=100 --port=$PORT --host=$HOST --username=$USER $DB
このワークロードでは、CloudWatch 書き込みレイテンシーのメトリクスにスパイクは発生しません。
しかし、以下のようなユースケースがあるとします。
- 完了するのに 10 ミリ秒かかる I/O リクエストと、完了までにそれぞれ 1 ミリ秒かかる 9 つの I/O リクエストがあります。これらのリクエストの平均レイテンシーは、以下のように計算されます。
平均レイテンシー = (10 + (9 * 1)) / 10 = 1.9 ミリ秒 - 完了までに 10 ミリ秒かかる I/O リクエストがあり、他の I/O リクエストはありません。この場合の平均レイテンシーは、以下のように計算されます。
平均レイテンシー = 10 / 1 = 10 ミリ秒
どちらのユースケースにも、完了までに 10 ミリ秒かかる同じ I/O リクエストが含まれています。ただし、平均レイテンシーを計算すると、低速リクエストとともに実行される I/O リクエストが少ない 2 番目のユースケースでは、低速リクエストが際立っています。ブロックサイズが大きいためにアイドル状態のシステムに 1 つの低速 I/O リクエストがある場合、レイテンシーはこのリクエストからのみ計算されます。複数の I/O リクエストがあり、そのほとんどが小さいブロックサイズで構成されているビジー状態のシステムでは、平均レイテンシーはこれらすべてのリクエストから計算されます。
このような場合、アイドル状態の RDS for PostgreSQL システムで 5 分ごとに書き込みレイテンシーのスパイクが発生することがあります。データベースインスタンスがビジーなワークロードを実行している場合、これらのスパイクは表示されない可能性があります。
例: 2 つの t2.small Amazon Elastic Compute Cloud (Amazon EC2) インスタンスがあり、それぞれに 8 つの gp2 ボリュームがあるとします。
crontab で以下のコマンドを実行し、最初の Amazon EC2 インスタンスで、5 分ごとにブロックサイズが 64 MB の 64 MB ファイルを作成します。
*/5 * * * * dd if=/dev/zero of=/tmp/big_file.txt bs=64MB count=1 oflag=dsync ; rm -rf /tmp/big_file.txt
注: コマンドの big_file.txt をファイル名に置き換えてください。
また、crontab で次のコマンドを実行して、2 番目の Amazon EC2 インスタンスで 1 分ごとに 8 KB のブロックサイズを持つ 100 個のファイルを作成します。
* * * * * for i in {1..100} ; do dd if=/dev/zero of=/tmp/small_file.txt bs=8k count=100 oflag=dsync ; rm -rf /tmp/small_file.txt ; done
注: コマンドの small_file.txt をファイル名に置き換えてください。
2 つ目の EC2 インスタンスでは、最初の EC2 インスタンスよりも CloudWatch の書き込みレイテンシーのスパイクが高いことがわかります。