jetcache icon indicating copy to clipboard operation
jetcache copied to clipboard

微服务下刷新缓存的问题

Open anic opened this issue 3 years ago • 7 comments

请教一下大大,使用jetcache遇到这样的问题,有何指引?

缓存注解写在微服务的接口上,由于开启了CacheType.BOTH,所以微服务生产者和消费者都会有一级缓存和二级缓存

参考是首页的这个例子 public interface SummaryService{ @Cached(expire = 3600, cacheType = CacheType.BOTH) @CacheRefresh(refresh = 1800, stopRefreshAfterLastAccess = 3600, timeUnit = TimeUnit.SECONDS) @CachePenetrationProtect BigDecimal summaryOfToday(long catagoryId); }

由于开了CacheRefresh(在缓存没失效时主动刷新),所以会从微服务consumer(有时候可能是provider刷新,取决于谁拿到锁)发起刷新请求,调用微服务provider。

如果此时数据库的数据发生变化,通过CacheUpdate更新了某个provider的一级和二级缓存,但是有一个provider的一级缓存还没更新,此时CacheRefresh的请求刚好hit中这个还没更新一级缓存的节点。

image

然后这个结果,会刷新到consumer的一级和二级缓存里,因此redis也被更新了错的数据。

是不是: 1 不要同时用两级缓存+CacheRefresh? 2 更新所有的一级缓存,但是这个 issue 说没有:https://github.com/alibaba/jetcache/issues/566

anic avatar Jun 20 '21 16:06 anic

本地缓存可以通过localExpire属性设置一个较短的超时时间 。

如果tps不是特别大,也可以不要开启两级缓存。

缓存更新以后,现在没有一个官方的机制去刷新所有的本地缓存。

areyouok avatar Jun 23 '21 16:06 areyouok

对实时性要求不高的话可以考虑定时刷新本地缓存?

LeoMalik avatar Jun 25 '21 08:06 LeoMalik

设置一个比较短的localExpire,等于就会定式刷新本地缓存了。

areyouok avatar Jun 25 '21 15:06 areyouok

本地缓存可以通过localExpire属性设置一个较短的超时时间 。

如果tps不是特别大,也可以不要开启两级缓存。

缓存更新以后,现在没有一个官方的机制去刷新所有的本地缓存。

@CacheUpdate 的原理,是只更新二级缓存么?一级缓存的更新有没有API?

anic avatar Jun 26 '21 02:06 anic

难道不会导致缓存不一致? 刷新二级缓存的时候,应该清掉本地缓存吧

wave-gbt avatar Jul 19 '22 02:07 wave-gbt

二级缓存一定会不一致,如果能接受这个不一致才可以使用二级缓存。新版本的程序(尚未发布的2.7)可以让本地缓存失效(可选)。

微服务场景,主调方和被调方不应该使用同一个缓存,这样会有很多问题,如果用了的话,可以考虑在某一方设置一个全局的keyPrefix,保证互相错开。

areyouok avatar Jul 19 '22 07:07 areyouok

二级缓存一定会不一致,如果能接受这个不一致才可以使用二级缓存。新版本的程序(尚未发布的2.7)可以让本地缓存失效(可选)。

微服务场景,主调方和被调方不应该使用同一个缓存,这样会有很多问题,如果用了的话,可以考虑在某一方设置一个全局的keyPrefix,保证互相错开。

目前dubbo框架支持client上使用jetcache注解,这样主调方和被调方用的是同一份remote缓存(如果开启了remote),您说【使用同一份会有很多问题】,请问会有什么问题。我们也考虑一下要不要使用同一份remote缓存。 感谢!

luger1990 avatar Oct 06 '23 11:10 luger1990