高斋晓开卷,独共圣人语。这篇文章主要讲述应用系统缓存体系深入研究(Java版)相关的知识,希望能为你提供帮助。
一、序言
在使用MyBatis
、MybatisPlus
等DAO层数据库访问框架式,常常会与一级缓存
、二级缓存
打交道,为了增强对缓存体系的整体把控力,提高软件应用响应速度,这里对三级缓存
一次梳理。
文章图片
缓存固然能够提高系统性能,与此同时也带来了脏数据的副作用,系统的缓存体系、缓存结构、缓存策略、缓存介质等对可能出现的脏数据产生影响。
缓存是一把双刃剑,既能够提高应用系统的效率,同时避免脏数据发生也是不小的工作量。特别是不同的层次的缓存同时使用时,出现数据异常的概率快速提高。
二、一级缓存
以MyBatis技术为基础的一级缓存默认是开启的且无法关闭,有
SESSION
和STATEMENT
两种类型。同一会话在关闭前可以执行多个语句,会话在关闭时,一级缓存生命周期结束。常见的情况是一个会话执行一条SQL语句,因此这两种类型区别不大。mybatis:
configuration:
# 强制使用语句级缓存
local-cache-scope: statement
1、脏数据分析一级缓存可能出现的脏数据问题:当一次会话调用两次以上相同的查询语句(包含查询条件)时,第二次以后调用会从本地缓存取数据,与此同时如果另一个会话将有关的数据修改,显而易见从缓存查询的数据是脏数据。
尽管这种现象是存在的,考虑到会话的持续时间可控,会话结束后数据查询即恢复正常,大多数情况下数据的实时行达不到此要求。
2、回避脏数据
- 强制使用语句级缓存
- 会话及时关闭
- 避免使用复杂查询语句
三、二级缓存
二级缓存面向
namespace
,同一个 Mapper 文件下所有的 DAO 方法都能对缓存施加影响。二级缓存默认是关闭状态。正确使用二级缓存,请参考MybatisPlus二级缓存解决方案一文。
1、脏数据分析二级缓存产生脏数据的情况有很多,典型的场景如下:
- 联合查询
namespace
的缓存中,与此同时,表 A 或者表 B 对数据库数据做了更新,联合查询与更新表如果不在同一个namespace
下,在缓存刷新时间结束前是收不到更新缓存的信号的,毫无疑问是存在脏数据的。2、回避脏数据
- 设置合理的缓存过期时间
- 避免使用传统意义上的多表连接查询
namespace
为单位的缓存数据能够主动刷新。新型多表连接查询操作,请查看MybatisPlus连接查询解决方案。四、三级缓存
三级缓存指业务层缓存,通常面向
service
层,主要缓存不常变化或者重复计算耗费CPU资源的数据。一般来讲,三级缓存存在于二级缓存之上。业务层缓存实现非常多,常见有缓存实现有:- Caffeine使用手册
- EhCache使用手册
- Redis使用手册
1、使用场景业务缓存,顾名思义是因处理业务流程而产生的数据缓存需要,比如说一项重复的计算,因为调用频率较高,因此可以对结果予以缓存。
业务层调用DAO层获取数据建议使用二级缓存完成,业务层的主要目标是使用数据,缓存数据并不是其主要职责。
五、接口缓存
接口缓存面向整个接口,面向用户端提高接口的响应性能。接口层可以直接调用数据访问层,或者调用数据访问层(二级缓存),异或调用业务层,异或调用业务层(三级缓存),甚至对接口返回结果本身进行缓存。
推荐阅读
- Linux之route命令
- 实践GoF的23的设计模式(SOLID原则(下))
- #yyds干货盘点#自定义spring boot starter三部曲之三(源码分析spring.factories加载过程)
- k8s初面考点ReplicaSet副本集极限9连击你懂了吗()
- #yyds干货盘点# Java八股文上篇
- #yyds干货盘点# Kubernetes 带你剖析容器运行时以及 CRI 原理(24)
- #yyds干货盘点#java接收前端map报错不能被转换
- 使用 FieldMask 提高 C# gRpc 服务性能 #yyds干货盘点#
- 木棉花知识分享——设计计算器的UI界面