我有一个高流量的网站,我使用休眠。我还使用ehcache来缓存生成页面所需的一些实体和查询。避免同一缓存区域的多个重新填充(由于并发)
问题是“并行缓存未命中”,长时间的解释是,当应用程序启动并且缓存区域很冷时,每个缓存区域被不同的线程多次填充(而不是一次),因为该站点正在同时受到许多用户的打击。另外,由于相同的原因,当某个缓存区域无效时,它会被重新填充很多次。 我该如何避免这种情况?
我设法为convert 1 entity and 1 query cache to a BlockingCache通过提供我自己的实现hibernate.cache.provider_class但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)支持hibernate的事务性缓存并发策略:http://stackoverflow.com/questions/3472613/does-ehcache-2-1-support - 事务性缓存并发策略在hibernat/3474011#3474011 – cherouvim 2011-03-17 07:39:40