HN 日本語サマリー

← 一覧へ戻る
インフラ・DevOps

Postgresは遅くない、ストレージが遅い

Postgres isn't slow, your storage is (clickhouse.com)

52 pointsby saisrirampur21 コメント

要約

この記事は、PostgreSQLのスケーリングにおけるストレージパフォーマンスの重要性を論じています。ストレージの遅さが、取り込み速度の低下、予測不能なレイテンシ、レプリケーションの遅延など、多くの問題の根本原因となりうることを指摘しています。ローカルNVMeとEBSを比較したベンチマークでは、NVMeがEBSを大幅に上回り、スループットが9倍以上向上し、レイテンシも劇的に改善されました。記事では、NVMeの高速性を活かしつつ、レプリケーションやバックアップで可用性を確保する本番環境での運用パターンも提案しています。

全文翻訳

POSETTE 2026で、Sai Srirampur氏は「Postgres Isn’t Slow. Your Storage Is.」と題した講演を行い、ストレージがPostgreSQLのパフォーマンスにスケーリング時にどのように影響するかを検証しました。この記事では、ベンチマーク、その結果が明らかにしたこと、そして本番環境でローカルNVMe上でPostgreSQLを実行するための提案アーキテクチャを要約します。完全な講演は以下の動画で視聴できます。 講演は、スケーリング時に多くのチームが認識する可能性のある、いくつかの症状から始まります。取り込み速度の低下、P95リードレイテンシの予測不能化、autovacuumの遅延、チェックポイントが実際のワークロードとリソースを競合する、論理レプリケーションが遅延を蓄積するなどです。これらの問題は常に同じ原因を共有しているわけではありませんが、見落としがちな共通の原因、すなわちストレージパフォーマンスを持つことがあります。その理由を理解するために、Sai氏はベースラインのgp3 EBSとローカルNVMe上で、同じ33億行のPostgreSQLワークロードを比較するベンチマークを実行しました。セットアップと、Sai氏が結果分析中に発見したことを説明し、最後にローカルNVMe上でPostgresを本番稼働させるための本番パターンで締めくくります。 5つのスケーリングの症状 PostgreSQLワークロードが数百ギガバイトまたはテラバイトに達し、実際の同時実行性とスループットで実行されるようになると、しばしば現れる5つの一般的な問題があります。 スローな取り込み。最初の問題は、UPDATEとUPSERTに負荷がかかる取り込みパイプラインです。かつて数秒で完了していたジョブが、その下のデータ量が増えるにつれて数分にまで伸びることがあります。 一貫性のないリードレイテンシ。次に現れるのは、ほとんどのクエリは高速なままだが、一部が劇的に遅くなるワークロードです。P95レイテンシがミリ秒から秒に移動し、ダッシュボードがタイムアウトし、不均一な遅延により原因の特定が困難になります。 VACUUMの遅延。3つ目の問題は、UPDATEとUPSERTのスループットが増加するにつれてautovacuumが遅延し、テーブルブロートがギガバイトからテラバイトに蓄積することです。 チェックポイントの遅延。チェックポイントにも時間がかかるようになり、クライアントワークロードとI/OおよびCPUを競合するようになり、かつては目立たなかった操作が定期的なレイテンシスパイクに変わります。 論理レプリケーションの遅延。最後の症状は、PostgreSQLデータがKafkaやClickHouseなどのシステムにストリーミングされる場合に現れます。WALのデコードが遅くなり、レプリケーションスロットの増加が問題を悪化させる可能性があります。 これらの症状はストレージとどのように関連するか PostgreSQLとオペレーティングシステムのページキャッシュで利用可能なメモリを作業セットが超えると、より多くのデータ読み取りには物理I/Oが必要になります。低速なストレージでは、これらの読み取りのコストとキューイングの増加が、平均レイテンシとテールレイテンシの両方を増加させる可能性があります。クライアントクエリとバックグラウンドメンテナンスも同じストレージ予算を使用します。ヒープとインデックスの書き込み、WAL同期、チェックポイント、VACUUM、論理デコードのスピンオフは、帯域幅、IOPS、キュー容量を競合します。ストレージがいずれかの制限に達すると、操作は互いに遅延し始めます。このように、低速なストレージが、一見無関係に見える複数のPostgreSQL問題の根本原因となることがあります。 ローカルNVMeで何が変わるか ローカルNVMeの利点はI/Oを排除することではなく、そのコストを劇的に削減できることです。比較では、ネットワーク接続ストレージでのミリ秒単位の操作と、ローカルNVMeでの数十マイクロ秒で完了する可能性のある操作を対比します。キャッシュミス、WALフラッシュ、メンテナンスI/Oは依然として発生しますが、全体的なシステムへの影響はそれほど大きくありません。 ベンチマーク:ローカルNVMe vs. EBS これがなぜそうなるのかをよりよく理解するために、Sai氏はEBSとローカルNVMeで実行されているPostgreSQL上の同様のワークロードを比較する簡単な実験を設定しました。 セットアップ ストレージを唯一の変数として分離するために、ベンチマークは8つの同一のPostgreSQLクラスタを使用しました。4つはインスタンスストアNVMeを使用し、4つは3,000 IOPSでプロビジョニングされたベースラインgp3 EBSを使用しました。各クラスタは、16 vCPU、64 GiB RAM、16 GiB shared_buffersを備えたm6id.4xlargeインスタンスで実行されました。ベンチマーク実行間のばらつきを正規化するために、各ストレージタイプに複数のインスタンスを使用しました。セットアップは、33億行を含む482 GiBのpgbench_accountsヒープを使用しました。次に、各クラスタは、64クライアントと16ワーカー・スレッドを使用して、5分間、同じ高同時実行ランダムUPDATEワークロードを実行しました。 1\set aid random(1, 3300000000) 2UPDATE pgbench_accounts SET abalance = abalance + 1 WHERE aid = :aid;Copy command 要するに、2つのグループ間の唯一の違いはストレージクラスでした。 ベンチマークが示したこと ベンチマークは、NVMeクラスタで中央値16,030 TPSを生成しました。これはEBS上の1,734 TPSと比較して、このテストでは9.24倍の違いでした。中央値トランザクションレイテンシは36.9 msから4.0 msに低下しました。異なる操作では、NVMeは10 GBのブロートのVACUUMをEBSの964秒に対して366秒で完了し、10 GBの論理レプリケーションバックログを238秒ではなく139秒で解消しました。1つの注意点があります。これらの結果は、このワークロードとこれらのストレージ構成に適用されます。EBS側は3,000 IOPSでプロビジョニングされたベースラインgp3を使用しており、異なるEBSセットアップはおそらく異なる結果をもたらすでしょう。 ギャップの説明 37 msのEBSトランザクションレイテンシの内訳を見ると、スループットのギャップは理解しやすくなります。このベンチマークでは、ページ読み取りはEBSで約19 msを占めましたが、NVMeでは0.3 msでした。コミット時のWAL fsyncは、EBSでさらに11 ms、NVMeで1.5 msを追加し、ロックとスケジューラオーバーヘッドはそれぞれ約5 msと0.2 msに寄与しました。CPU作業自体は、どちらの場合も約2 msで、ほぼ同じでした。つまり、追加のEBSレイテンシのほとんどは、PostgreSQLがより多くのCPU作業を行うことではなく、ストレージの待機から来ていました。 実行中のpg_stat_activityのスナップショットは、別の角度から同じパターンを示しました。64のバックエンドのうち、EBSでは29がIO:DataFileReadを待機していましたが、NVMeでは9でした。これは約45%対14%です。これはポイントインタイムのスナップショットであり、実行全体での平均ではありませんでしたが、その時点でNVMeセッションよりも多くのEBSセッションが読み取りで停止していたことを示しています。 CPUプロファイルは、直感に反する観察結果を追加します。約240秒のプロファイリングウィンドウで、NVMeホストは2,253 CPU秒(約9.4コアがビジー)を蓄積しましたが、EBSホストはわずか251 CPU秒(約1コアがビジー)しか蓄積しませんでした。一部のPostgreSQL関数はEBS上で比例してよりホットに見えましたが、絶対的なCPU時間は、EBSプロセスがストレージを待機してオフCPUでより多くの時間を費やしていたことを示しました。NVMeホストは、CPU容量のより多くを、有用な作業を行うためにビジー状態に保ちました。これがはるかに高いスループットを説明するのに役立ちます。キャッシュミス、WALフラッシュ、メンテナンスI/Oは依然として発生しましたが、それらはより速く完了し、PostgreSQLがストレージでブロックされる時間を短縮しました。 耐久性の問題 パフォーマンス結果の後、講演は明白な反論に移ります。インスタンスストアNVMeはマシンの寿命に結びついているため、ローカルデータはノードと共に消滅します。運用上の問題は、PostgreSQLがNVMeレイテンシと本番グレードの可用性およびリカバリを組み合わせることができるかどうかです。短い答えは「はい」です。耐久性は個々のPostgresノードではなく、クラスタレベルで提供されるためです。 本番環境でのNVMeバックドPostgresの実行 本番環境でローカルNVMe上でPostgreSQLを実行することは、高速だがマシンの寿命に結びついたストレージを中心に設計することを意味します。ノードを失うことは、そのローカルデータコピーを失うことを意味します。インスタンスストアボリュームはEBS APIを通じてスナップショットできません。利用可能な容量は、選択されたインスタンスタイプによって異なります。講演で提示された本番アーキテクチャは、次の3つの主要な要件を通じてこれに対処します。 ノード損失からサービスが生存できるようにデータベースをレプリケートする。 個々のマシン外でバックアップとリカバリデータを維持する。 各インスタンスタイプのNVMeに基づいて容量を計画する。 これらのパターンを組み合わせることで、NVMeバックドPostgreSQLを本番環境で自信を持って実行することが可能になります。 2つのスタンバイによる高可用性 最初のパターンは、2つのスタンバイ候補を持つクォーラムベースの同期レプリケーションです。ANY 1 (standby1, standby2) のような構成では、トランザクションは、WALを耐久的に確認するいずれかのスタンバイを待つのではなく、コミットできます。