Heroku Postgres のデータキャッシングの概要
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2022年12月12日(月)
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 インスタンスなど) を実行しているサーバーでは合計システムメモリの約 25% に設定されます。使用可能なメモリの残りは、データやインデックスをオペレーティングシステムのページキャッシュ経由でディスク上にキャッシュするためと、内部操作またはデータ構造のための 2 つの目的のために Postgres によって使用されます。
最近ディスクとの間で読み書きされたデータは、オペレーティングシステムのページキャッシュを通過するため、メモリ内にキャッシュされています。その間、読み取りはキャッシュから処理されるため、ブロックデバイス I/O 操作が削減され、その結果としてスループットが向上します。ただし、このメモリも使用する Postgres 操作がいくつか存在し、それによりキャッシュが無効になります。
ここで最も注目すべきは、内部のメモリ内クイックソートやハッシュテーブルまたは GROUP BY 操作などの、クエリを満たすために実行される特定の種類の内部操作です。さらに、work_mem
という Postgres 設定によって指定された特定の量のメモリをクエリ内のすべての結合で使用できます。これらの各操作では、通常であればデータやインデックスのキャッシングに使用されるメモリが使用される可能性があります。ただし、これはまた、その処理のために同じ情報をディスクから読み取らなくても済むという意味で、キャッシングの 1 つの形態でもあります。
これ以外にも、autovacuum デーモン (またはユーザー自身) による VACUUM の実行やすべての DDL 操作などの、メモリを必要とする他の操作が存在します。DDL のカテゴリでは、インデックスの作成に触れておく必要があります。これは大量のメモリを消費する傾向があります。したがって、データやインデックスのキャッシュに使用できるメモリも、一時的であっても使い果たします。
Heroku Postgres プランは、主に使用可能なシステム RAM の量によって異なります。ワークロードにとってどのようなプランが最適かを理解するための最善の方法は、実際に試してみることです。詳細は、この記事を参照してください。
コールドキャッシュが存在することの意味
何らかの理由で、本番プランの Heroku Postgres データベースでサービス中断が発生した場合は、データベースがオンラインに戻ったら “コールドキャッシュ” が存在することを示すメッセージを受信する可能性があります。このメッセージが表示されたときは、影響を受けた基礎となるハードウェアが存在し、その結果データベースは、データがキャッシュされていない新しいホストでオンラインに戻ります。
読み取りをフォロワーに定期的に送信している場合は、キャッシュがすでにウォームアップされている可能性があるため、キャッシュを通常のレベルで実行する時間が短縮されます。
フォロワーがある場合は、このメッセージが表示されたときに、データベースが新しいホストで使用可能になるのを待つのではなく、そのフォロワーをプロモートできます。