メインコンテンツにスキップ

Prisma Postgresでのクエリのキャッシュ

Prisma Postgresは、データベースの負荷を軽減し、クエリのパフォーマンスを向上させるための組み込みクエリキャッシュをサポートしています。すべての読み取りクエリで利用可能なcacheStrategyオプションを使用してキャッシュの動作を設定できます。

この機能はPrisma Accelerateを通じて有効化される内部キャッシュ層によって強化されていますが、独自のデータベースを使用している場合を除き、Accelerateと直接やり取りする必要はありません。

キャッシュ戦略

Prisma Clientのすべての読み取りクエリでは、キャッシュの動作を設定するcacheStrategyパラメータを定義できます。キャッシュ戦略では、キャッシュの2つの主要な特性を定義できます。

  • TTL(Time-to-Live): キャッシュされた応答が「フレッシュ」と見なされる秒数。
  • SWR(Stale-while-Revalidating): 古いキャッシュ応答が許容される一方で、キャッシュがバックグラウンドで更新される秒数。

TTL(Time-to-Live)

TTL(Time-to-Live)は、キャッシュされたデータがどのくらいの期間「フレッシュ」と見なされるかを決定します。ttlを秒単位で指定することで、キャッシュ内のデータが有効である期間を制御できます。読み取りクエリが実行される際、キャッシュされた応答がttlの制限内であれば、Prisma Clientはデータベースにクエリを発行することなくキャッシュからデータを取得します。キャッシュされたデータが利用できないか期限切れの場合、Prisma Clientはデータベースにクエリを発行し、その結果を将来のリクエストのためにキャッシュに保存します。

cacheStrategyttlを使用し、クエリのTTLを秒単位で指定します。

await prisma.user.findMany({
cacheStrategy: {
ttl: 60,
},
});

TTLが60秒と指定されている場合、ほとんどのリクエストはTTL期間全体にわたってキャッシュヒットになります。

TTL

TTLは、頻繁な更新を必要としないデータのデータベース負荷とレイテンシーを削減するのに役立ちます。

TTLを無効化し、キャッシュされたクエリ結果を最新の状態に保つ

アプリケーションがリアルタイムまたはほぼリアルタイムのデータを必要とする場合、キャッシュの無効化は、大きなttl(Time-To-Live)を使用している場合でも、ユーザーが最も最新のデータを確認できるようにします。キャッシュを無効化することで、長時間のキャッシュ期間をバイパスし、必要なときにいつでもライブデータを表示できます。

例えば、ダッシュボードが顧客情報を表示し、顧客の連絡先の詳細が変更された場合、TTL(Time-To-Live)設定により、キャッシュは設定された期間後に自動的に期限切れになります。これにより、システムは次回のアクセス時に更新されたデータのみをリフレッシュし、サポートスタッフが手動でキャッシュをリフレッシュすることなく常に最新の情報を見ることができます。

しかし、TTLが期限切れになる前に即時更新が必要な場合、キャッシュの無効化により、システムはキャッシュから特定のデータを事前にクリアできます。これにより、更新された情報が即座に強制的にリフレッシュされ、サポートスタッフはTTLがトリガーされるのを待つことなく、常に最新の詳細情報を得ることができます。

キャッシュされたクエリ結果を無効化するには、タグを追加し、$accelerate.invalidate APIを使用します。

注記

オンデマンドキャッシュ無効化は、有料プランで利用可能です。詳細については、弊社の料金設定をご覧ください。

以下のクエリを無効化するには、$accelerate.invalidate APIにキャッシュタグを提供する必要があります。

await prisma.user.findMany({
cacheStrategy: {
ttl: 60,
tags: ["findMany_users"],
},
});

// This is how you would invalidate the cached query above.
await prisma.$accelerate.invalidate({
tags: ["findMany_users"],
});

SWR(Stale-While-Revalidate)

SWR(Stale-While-Revalidate)を使用すると、Prisma Postgresがバックグラウンドで最新データを取得している間に、古いキャッシュデータをどのくらいの期間提供できるかを制御できます。読み取りクエリが実行されると、Prisma Postgresはキャッシュされた応答の経過時間をswr期間と比較します。キャッシュデータがswrの制限内であれば、Prisma Postgresは古いデータを提供しつつ、同時にデータベースから最新データをフェッチしてキャッシュを更新します。

cacheStrategyswrを使用し、クエリのSWRを秒単位で指定します。

await prisma.user.findMany({
cacheStrategy: {
swr: 60,
},
});

SWRを60秒と指定すると、キャッシュは各リクエスト後にバックグラウンドでキャッシュが自己更新するまで古いデータを提供します。

SWR

SWRを無効化し、キャッシュされたクエリ結果を最新の状態に保つ

アプリケーションがリアルタイムまたはほぼリアルタイムのデータを必要とする場合、キャッシュの無効化は、大きなswr(Stale-While-Revalidate)を使用している場合でも、ユーザーが最も最新のデータを確認できるようにします。キャッシュを無効化することで、長時間のキャッシュ期間をバイパスし、必要なときにいつでもライブデータを表示できます。

例えば、倉庫内の製品の在庫レベルを表示するダッシュボードを考えてみましょう。SWR(Stale-While-Revalidate)設定を使用すると、ダッシュボードは、わずかに古くても最後に確認された在庫データをすぐに表示できます。その間、新しいデータはバックグラウンドで取得されます。これにより、スタッフは待つことなく最新の情報で作業を続けることができ、再検証が完了するとすぐに在庫レベルが更新されます。

しかし、在庫データが即座に更新される必要がある場合—例えば、製品の在庫が少なく、その数がリアルタイムの精度を必要とする場合—キャッシュの無効化により、システムはキャッシュから特定のデータを事前にクリアできます。これにより、最新の在庫データが即座に強制的にリフレッシュされ、スタッフはSWRが再検証を完了するのを待つことなく、常に最新の情報を得ることができます。

キャッシュされたクエリ結果を無効化するには、タグを追加し、$accelerate.invalidate APIを使用します。

注記

オンデマンドキャッシュ無効化は、有料プランで利用可能です。詳細については、弊社の料金設定をご覧ください。

以下のクエリを無効化するには、$accelerate.invalidate APIにキャッシュタグを提供する必要があります。

await prisma.user.findMany({
cacheStrategy: {
swr: 60,
tags: ["findMany_users"],
},
});

// This is how you would invalidate the cached query above.
await prisma.$accelerate.invalidate({
tags: ["findMany_users"],
});

キャッシュ戦略の選択

キャッシングは、クエリ応答時間を改善し、データベース負荷を軽減するのに役立ちます。ただし、古いデータをクライアントに提供する可能性も意味します。古いデータを提供することが許容されるかどうか、そしてどの程度許容されるかは、ユースケースによります。ttlswrは、キャッシュの動作を微調整するために使用できるパラメータです。

TTLを使用したキャッシュ戦略

古いキャッシュデータが許容できる場合に、データベース負荷を軽減するためにTTLを使用します。

ユースケース:eコマースアプリケーションの製品カタログ

頻繁に変わらない製品カタログを持つeコマースアプリケーションを考えてみましょう。例えば、ttlを1時間に設定することで、Prisma Clientはその1時間内の後続のユーザーリクエストに対して、データベースにアクセスすることなくキャッシュされた製品データを提供できます。これにより、データベース負荷が大幅に軽減され、製品リストページの応答時間が向上します。

無効化のタイミング: カタログに重要な更新があった場合、例えば大幅な価格変更や製品の在庫調整があった場合は、顧客に古い情報が表示されるのを防ぐためにキャッシュを直ちに無効化する必要があります。

SWRを使用したキャッシュ戦略

最小限の古いデータでリクエストに素早く応答するためにSWRを使用します。データベース負荷を軽減するわけではありませんが、応答時間を大幅に改善できます。

ユースケース:ソーシャルメディアプラットフォームのユーザープロフィール

ユーザープロフィールが頻繁にアクセスされるソーシャルメディアプラットフォームを想像してみてください。swrを5分などの期間で活用することで、Prisma Postgresはキャッシュされたユーザープロフィール情報を素早く提供し、プロフィールページのレイテンシーを低減できます。その間、バックグラウンドでは各リクエスト後にキャッシュを更新し、プロフィールに行われた更新が後のリクエストに最終的に反映されるようにします。

無効化のタイミング: ユーザーがプロフィール写真や自己紹介文を変更するなど、プロフィールに重要な更新を行った場合、フォロワーがSWRの更新を待つことなく最新の更新を確認できるように、キャッシュを直ちに無効化する必要があります。

TTL + SWRを使用したキャッシュ戦略

非常に高速な応答時間とデータベース負荷の軽減のために、TTLとSWRの両方を使用します。この戦略を使用して、アプリケーションの古いデータに対する許容度を微調整できます。

cacheStrategyttlswrを使用し、クエリのTTLとSWRを秒単位で指定します。

await prisma.user.findMany({
cacheStrategy: {
ttl: 30,
swr: 60,
},
});

TTLを30秒、SWRを60秒と指定すると、キャッシュは最初の30秒間は新しいデータを提供します。その後、キャッシュは各リクエスト後にバックグラウンドで自己更新するまで、古いデータを提供し続けます。

ttl_and_swr.png

ユースケース:ニュース記事

記事が頻繁にアクセスされるがリアルタイムの更新を必要としないニュースアプリケーションを考えてみましょう。ttlを2時間、swr期間を5分に設定することで、Prisma Clientはキャッシュされた記事を素早く提供し、読者のレイテンシーを軽減できます。記事がttlの範囲内であれば、ユーザーは高速な応答を得られます。ttlの期限が切れた後も、Prisma Clientはさらに最大5分間古い記事を提供し続け、新しいクエリに応答してデータベースから最新のニュースでキャッシュを再検証します。これにより、パフォーマンスと鮮度のバランスを保つことができます。

無効化のタイミング: 重要な更新や速報記事が公開された場合、読者が遅延なく最新情報を確認できるように、キャッシュを直ちに無効化する必要があります。このアプローチは、特定のニュース項目が適時性のために通常のキャッシュサイクルを上書きする必要があるアプリケーションに特に役立ちます。

オンデマンドキャッシュ無効化

アプリケーションがリアルタイムまたはほぼリアルタイムのデータを必要とする場合、キャッシュの無効化は、大きなttl(Time-To-Live)またはswr(Stale-While-Revalidate)のキャッシュ戦略を使用している場合でも、ユーザーが最も最新のデータを確認できるようにします。キャッシュを無効化することで、長時間のキャッシュ期間をバイパスし、必要なときにいつでもライブデータを表示できます。

$accelerate.invalidate APIを使用してキャッシュを無効化できます。

注記

キャッシュされたクエリをプログラムで無効化するには、有料プランが必要です。詳細は料金設定をご覧ください。

await prisma.user.findMany({
where: {
email: {
contains: "alice@prisma.io",
},
},
cacheStrategy: {
swr: 60,
ttl: 60,
tags: ["emails_with_alice"],
},
});

$accelerate.invalidate APIにはキャッシュタグを指定する必要があります。

try {
await prisma.$accelerate.invalidate({
tags: ["emails_with_alice"],
});
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
// The .code property can be accessed in a type-safe manner
if (e.code === "P6003") {
console.log(
"The cache invalidation rate limit has been reached. Please try again later."
);
}
}
throw e;
}

デモアプリを探索して、Prisma Postgresでのキャッシュされたクエリ結果がオンデマンドでどのように無効化されるかを明確なタイムラインで確認してください。

デフォルトのキャッシュ戦略

予期せぬ問題を避けるため、Prisma Postgresはデフォルトでキャッシュなしになっています。キャッシュはパフォーマンスを向上させることができますが、誤った使用はエラーにつながる可能性があります。

例えば、重要なパスでキャッシュ戦略を指定せずにクエリが実行された場合、結果が不正になることがあり、明確な説明がありません。この問題は、意図せずに暗黙的なキャッシュが有効のままになっている場合にしばしば発生します。

このような問題を避けるためには、明示的にキャッシュをオプトインする必要があります。これにより、キャッシュがデフォルトで有効になっていないことを認識し、潜在的なエラーを防ぐことができます。

注記

キャッシュ戦略が指定されていない場合やキャッシュミスの場合、キャッシュ層はすべてのクエリをデータベースリージョンに近い接続プールインスタンスを通じてデータベースにルーティングします。

© . All rights reserved.