我有一个Web服务,平均有~1k个请求线程同时运行。这些线程从缓存(当前在ehcache上)访问数据。当缓存中的条目到期时,命中过期条目的线程尝试从DB获取新值,而其他线程也尝试命中此条目块,即我使用BlockingEhCache装饰器。我希望其他线程使用与“遗漏”键对应的“陈旧”值,而不是让其他线程等待“获取线程”。是否有任何第三方为此目的开发了ehcache装饰器?您知道有任何其他具有此行为的缓存解决方案吗?其他建议?
答案 0 :(得分:1)
我不知道EHCache是否足以提供解决问题的具体建议,因此我将概述在没有EHCache的情况下我会做什么。
假设所有线程都使用名为FooService的Service接口和名为SimpleFooService的服务bean访问此缓存。该服务将具有获取所需数据所需的方法(也被缓存)。这样你就可以隐藏它从前端缓存的事实(http请求对象)。
我们不是简单地将要缓存的数据存储在服务的属性中,而是为它创建一个特殊对象。我们称之为FooCacheManager。它会将缓存存储在FooCacheManger的一个属性中(比如它的Map类型)。它将有getter来获取缓存。它还有一个名为reload()的特殊方法,它将从DB加载数据(通过调用服务方法来获取数据,或通过DAO),并替换缓存的内容(保存在属性中)
这里的诀窍如下:
此方法自读取线程有效:
写入线程在写入数据时也不会阻塞。
如果不清楚,我可以添加示例代码。
答案 1 :(得分:0)
由于ehcache删除陈旧数据,因此不同的方法可以刷新数据的概率随着到期时间的增加而增加,如果到期时间“足够”,则为0。
因此,如果线程1需要一些数据元素,它可能会刷新它,即使数据还不老。 在此期间,线程2需要相同的数据, 可能 使用现有数据(刷新线程尚未完成)。线程2可能也会尝试刷新。
如果您正在使用引用(更新程序线程加载对象,然后只是更改缓存中的引用),则缓存上的get和set操作不需要单独的同步。