java cache缓存更新_JetCache 扩展:实现二级缓存准实时刷新

本文介绍了在项目中遇到的频繁基础数据查询导致Redis效率不高的问题,以及如何利用JetCache实现二级缓存,减少Redis查询延迟。通过对比实验展示了JetCache二级缓存与一级缓存、Redis直接查询的效率差距,并详细讲解了自定义扩展JetCache以实现实时刷新二级缓存的方法,包括基于Redis订阅发布的缓存消息发布器和本地缓存过期策略。
摘要由CSDN通过智能技术生成

遇到问题7 C% Y3 b/ s; }6 |2 G- X  V3 i' r

4 V2 H0 j( N4 z9 G5 u! |$ B! q

项目建设过程中遇到一个问题:使用频率很高的基础数据(8MB),缓存到redis 存取效率不高。存在多条这样的基础数据。

! `5 X; \* Z, Q8 ^9 a) L1 \  J8 U* u2 i

4d5dfeeacbae072a388ab32a3c9d6bf4.png9 q) T5 B% K; O# r3 i

当然,可以用ListenableFutureCallback结合CountDownLatch做并发和结果聚合。(前提是获取缓存数据的操作不存在先后关系)

/ J2 M1 v2 O0 D但每次接口调用仍会有零点几秒消耗在查询Redis上。

! \1 Q5 C4 j/ f1 _0 l' ]2 s自行实现二级缓存又存在一致性问题:, G7 A* y. c" D( j' |0 w

即使有定时刷新作业,也会出现:一段时间内同一个应用的不同实例本地缓存的数据不一致的情况。

1 Q: J0 }+ x# A2 k因为更新的时候无法更新所有应用实例的本地缓存。9 l" C1 k9 ?( p  u# [2 H  b, |4 b% r

举栗说明:

8 @+ Y* i+ U. |- z/ G应用A借助JetCache实现二级缓存。部署时创建两个实例4 M( i: F( W" Z

实例1修改了一条数据,并更新到数据库、local cache、remote cache中。

& X* y6 {, N  B4 \5 c实例2在本地缓存刷新或过期前,local cache中的数据仍是旧的。

* n4 Q6 z" o* A1 W6 c9 |5 @; V数据不一致的最长时间取决于缓存刷新作业的执行周期

* Y2 `! {1 Y/ B5 u! |& v后面goolge到了阿里开源的二级缓存组件JetCache,做了对比实验:# \* X) h8 s" Z6 a

Redisson(redis)VS JetCache 一级缓存(redis) VS JetCache 二级缓存(redis + caffeine)

" `& f* O% B; C8 D9 q) C7 ]/ f+ p/ P* `

配置文件:

' t6 K0 ]6 u. U' ?  \, W. V6 {) C) r7 r1 v" k: q; {

18fcdbec11dbaa681c2d2d671e920824.png9 l) [) i" A" N5 n

单元测试方法:/ {  D% U1 F3 f5 P     @Test    public void compareEfficiency() throws IOException {        //保障数据都加载到缓存中        airportCacheDao.getAllFromRedisson();        long start = System.currentTimeMillis();        for (int i = 0; i < 20; i++) {            airportCacheDao.getAllFromRedisson();        }        long end = System.currentTimeMillis();        System.out.println(String.format("通过Redisson查询redis;20次全量数据,耗时:%s ms", end - start));        //保障数据都加载到缓存中        airportCacheDao.getAllFromDbOrJetCacheRemote();        long start1 = System.currentTimeMillis();        for (int i = 0; i < 20; i++) {            airportCacheDao.getAllFromDbOrJetCacheRemote();        }        long end1 = System.currentTimeMillis();        System.out.println(String.format("通过JetCache查询redis;20次全量数据,耗时:%s ms", end1 - start1));        //保障数据都加载到缓存中        airportCacheDao.getAllFromDbOrJetCacheBoth();        long start2 = System.currentTimeMillis();        for (int i = 0; i < 20; i++) {            airportCacheDao.getAllFromDbOrJetCacheBoth();        }        long end2 = System.currentTimeMillis();        System.out.println(String.format("通过JetCache二级缓存查询;20次全量数据,耗时:%s ms", end2 - start2));        System.in.read();    }

; O0 F% e( W; ]3 P0 Z0 P4 a~5 C6 `- c  @! q

DAO中的方法

5 [- [" P; c1 s0 n; U8 i    public List getAllFromRedisson() {        List airports;        RBucket airportRList = redissonClient.getBucket(RedisKey.MDMAirportDataList+"_Redisson");        if (airportRList.isExists()) {            //System.out.println("get from cache");            airports = airportRList.get();        } else {            System.out.println("get from db");            airports = iMdBmdmAirportDao.list(null);            airportRList.set(airports);        }        return airports;    }    @Cached(name = RedisKey.MDMAirportDataList+"_JetCache_Remote", cacheType = CacheType.REMOTE, expire = 1000)    public List getAllFromDbOrJetCacheRemote() {        System.out.println("get from db");        List airports;        airports = iMdBmdmAirportDao.list(null);        return airports;    }    @Cached(name = RedisKey.MDMAirportDataList+"_JetCache_Both", cacheType = CacheType.BOTH, expire = 1000)    public List getAllFromDbOrJetCacheBoth() {        System.out.println("get from db");        List airports;        airports = iMdBmdmAirportDao.list(null);        return airports;    }

c298e98091fbea66ea5a1c23038f8714.png从对比实验中可看出查询效率差别巨大。

7 E  Y) Z: m0 X, \0 |* h说明:: {: F1 o; n

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值