web-dev-qa-db-ja.com

休止状態の2次キャッシュをいつどのように使用しますか?

休止状態が2次キャッシュにヒットするタイミングと、キャッシュが無効になるタイミングを理解するのが困難です。

これは私が現在理解していることです:

  • セカンドレベルキャッシュはセッション間でエンティティを保存します。スコープはSessionFactoryです
  • キャッシュするエンティティを指定する必要があります。デフォルトではエンティティはキャッシュされません
  • クエリキャッシュは、クエリの結果をキャッシュに保存します。

私が理解できないのは

  • 休止状態はいつこのキャッシュにヒットしますか?
  • クエリキャッシュではなく、セカンドレベルキャッシュを設定したとします。顧客をキャッシュしたいのですが、50000があります。どのような方法でキャッシュから顧客を取得できますか?
  • キャッシュからidで取得できると思います。これは簡単ですが、キャッシュする価値もありません。しかし、すべての顧客と何らかの計算を行いたい場合はどうでしょう。顧客のリストを表示したい場合、どのようにしてそれらにアクセスしますか?
  • クエリキャッシュが無効になっている場合、すべての顧客を獲得するにはどうすればよいですか?
  • 誰かが顧客の1人を更新したらどうなりますか?
    • その顧客はキャッシュで無効化されますか、それともすべての顧客が無効化されますか?

それとも、キャッシュがまったく間違っていると思いますか?その場合、セカンドレベルキャッシュのより適切な使用は何でしょうか?休止状態のドキュメントには、実際にキャッシュがどのように機能するかがまったく明確ではありません。それを設定する方法についての指示のみがあります。

更新:だから、2番目のレベルのキャッシュ(クエリキャッシュなし)がIDによるデータの読み込みに適していることを理解しました。たとえば、Webアプリケーションのすべてのリクエストで権限を確認したいユーザーオブジェクトがあります。これは、ユーザーを2次キャッシュにキャッシュしてデータベースアクセスを削減するのに適したケースでしょうか?セッションまたはどこにでもユーザーIDを保存するように、アクセス許可を確認する必要がある場合は、そのIDによってユーザーを読み込み、アクセス許可を確認します。

83
palto

まず、プロセスレベルキャッシュ(またはHibernateで呼び出す2次キャッシュ)について説明しましょう。動作させるには、次のことを行う必要があります

  1. キャッシュプロバイダーを構成する
  2. キャッシュするエンティティを休止状態に指定します(この種類のマッピングを使用する場合は、hbm.xmlファイルで直接)。

キャッシュプロバイダーに、保存するオブジェクトの数と、それらを無効にするタイミング/理由を伝えます。したがって、DBからそれらを取得するたびに、BookエンティティとAuthorエンティティがあり、キャッシュにないエンティティのみが実際のDBから選択されるとします。これにより、パフォーマンスが大幅に向上します。次の場合に便利です。

  • Hibernate経由でのみデータベースに書き込みます(キャッシュ内のエンティティをいつ変更または無効にするかを知る方法が必要なため)
  • オブジェクトを頻繁に読む
  • 単一のノードがあり、レプリケーションがありません。それ以外の場合は、キャッシュ自体を複製する必要があり(JGroupsなどの分散キャッシュを使用)、より複雑になり、何も共有しないアプリほどスケーリングしません。

キャッシュはいつ機能しますか?

  • session.get()またはsession.load()を選択すると、以前に選択され、キャッシュに存在するオブジェクト。キャッシュは、IDがキーであり、プロパティが値であるストレージです。したがって、IDで検索する可能性がある場合にのみ、DBにアクセスする必要がなくなります。
  • 関連付けが遅延読み込み(または、結合ではなく選択を使用して積極的に読み込まれる)の場合

ただし、次の場合は機能しません。

  • IDで選択しない場合。再び-2次キャッシュはエンティティのIDのマップを他のプロパティに格納します(実際にはオブジェクトではなく、データ自体を格納します)。したがって、ルックアップがfrom Authors where name = :nameの場合、ヒットしませんキャッシュ。
  • HQLを使用する場合(where id = ?を使用する場合でも)。
  • マッピングでfetch="join"を設定した場合、これは、関連付けを読み込むために、個別のselectステートメントの代わりに結合がどこでも使用されることを意味します。プロセスレベルのキャッシュは、fetch="select"が使用されている場合にのみ、子オブジェクトで機能します。
  • fetch="select"があるが、HQLで結合を使用して関連付けを選択する場合でも、それらの結合はすぐに発行され、hbm.xmlまたはアノテーションで指定したものを上書きします。

次に、クエリキャッシュについて説明します。独立したキャッシュではなく、プロセスレベルキャッシュへの追加であることに注意してください。 Countryエンティティがあるとしましょう。静的なので、from Countryと言ったときに同じ結果セットが毎回あることを知っています。これはクエリキャッシュの完璧な候補です。IDsのリストをそれ自体に保存し、次回すべての国を選択すると、このリストをプロセスレベルキャッシュに返し、後者を順番に返します。 、これらのオブジェクトは2次キャッシュに既に格納されているため、各IDのオブジェクトを返します。クエリキャッシュは、エンティティに関連する何かが変更されるたびに無効になります。 from Authorsをクエリキャッシュに配置するように設定したとしましょう。 Authorは頻繁に変更されるため、効果的ではありません。そのため、クエリキャッシュは多少の静的データにのみ使用する必要があります。

93
  • 2次キャッシュはキーと値のストアです。 IDでエンティティを取得する場合にのみ機能します
  • エンティティが休止状態を介して更新/削除されると、2次キャッシュはエンティティごとに無効化/更新されます。データベースが別の方法で更新されても無効になりません。
  • クエリ(顧客リストなど)にはクエリキャッシュを使用します。

実際には、Key-Value分散キャッシュを使用すると便利です。これがmemcachedであり、facebook、Twitterなどを強化します。ただし、IDによるルックアップがない場合は、あまり役に立ちません。

38
Bozho

パーティーに遅れたが、多くの開発者が尋ねるこれらの質問に体系的に答えたいと思った。

ここであなたの質問を一つ一つ取り上げることが私の答えです。

Q.休止状態はいつこのキャッシュにヒットしますか?

A.ファーストレベルキャッシュは、Sessionオブジェクトに関連付けられています。 Second Level Cacheは、Session Factoryオブジェクトに関連付けられています。最初のオブジェクトが見つからない場合、2番目のレベルがチェックされます。

Q. 2次キャッシュを設定したが、クエリキャッシュは設定していないとしましょう。顧客をキャッシュしたいのですが、50000があります。どのような方法でキャッシュから顧客を取得できますか?

A.アップデートで回答がありました。また、クエリキャッシュはオブジェクトのIDのリストのみを保存し、それらのオブジェクトw.r.tのIDはsame2次キャッシュに保存されます。したがって、クエリキャッシュを有効にすると、同じリソースを利用できます。きちんと正しい?

Q.キャッシュからIDで取得できると思います。これは簡単ですが、キャッシュする価値もありません。しかし、すべての顧客と何らかの計算を行いたい場合はどうでしょう。顧客のリストを表示したい場合、どのようにしてそれらにアクセスしますか?

A.上記の回答。

Q.クエリキャッシュが無効になっている場合、すべての顧客を獲得するにはどうすればよいですか?

A.上記の回答。

Q.誰かが顧客の1人を更新したらどうなりますか?その顧客はキャッシュで無効化されますか、それともすべての顧客が無効化されますか?

A. Hibernateにはわかりませんが、他のサードパーティのIMDG /分散キャッシュを使用して hibernate 2次キャッシュ として実装し、無効にすることができます。例えば TayzGrid はそのような製品の1つで、他にもあると思います。

11
Basit Anwer