キャッシュの抽象化について
コアでは、キャッシュの抽象化は Java メソッドにキャッシングを適用するため、キャッシュで利用可能な情報に基づいて実行回数を減らします。つまり、ターゲットとなるメソッドが呼び出されるたびに、抽象化により、指定された引数に対してメソッドがすでに呼び出されているかどうかをチェックするキャッシュ動作が適用されます。呼び出された場合、実際のメソッドを呼び出さなくても、キャッシュされた結果が返されます。メソッドが呼び出されていない場合は呼び出され、結果がキャッシュされてユーザーに返されるため、次にメソッドが呼び出されたときに、キャッシュされた結果が返されます。このように、特定のパラメーターセットに対して(CPU または IO に制限された)高負荷なメソッドを 1 回だけ呼び出すことができ、その結果は、メソッドを実際に再度呼び出すことなく再利用できます。キャッシングロジックは、呼び出し側への干渉なしに透過的に適用されます。
このアプローチは、呼び出された回数に関係なく、特定の入力(または引数)に対して同じ出力(結果)を返すことが保証されているメソッドに対してのみ機能します。 |
キャッシュの抽象化は、キャッシュのコンテンツを更新したり、1 つまたはすべてのエントリを削除したりする機能など、他のキャッシュ関連の操作を提供します。これらは、アプリケーションの過程で変化する可能性のあるデータをキャッシュが処理する場合に役立ちます。
Spring Framework の他のサービスと同様に、キャッシングサービスは抽象化(キャッシュ実装ではない)であり、キャッシュデータを保存するために実際のストレージを使用する必要があります。つまり、抽象化によりキャッシングロジックを記述する必要がなくなりますが、実際のデータストアを提供します。この抽象化は、org.springframework.cache.Cache
および org.springframework.cache.CacheManager
インターフェースによって実現されます。
Spring は、その抽象化のいくつかの実装を提供します: JDK java.util.concurrent.ConcurrentMap
ベースのキャッシュ、Gemfire キャッシュ、Caffeine [GitHub] (英語) 、JSR-107 準拠のキャッシュ(Ehcache 3.x など)。他のキャッシュストアおよびプロバイダーのプラグインの詳細については、異なるバックエンドキャッシュのプラグインを参照してください。
キャッシュの抽象化には、マルチスレッドおよびマルチプロセス環境に対する特別な処理はありません。そのような機能はキャッシュの実装によって処理されるためです。 |
マルチプロセス環境(つまり、複数のノードにデプロイされたアプリケーション)がある場合、それに応じてキャッシュプロバイダーを構成する必要があります。ユースケースによっては、複数のノード上の同じデータのコピーで十分な場合があります。ただし、アプリケーションの実行中にデータを変更する場合は、他の伝播メカニズムを有効にする必要があります。
特定のアイテムをキャッシュすることは、プログラムによるキャッシュの相互作用で見つかる典型的な get-if-not-found-then-proceed-and-put-evently コードブロックと直接同等です。ロックは適用されず、複数のスレッドが同じアイテムを同時にロードしようとする場合があります。同じことが小作農追い出しにも当てはまります。複数のスレッドが同時にデータを更新または削除しようとしている場合は、古いデータを使用する可能性があります。特定のキャッシュプロバイダーは、その領域で高度な機能を提供します。詳細については、キャッシュプロバイダーのドキュメントを参照してください。
キャッシュの抽象化を使用するには、次の 2 つの側面に注意する必要があります。
キャッシュ宣言: キャッシュする必要のあるメソッドとそのポリシーを特定します。
キャッシュ構成: データが格納され、そこから読み取られるバッキングキャッシュ。