Heroku Postgres のデータキャッシングの概要
最終更新日 2024年04月01日(月)
Table of Contents
Postgres のデータキャッシングは、事前に割り当てられたり保証されたりしません。むしろ、これは見積に過ぎず、ワークロードに応じて大きく異なります。Heroku Postgres プランには、特定の量のシステム RAM が含まれています。その多くはキャッシングに使用されますが、ユーザーが確認できるデータベースでのキャッシングもそれとあまり変わりません。適切に設計されたアプリケーションは、キャッシュからのクエリの 99% 以上を処理します。この記事では、Postgres でキャッシングする方法の概要を示します。
PostgreSQL でのデータキャッシングの方法
Postgres には、キャッシングのメモリ割り当てに直接影響する設定がいくつかありますが、Postgres が使用するほとんどのキャッシュは、基礎となるオペレーティングシステムによって提供されます。Postgres は、他のほとんどのデータベースシステムとは異なり、多くの操作のためにオペレーティングシステムのページキャッシュを積極的に使用します。
例として、サーバーを合計 7.5 GB のシステムメモリでプロビジョニングするとします。この 7.5 GB のうち、ごく一部がオペレーティングシステムのカーネルによって使用され、さらに少量のシステムメモリが Postgres などの他のプログラムに使用されます。残り (システムメモリの 80 ~ 95%) は、オペレーティングシステムによるデータのキャッシングに使用されます。
Heroku Postgres インスタンスのオペレーティングシステムと他の実行中のプログラムのメモリフットプリントは平均 500 MB であることがわかりました。コストはプランのサイズに関係なくほぼ固定されています。Postgres がこの大量のメモリを割り当てる方法はいくつかありますが、通常、メモリの大部分は管理がオペレーティングシステムに任されています。
共有バッファキャッシュ
Postgres は、自身が割り当て、データやインデックスをメモリ内に保持するために内部的に使用する “共有バッファキャッシュ” を管理しています。この割り当ては、専用の Postgres インスタンス (すべての Heroku Postgres インスタンスなど) を実行しているサーバーの合計システムメモリの約 15 ~ 25% になるように設定されています。残りの使用可能なメモリは、Postgres によって 2 つの目的 (データやインデックスをオペレーティングシステムのページキャッシュを使用してディスク上にキャッシュするためと、内部操作やデータ構造のため) に使用されます。
共有バッファキャッシュの割り当ては、データベースプランによって異なります。
プラン | 割り当て |
---|---|
Standard-0 Premium-0 Private-0 Shield-0 | 1 GB |
standard-2 premium-2 private-2 shield-2 | 2 GB |
standard-3 premium-3 private-3 shield-3 | 4 GB |
standard-4 premium-4 private-4 shield-4 | 8 GB |
standard-5 premium-5 private-5 shield-5 | 9 GB |
standard-6 premium-6 private-6 shield-6 | 19 GB |
premium-l-6 private-l-6 shield-l-6 | 19 GB |
premium-xl-6 private-xl-6 shield-xl-6 | 19 GB |
standard-7 premium-7 private-7 shield-7 | 39 GB |
standard-8 premium-8 private-8 shield-8 | 78 GB |
standard-9 premium-9 private-9 shield-9 | 117 GB |
premium-l-9 private-l-9 shield-l-9 | 117 GB |
premium-xl-9 private-xl-9 shield-xl-9 | 117 GB |
standard-10 premium-10 private-10 shield-10 | 157 GB |
データベースの shared_buffers
値を確認するには、pg:psql
セッションを開いて次を実行します。
SHOW shared_buffers;
インメモリキャッシュ
最近ディスクとの間で読み書きされたデータは、オペレーティングシステムのページキャッシュを通過するため、メモリ内にキャッシュされています。その間、読み取りはキャッシュから処理されるため、ブロックデバイス I/O 操作が削減され、その結果としてスループットが向上します。ただし、このメモリも使用する Postgres 操作がいくつかあり、キャッシュが無効になります。
最も注目すべきは、内部のメモリ内クイックソートやハッシュテーブル、GROUP BY 操作など、クエリを実行するために行われる特定の種類の内部操作です。
work_mem
work_mem
という Postgres 設定によって指定された特定の量のメモリをクエリ内のすべての結合で使用できます。PostgreSQL の work_mem
設定は、一時ディスクファイルに書き込む前に、ソートテーブルやハッシュテーブルなどのクエリ操作で使用される基本の最大メモリ量を設定します。
これらの各操作では、通常であればデータやインデックスのキャッシングに使用されるメモリが使用される可能性があります。ただし、これらの操作は、その処理のために同じ情報をディスクから読み取らなくても済むという意味で、キャッシングの 1 つの形態でもあります。
work_mem
のデフォルト設定はデータベースプランによって異なります。
プラン | デフォルト設定 |
---|---|
Standard-0 Premium-0 Private-0 Shield-0 | 8 MB |
standard-2 premium-2 private-2 shield-2 | 8 MB |
standard-3 premium-3 private-3 shield-3 | 8 MB |
standard-4 premium-4 private-4 shield-4 | 16 MB |
standard-5 premium-5 private-5 shield-5 | 32 MB |
standard-6 premium-6 private-6 shield-6 | 64 MB |
premium-l-6 private-l-6 shield-l-6 | 64 MB |
premium-xl-6 private-xl-6 shield-xl-6 | 64 MB |
standard-7 premium-7 private-7 shield-7 | 128 MB |
standard-8 premium-8 private-8 shield-8 | 256 MB |
standard-9 premium-9 private-9 shield-9 | 256 MB |
premium-l-9 private-l-9 shield-l-9 | 256 MB |
premium-xl-9 private-xl-9 shield-xl-9 | 256 MB |
standard-10 premium-10 private-10 shield-10 | 256 MB |
データベースの work_mem
値を確認するには、pg:psql
セッションを開いて次を実行します。
SHOW work_mem;
カスタムの work_mem
値は次のように設定できます。
- 取引ごと:
SET LOCAL work_mem = '100 MB';
- セッションごと:
SET work_mem = '100 MB';
- ロールごと:
ALTER ROLE username SET work_mem = '100 MB';
- データベースレベル:
ALTER DATABASE database_name SET work_mem = '100 MB';
work_mem
設定をロールごとまたはデータベースレベルで変更すると、変更は新しい接続にのみ適用されます。
VACUUM と DDL
すべての DDL 操作と同様に、ユーザー自身による VACUUM
の実行や autovacuum デーモンの使用など、メモリを必要とする他の操作があります。DDL の場合、インデックスの作成には大量のメモリが消費される傾向があり、データとインデックスのキャッシュに使用可能なメモリも一時的に消費されます。
Heroku Postgres プランは、主に使用可能なシステム RAM の量によって異なります。ワークロードにとってどのようなプランが最適かを理解するための最善の方法は、実際に試してみることです。
コールドキャッシュが存在することの意味
何らかの理由で、本番プランの Heroku Postgres データベースでサービスの中断が発生した場合、データベースがオンラインに戻ったときに “コールドキャッシュ” があるというメッセージを受け取ることがあります。このメッセージが表示された場合は、基礎となるハードウェアが影響を受けており、その結果、データベースはデータがキャッシュされていない新しいホストでオンラインに戻ります。新しい Postgres インスタンスでのコールドキャッシュの問題を軽減するには、このナレッジベースの記事を参照してください。
読み取りをフォロワーに定期的に送信している場合は、キャッシュがすでにウォームアップされているため、キャッシュを通常のレベルで実行する時間が短縮されます。
フォロワーがある場合は、このメッセージが表示されたときに、データベースが新しいホストで使用可能になるのを待つのではなく、そのフォロワーをプロモートできます。