Java 使用缓存作为数据库前面的层
我正在开发一些本质上是异步的后端服务。也就是说,我们有多个异步运行的作业,并将结果写入某个记录 该记录基本上是一个类,它包装了结果的Java 使用缓存作为数据库前面的层,java,caching,guava,jcache,caffeine,Java,Caching,Guava,Jcache,Caffeine,我正在开发一些本质上是异步的后端服务。也就是说,我们有多个异步运行的作业,并将结果写入某个记录 该记录基本上是一个类,它包装了结果的HashMap(键是job\u id) 问题是,我不想预先计算或知道要运行多少个作业(如果我知道,我可以cache.invalidate()在所有作业都已完成时缓存密钥) 相反,我希望有以下方案: 设置新记录的到期日(即expireAfterWrite) 到期时,写入(实际上是upsert)数据库中的记录 如果发生缓存未命中,则调用load()从数据库中获取记录(如
HashMap
(键是job\u id
)
问题是,我不想预先计算或知道要运行多少个作业(如果我知道,我可以cache.invalidate()
在所有作业都已完成时缓存密钥)
相反,我希望有以下方案:
expireAfterWrite
)upsert
)数据库中的记录load()
从数据库中获取记录(如果未找到,则创建一个新记录)另外,如有必要,我愿意切换到其他缓存解决方案 您可以查看带有write-behind的Ehcache。这当然需要更多的安装工作,但它工作得很好我认为Ehcache没有计划在写延迟的情况下过期。过期是通过用死掉的条目污染缓存并依靠大小逐出最终丢弃它们来实现的。咖啡因和Guava一样,不会创建线程,因此它不能在用户活动之外安排工作。两者都需要定期调用
cleanUp
<不过,code>CacheWriter将为write-behind提供更安全的语义。调度语义可以通过Java 9功能()完成,我将优先考虑提供接口,以便在与JDK8兼容的同时利用这一点。在中,这可以通过添加同步过期侦听器来实现,例如builder.Cache2kBuilder.addListener(新的CacheEntryExpiredListener()…)
并使用builder关闭夏普到期。夏普到期(false)
。但是,cache2k在过期时每个缓存使用一个线程,如果您需要在数据库上并行执行多个过期操作,这可能会成为瓶颈。您的用例就是一个很好的例子。我将记住这一点,以便进一步开发。@yaseco此功能已在咖啡因2.8中发布。只需在缓存生成器中指定caffee.scheduler(scheduler.systemScheduler())
(如果是JDK9+),它就会立即删除过期的条目。