【问题标题】:Second Level Cache - Why not cache all entities?二级缓存 - 为什么不缓存所有实体?
【发布时间】:2016-04-27 22:22:24
【问题描述】:

根据我的经验,我通常使用共享缓存设置:

<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

然后我的过程是考虑哪些实体不会经常更改,哪些实体会从缓存中受益,性能方面,并将它们标记为@Cacheable。我使用选择性实体缓存的做法是一种学习惯例,但我并不完全理解这种方法。

为什么不缓存所有实体?什么时候缓存所有实体会成为一种损害?我如何才能更好地衡量这一点以做出更有根据的决定?

【问题讨论】:

  • 如果某个实体经常被外部进程更改怎么办?那时可能不想缓存它(从那时起你必须继续刷新)

标签: hibernate jpa caching jpa-2.0 second-level-cache


【解决方案1】:

为什么不缓存所有实体?什么时候可以缓存所有实体成为 损害?我怎样才能更好地衡量这一点以使受过更多教育 决定?

一般来说,要从缓存数据中受益的应用程序应该以读取为主。这意味着每次写入/更新有多个读取。如果不是这种情况,例如在多写或只写(想想从温度计中采样数据),则没有好处,因为从内存中读取数据不会产生任何节省。

要做出明智的决定,您可以缓存所有内容,然后查看缓存的命中/未命中率。如果它很高(+70%),那么你就在正确的轨道上。

【讨论】:

  • Web 容器中的“智能”缓存 (JSR-107) 有助于减少 Web 和 EJB 容器之间的通信。考虑对实体进行分页的“列表”视图,例如由 Primefaces 的 &lt;p:dataTable&gt; 标签和过滤/排序。每次单击(阅读:AJAX 回复)都会导致一次 EJB 调用。在 Web 容器中进行缓存是完全有意义的。
【解决方案2】:

不缓存实体的一些原因:

  1. 当实体频繁更改时(因此您最终会在缓存中无效/锁定它们并重新读取它们,但是您支付的缓存维护成本不低,因为缓存写入操作会很频繁) .
  2. 如果有大量实体实例要缓存,并且在给定的时间段内没有一个实例比其他实例更频繁地使用。然后,您基本上会将实例放入缓存中,然后很快将它们逐出以为新实例腾出空间,而无需频繁地读取缓存的实例以使缓存维护成本得到回报。
  3. 如果实体可以在 Hibernate 不知道的情况下更改(例如从外部应用程序或直接 JDBC)。

【讨论】:

  • 3.) 应该不惜一切代价避免使用 JPA 控制的数据库。如果 JPA 的实体缓存不同步(由 3rd 方完成)应用程序,您将并且必须得到丑陋的异常。这里的解决方法是为您通过 3rd 方程序(如 Adminer/phpMyAdmin 所做的任何事情)编写 JSF 视图。这是我被告知的。
【解决方案3】:

如果你使用 ehcache 作为你的提供者

<property key="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</property>

然后您可以通过设置 ehcache.xml 来配置缓存以限制其使用的资源,以根据需要逐出最少使用的实体。

好文章在这里http://howtodoinjava.com/2013/07/04/hibernate-ehcache-configuration-tutorial/

一般来说我会缓存所有内容,只是限制缓存的大小。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 2016-11-24
    • 2016-06-08
    相关资源
    最近更新 更多