Hibernateのキャッシュについて考えてみる

Hibernate では2次キャッシュ(query cache と collection cache 含む)を提供していますが、キャッシュプロバイダ実装の選定とか、実案件への適用ポリシー等についてはユーザーにお任せですよね。自由度が高いというメリットはあるけど、自由を持て余してしまうかもしれません。


ということで、利用者の視点で、少し考えてみようと思います。

本家の情報からわかること

やるな Gavin!という感じで、リファレンスマニュアルとして必要な説明は、かなりカバーされてますね〜。(もっと細部まで知りたければソースを読めばいいし。)でも、クラスタ環境についての情報は弱いですね。マニュアル中に、"cluster" や "cluster safe" という用語は出てきますが、その説明は書かれていません。

実案件に適用するには

ということで、クラスタ関連を除けば、Hibernate的視点における技術的なハードルはほとんどなさそうです。しかしそれでも、実案件への適用という視点では、ちょっとハードルが高いかもしれません。

たとえば、

システムのライフサイクル中に絶対に変更されないことが保証され、ヒープの使用は10MBを超えることはない

と保証されたエンティティというのがあるとすれば、それをキャッシュするのはわけないわけです。


でも、残念ながら、実案件でそのようなデータってほとんどないですよね。多くの案件では、エンティティのキャッシュがメモリに入りきらない量であるために LRU アルゴリズムによるキャッシュ退避を検討したり、cluster 環境で write 対象のエンティティをキャッシュしようとか検討したりするわけです。そうなると、Hibernate側のキャッシュ関連実装やキャッシュプロバイダ実装の制約事項を理解しなければならなくなったりするわけです。あまつさえ、キャッシュプロバイダ実装側独自のレプリケーションに頼ったりすると、Hibernateとキャッシュプロバイダ双方の実装を詳細まで把握しなくてはならなくなるわけです。


なんてことを考えていると、そもそもどういう動作を望んでいるのかという視点も、実際にどういう動作をしているのかという視点も、どちらもぼやけてしまいそうです。

まとめ

今回は、Hiberanteの2次キャッシュを、単純に技術的に適用して動かすだけなら簡単だけど、適切に設計して実案件に取り込むのはハードルが高そうだねぇという話でした。次回は、キャッシュ関連の分類と、キャッシュプロバイダ実装側の対応について考えてみようと思います。