当前位置: 首页 > 面试题库 >

避免对同一缓存区域进行多次填充(由于并发)

苏鸿才
2023-03-14
问题内容

我的网站流量很高,并且使用hibernate模式。我还使用ehcache缓存生成页面所需的一些实体和查询。

问题是“并行高速缓存未命中”,长原因是当应用程序启动且高速缓存区域变冷时,每个高速缓存区域将由不同线程填充多次(而不是仅一次),因为该站点受到许多用户的攻击与此同时。另外,由于相同的原因,当某些缓存区域无效时,它会被多次填充。如何避免这种情况?

我通过向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,但没有明确的答案。


问题答案:

这个问题的最大改进是ehcache现在(从2.1开始)支持transactionalhibernate cache
policy。这极大地缓解了此问题中描述的问题。

为了更进一步(在访问同一查询缓存区域时锁定线程),需要实现QueryTranslatorFactory以返回自定义(扩展)的QueryTranslatorImpl实例,该实例将检查查询和参数,并根据需要在list方法中进行阻塞。当然,这与使用获取许多实体的hql的查询缓存的特定用例有关。



 类似资料:
  • 我在Grails应用程序中工作,希望在不同的文件中记录消息。我想在不同的文件中记录异常,正常和API日志。但是根据Log4j的一般角色,如果我们将记录器级别设置为'info',那么警告和错误消息也将开始登录到这个文件中,而我想在不同的文件中记录错误消息。因此,我的错误信息将被记录在错误文件和信息文件中。虽然我希望“信息”记录器只记录“信息”级别的消息,而不是“错误”级别的消息。而“错误”记录器只记

  • 问题内容: 我正在开发一个Angular应用程序。在此,我将在进入仪表板之前对用户进行身份验证。为了达到这个目的,我写了as 登录功能 我还想限制用户访问路由(如果尚未登录)。为此,我想到了this 。 路线 我说上面的代码 DIRTY 的原因是,如果我要保护10条未授权用户使用的路由,则必须在所有路由中复制相同的resolve函数。 所以我的问题是,我应该怎么做才能摆脱多重解析功能并能够编写DR

  • 问题内容: 我有一个宽度为70%的元素,它漂浮在一个宽度为30%的元素旁边,但是当我添加填充时,它会扩展元素并破坏格式,有没有办法使它仅增加内容距离边缘而不是仅仅扩大它? 问题答案: 使用模型时,边框大小中将包含填充。

  • 问题内容: 我有两个平行的继承链: 我的经验是,并行继承层次结构在增长时会成为维护上的麻烦。 即不添加方法到我的主要类。 如何避免并行继承层次结构而又不破坏关注点分离的概念? 问题答案: 我正在考虑使用“访客”模式。 这样,您就可以避免多余的继承树,并使格式化逻辑与Vehicle类分开。当然,当您创建新的载具时,您必须向Formatter接口添加另一种方法(并在Formatter接口的所有实现中实

  • 下面的php代码用于预填充输入框,但不适用于文本区域。问题是标准输入框的高度很小,所以文本显示在一行上。我尝试使用文本区域,但它出现空白时,呈现。代码显示了这两种方法,工作方法,然后是文本区域方法。有谁能给出建议吗?

  • 我有两个集合比尔和员工。比尔包含有关每月学生账单的信息,员工包含在学校工作的所有类型的人(会计师、教师、维护等)。 比尔有billVerifyBy和classteacher字段,它们指向员工的记录。 账单收集 员工集合 我需要检索与特定账单相关的帐户和教师信息。我正在使用MongoDB查找来获取信息。但是,我必须查找同一个表两次,因为billVerifiedBy和classteacher属于相同的