基于Java怎么实现Redis多级缓存
导读:本文共3239字符,通常情况下阅读需要11分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 一、多级缓存1. 传统缓存方案请求到达tomcat后,先去redis中获取缓存,不命中则去mysql中获取2. 多级缓存方案tomcat的请求并发数,是远小于redis的,因此tomcat会成为瓶颈利用请求处理每个环节,分别添加缓存,减轻tomcat压力,提升服务性能二、JVM本地缓存缓存是存储在内存中,数据读取速度较快,能大量减少对数据库的访问,减少数据库压力... ...
目录
(为您整理了一些要点),点击可以直达。一、多级缓存
1. 传统缓存方案
请求到达tomcat后,先去redis中获取缓存,不命中则去mysql中获取
2. 多级缓存方案
tomcat
的请求并发数,是远小于redis的,因此tomcat会成为瓶颈利用请求处理每个环节,分别添加缓存,减轻tomcat压力,提升服务性能
二、JVM本地缓存
缓存是存储在内存中,数据读取速度较快,能大量减少对数据库的访问,减少数据库压力
分布式缓存,如redis
- 优点: 存储容量大,可靠性好,可以在集群中共享
- 缺点: 访问缓存有网络开销
- 场景: 缓存数据量大,可靠性高,需要在集群中共享的数据
进程本地缓存, 如HashMap, GuavaCache
- 优点:读取本地内存,没有网络开销,速度更快
- 缺点:存储容量有限,可靠性低(如重启后丢失),无法在集群中共享
- 场景:性能要求高,缓存数据量少
1. 实用案例
Caffeine是一个基于java8开发的,提供了近乎最佳命中率的高性能的本地缓存库
目前spring内部的缓存用的就是这个
<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>3.0.5</version></dependency>
packagecom.erick.cache;importcom.github.benmanes.caffeine.cache.Cache;importcom.github.benmanes.caffeine.cache.Caffeine;importjava.time.Duration;publicfinalclassCacheUtil{privatestaticintexpireSeconds=2;publicstaticCache<String,String>cacheWithExpireSeconds;privatestaticintmaxPairs=1;publicstaticCache<String,String>cacheWithMaxPairs;static{/*过期策略,写完60s后过期*/cacheWithExpireSeconds=Caffeine.newBuilder().expireAfterWrite(Duration.ofSeconds(expireSeconds)).build();/*过期策略,达到最大值后删除*1.并不会立即删除,等一会儿才会删除*2.会将之前存储的数据删除掉*/cacheWithMaxPairs=Caffeine.newBuilder().maximumSize(maxPairs).build();}/*从缓存中获取数据*1.如果缓存中有,则直接从缓存中返回*2.如果缓存中没有,则去数据查询并返回结果*/publicstaticStringgetKeyWithExpire(Stringkey){returncacheWithExpireSeconds.get(key,value->{returngetResultFromDB();});}publicstaticStringgetKeyWithMaxPair(Stringkey){returncacheWithMaxPairs.get(key,value->{returngetResultFromDB();});}privatestaticStringgetResultFromDB(){System.out.println("数据库查询");return"dbresult";}}
packagecom.erick.cache;importjava.util.concurrent.TimeUnit;publicclassTest{@org.junit.Testpublicvoidtest01()throwsInterruptedException{CacheUtil.cacheWithExpireSeconds.put("name","erick");System.out.println(CacheUtil.getKeyWithExpire("name"));TimeUnit.SECONDS.sleep(3);System.out.println(CacheUtil.getKeyWithExpire("name"));}@org.junit.Testpublicvoidtest02()throwsInterruptedException{CacheUtil.cacheWithMaxPairs.put("name","erick");CacheUtil.cacheWithMaxPairs.put("age","12");System.out.println(CacheUtil.getKeyWithMaxPair("name"));System.out.println(CacheUtil.getKeyWithMaxPair("age"));TimeUnit.SECONDS.sleep(2);System.out.println(CacheUtil.getKeyWithMaxPair("name"));//查询不到了System.out.println(CacheUtil.getKeyWithMaxPair("age"));}}
三、缓存一致性
1. 常见方案
1.1 设置有效期
给缓存设置有效期,到期后自动删除。再次查询时可以更新
优势:简单,方便
缺点:时效性差,缓存过期之前可能不一致
场景:更新频率低,时效性要求比较低的业务
1.2 同步双写
在修改数据库的同时,直接修改缓存
优势:有代码侵入,缓存与数据库强一致性
缺点:代码进入,耦合性高
场景:对一致性,失效性要求较高的缓存数据
1.3 异步通知
修改数据库时发送事件通知,相关服务监听到后修改缓存数据
优势:低耦合,可以同时通知多个缓存服务
缺点:时效性一把,可能存在缓存不一致问题
场景:时效性一般,有多个服务需要同步
2. 基于Canal的异步通知
是阿里旗下的一款开源项目,基于java开发
基于数据库增量日志解析,提供增量数据订阅和消费
基于mysql的主从备份的思想
2.1 mysql主从复制
2.2 canal 工作原理
canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
MySQL master 收到 dump 请求, 开始推送 binary log 给 slave (即 canal )
canal 解析 binary log 对象(原始为 byte 流)
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
基于Java怎么实现Redis多级缓存的详细内容,希望对您有所帮助,信息来源于网络。