トラフィックの多いWebサイトがあり、休止状態を使用しています。また、ehcacheを使用して、ページの生成に必要ないくつかのエンティティとクエリをキャッシュします。
問題は「並列キャッシュミス」であり、長い説明は、アプリケーションが起動してキャッシュ領域がコールドになると、サイトが多くのユーザーにヒットされているため、各キャッシュ領域に異なるスレッドが何度も(1回だけではなく)入力されることです。同時に。さらに、一部のキャッシュ領域が無効になると、同じ理由で何度も再入力されます。どうすればこれを回避できますか?
hibernate.cache.provider_classに独自の実装を提供することで、1つのエンティティと1つのクエリキャッシュをBlockingCacheに変換できましたが、BlockingCacheのセマンティクスが機能していないようです。最悪の場合でも、BlockingCacheがデッドロック(ブロック)し、アプリケーションが完全にハングすることがあります。スレッドダンプは、get操作でBlockingCacheのミューテックスで処理がブロックされていることを示しています。
それで、問題は、Hibernateがこの種の使用をサポートしているのかということです。
そうでない場合は、本番環境でこの問題をどのように解決しますか?
編集:hibernate.cache.provider_classは、 SingletonEhCacheProviderからのコピーペーストであり、start()メソッドの最後(136行目以降)にあるカスタムキャッシュプロバイダーを指します。
Ehcache cache = manager.getEhcache("foo");
if (!(cache instanceof BlockingCache)) {
manager.replaceCacheWithDecoratedCache(cache, new BlockingCache(cache));
}
このように初期化すると、他の誰かが「foo」という名前のキャッシュに触れる前に、BlockingCacheで装飾します。「foo」はクエリキャッシュであり、「bar」(同じコードですが省略されています)はpojoのエンティティキャッシュです。
編集2:「機能していないようです」は、最初の問題がまだ存在することを意味します。同時実行性のため、キャッシュ「foo」には同じデータが何度も再入力されています。10スレッドのJMeterでサイトにストレスをかけることで、これを検証します。9つのスレッドは、「foo」からのデータを要求してジョブを終了し(クエリを実行し、データをキャッシュに格納する)、最初のスレッドがキャッシュから直接データを取得するまでブロックされると予想されます。
編集3:この問題の別の説明はで見ることができますhttps://forum.hibernate.org/viewtopic.php?f=1&t=964391&start=0ですが、明確な答えはありません。