web-dev-qa-db-ja.com

Grailsアプリで2次キャッシュを休止状態にする

パートI

Grailsアプリでは、追加することでドメインクラスごとに第2レベルのキャッシュを有効にすることを理解しています

_static mapping {
  cache true
}
_

デフォルトでは、第2レベルのキャッシュはget()が呼び出された場合にのみ使用されますが、クエリに_cache true_を追加することで、条件クエリや動的ファインダーにも使用できます。

ただし、クエリキャッシュがどのように機能するかはまだわかりません。私の最善の推測はそれです:

  • ドメインクラスごとに個別のクエリキャッシュがあります。 1つは本用、もう1つは著者用です。
  • Author.findByName('bob', [cache: true])のようなクエリが実行される前に、ドメインクラス(作成者)、クエリ(findByName)、およびクエリパラメータ( 'bob')に基づいてキャッシュキーが計算されます。そのキーが作成者クエリキャッシュで見つかった場合、クエリを実行する代わりに、キャッシュされた結果が返されます
  • 作成者が保存、削除、または更新されるたびに、作成者のクエリキャッシュがフラッシュされます

これは、Bookインスタンスを返すクエリがAuthorテーブルに結合する可能性があると考えるまでは合理的と思われます。その場合、作成者が保存、削除、または更新されるときに、BookとAuthorの両方のクエリキャッシュをフラッシュする必要があります。これにより、クエリキャッシュが1つだけで、キャッシュされたドメインクラスが保存されるたびにクリアされるのではないかと思われます。

パートII

Grailsのドキュメントでは、次のように述べています

Hibernateの第2レベルのキャッシュを使用してインスタンスをキャッシュする機能に加えて、オブジェクトのコレクション(関連付け)をキャッシュすることもできます。

例えば:

_class Author {    

  static hasMany = [books: Book]

  static mapping = { 
    cache true        // Author uses the 2nd level cache
    books cache: true // associated books use the 2nd level cache
  } 
}

class Book {
  static belongsTo = [author: Author]

  static mapping = {
    cache true // Book uses the 2nd level cache
  }
}
_

上記の構成は理にかなっていますか?つまり、著者と本自体が第2レベルのキャッシュを使用している場合、著者と本の関連付けにも第2レベルのキャッシュを使用させることにメリットはありますか?

パートIII

最後に、第2レベルのクエリキャッシュの使用について このアドバイス を読みました。これは、ドメインクラスの変更頻度が低い場合にのみ使用する必要があることを示しています。 get()操作に対して第2レベルのキャッシュを有効にすべきではない状況、つまり、ドメインクラスに以下を追加しない理由はありますか?

_static mapping = {
  cache true // Book uses the 2nd level cache
}
_
39
Dónal

パート1:

Hibernateは正しいことをします。クエリキャッシュはエンティティごとではありません。クエリに特定の領域を設定しない限り、すべてのクエリで共有される単一のクエリキャッシュ領域があります。テーブルが更新されるたびに、タイムスタンプキャッシュ内のそのタイムスタンプが更新されます。クエリが実行されるたびに、クエリが検索する各テーブルのタイムスタンプが、キャッシュされた結果のタイムスタンプと比較されます。そしてもちろん、キャッシュされた結果は、そのタイムスタンプがすべてのテーブルのタイムスタンプよりも新しい場合にのみ返されます。

パート2:

はい、それは理にかなっています。著者のキャッシュは、ID456の著者の名前が「foo」で生年月日が1975/07/19であることを覚えています。著者テーブルに保存されているデータのみが記憶されます。したがって、関連付けをキャッシュすることも役立ちます。author.getBooks()を呼び出すときに著者の本のセットを取得するために追加のクエリを作成する代わりに、Hibernateはそのキャッシュから著者の本のIDを取得します。次に、各ブックを第2レベルのキャッシュからロードします。ただし、必ずブックをキャッシュしてください。

パート3:

私はいくつかの理由を想像することができます:

  • 非常に多くのエンティティがあり、それらは非常に変化しているため、キャッシュヒットの数は非常に少なく、第2レベルのキャッシュ処理は実際にはキャッシュのないソリューションよりも多くの時間とメモリを消費します
  • アプリケーションがクラスター化されており、分散型の第2レベルのキャッシュのコストと複雑さが高すぎて、ゲインが低くなっています。
  • 他の非休止状態のアプリケーションは同じデータベースに書き込むため、キャッシュには古いデータが返されるリスクが高く、これは受け入れられません。
  • 第2レベルのキャッシュがなくてもすべてがうまくいき、アプリケーションをそれ以上に複雑にする理由はありません。
45
JB Nizet