现实分布式项目中会不会开启mybatis的二级缓存?
在分布式项目中,是否开启MyBatis的二级缓存需结合具体场景和技术方案综合评估。
以下是关键考量因素:
一、默认二级缓存的局限性
- 隔离性问题 :MyBatis默认的二级缓存基于HashMap实现,
属于本地缓存,不同节点间的缓存数据无法共享
,可能导致集群环境下
的数据不一致或脏读问题。 - 缓存刷新机制 :默认缓存采用
"全量清空"
策略,任何更新操作
会清空对应namespace下的所有缓存,可能引发缓存雪崩
。 - 序列化要求 :实体类必须实现
Serializable
接口,增加了开发约束。
二、分布式场景下的替代方案
-
Redis集成
- 通过自定义缓存实现(如
MybatisRedisCache
),将二级缓存替换为Redis等分布式缓存,解决数据共享问题。 - 需额外处理缓存过期策略、序列化兼容性等问题。
- 通过自定义缓存实现(如
-
Spring Cache抽象
- 使用
@Cacheable
等注解结合Redis,实现更灵活的分布式缓存管理,避免直接依赖MyBatis缓存机制。
- 使用
三、实际应用建议
- 高并发读场景 :若查询频繁且数据更新较少,可开启分布式二级缓存(
如Redis
),但需配合合理的TTL和一致性策略。 - 强一致性要求 :若业务对数据实时性要求高(如金融交易),
建议关闭二级缓存
,直接依赖数据库
。 - 混合架构 :可结合本地缓存(
如Caffeine
)作为一级缓存,Redis
作为二级缓存,平衡性能与一致性。
四、典型配置示例
xml
<!-- MyBatis配置开启二级缓存 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- Mapper中指定Redis缓存实现 -->
<cache type="com.example.MybatisRedisCache"/>
综上,分布式项目中通常不会直接使用MyBatis默认二级缓存
,而是通过自定义分布式缓存(如redis)
或框架级方案(如Spring Cache)实现类似功能。
引用链接:
1.为什么mybatis默认不开启二级缓存? - 学亮编程手记
2.【SpringBoot+MyBatis】二级缓存以及使用Redis缓存数据 - CSDN博客
3.Mybatis自定义分布式二级缓存实现与遇到的一些问题解决方案! - 博客园
4.HoRain云--MyBatis一级缓存、二级缓存详解:正确理解缓存机制与实战应用 - HoRain 云助手
7.使用Spring Cache优雅的实现分布式二级缓存! - CSDN博客
8.Spring Boot 的 3 种二级缓存落地方案 - CSDN博客
9.MyBatis Plus整合Redis实现分布式二级缓存的问题 - 脚本之家
10.《从Java面试题来看源码》,项目中使用 Mybatis 缓存吗?为什么项目中不用 Mybatis 的二级缓存? - 腾讯云
11.MyBatis之缓存避坑: MyBatis的一级缓存、二级缓存的实现分析与分布式环境下数据一致性问题 - 腾讯云
12.MyBatis Plus整合Redis实现分布式二级缓存 - CSDN博客
14.MyBatis二级缓存深度解析:从入门到实战,看这篇就够了! - xuanyi.blog.csdn.net
15.【MyBatis学习13】MyBatis中的二级缓存[通俗易懂] - 腾讯云
17.mybatis+redis实现分布式缓存+缓存面试题 - CSDN博客
19.🚀 MyBatis缓存机制揭秘 🔍 - 此刻的雨一落便是长久
22.Spring Boot 集成 Redis 配置 MyBatis 二级缓存 - 阿甘
24.MyBatis框架详解:从基础到实战的全栈指南 - Arvin
Mybatis有多少级缓存?
MyBatis 提供两级缓存机制,用于优化数据库查询性能。
具体如下:
1. 一级缓存
- 作用域 :
SqlSession
级别,默认开启且无法关闭。 - 生命周期 :与
SqlSession
绑定,当执行flush()
、close()
、事务提交或回滚时,缓存自动清空。 - 特点 :
- 同一
SqlSession
内,重复执行相同 SQL(参数、方法、Mapper 接口一致)会直接命中缓存,避免重复查询数据库。 - 执行增删改(DML)操作或手动调用
clearCache()
会立即清空当前会话的所有缓存。
- 同一
2. 二级缓存
- 作用域 :
Mapper
级别(namespace
作用域),默认关闭,需手动开启。 - 开启条件 :
- 全局配置中启用缓存(
<setting name="cacheEnabled" value="true"/>
)。 - 实体类实现
Serializable
序列化接口。 - 映射文件中添加
<cache/>
标签。
- 全局配置中启用缓存(
- 查询顺序 :
优先检查二级缓存 → 再查一级缓存 → 最后访问数据库。 - 失效机制 :
同namespace
下的 DML 操作会清空该 Mapper 的所有缓存;可通过useCache="false"
禁用特定查询的缓存。
⚠️ 注意事项
- 性能与一致性 :
一级缓存响应快但作用域有限,二级缓存可跨会话但需处理数据一致性问题;分布式场景建议结合 Redis 等第三方缓存。 - 适用场景 :
高频查询且数据变动少时适合二级缓存;短事务或单次操作频繁查询适合一级缓存。
两级缓存协同工作,构成 MyBatis 完整的缓存体系,可显著减少数据库压力,但需根据业务需求权衡实时性与性能。
引用链接:
3.Mybatis缓存机制详解:一级与二级缓存的区别 - 无名指的心愿
4.【Java面试】阿里二面,讲一下Mybatis里的缓存机制?请看Mic老师是如何替你解答的! - 哔哩哔哩
5.MyBatis 一级缓存与二级缓存_mybatis一级缓存和二级缓存-CSDN博客 - CSDN博客
7.【Java面试】阿里一面:MyBatis缓存机制的理解以及优缺点是什么? - 哔哩哔哩
8.【2025Java最新大厂面试题】7天刷完7月面试、跳槽拿offer就稳啦!!包括Java基础/并发编程/JVM/Mysql/Spring/Redis等等! - 哔哩哔哩
9.逼自己6月刷完这100集《2025Java面试题》,啃透这4个重点,offer拿到手软!|视频含代码讲解! - 哔哩哔哩
10.数据库常见面试题:聊聊Mybatis中的一级缓存,二级缓存 - 哔哩哔哩
11.Mybatis源码解析(十):一级缓存和二级缓存 - 腾讯云
12.MyBatis之缓存避坑: MyBatis的一级缓存、二级缓存的实现分析与分布式环境下数据一致性问题 - 腾讯云
13.HoRain云--MyBatis一级缓存、二级缓存详解:正确理解缓存机制与实战应用 - HoRain 云助手
14.MyBatis中一级缓存和二级缓存的区别 - 脚本之家
16.Mybatis中的一级缓存与二级缓存详解 - 百度开发者中心
17.MyBatis中的一级、二级缓存机制详解 - 百度开发者中心
19.Mysql--实战篇--mybatis cache(一级缓存,二级缓存,子查询主键主查询全部,查询条件加索引,覆盖索引等) - CSDN博客
MyBatis二级缓存有哪些失效情况?
MyBatis二级缓存的失效主要涉及配置、操作、事务及环境四类场景,具体如下:
🔧 一、配置或条件缺失导致失效
- 未开启全局缓存
全局配置中若未设置<setting name="cacheEnabled" value="true"/>
,二级缓存完全禁用。 - Mapper未配置
<cache/>
标签
单个Mapper需显式添加<cache/>
标签,否则该命名空间(namespace)下的查询不启用二级缓存。 - 实体类未序列化
查询结果对应的实体类未实现Serializable
接口时,缓存数据无法正确存储。 - 查询方法禁用缓存
在<select>
标签中设置useCache="false"
,该查询结果不进入二级缓存。
🔄 二、数据变更操作导致失效
- 同namespace的DML操作
执行同Mapper下的INSERT
/UPDATE
/DELETE
语句后,该命名空间下所有二级缓存数据立即清空。 - 配置强制刷新
flushCache=true
若查询语句配置flushCache="true"
,执行时会同时清空一、二级缓存(通常不建议用于查询)。 - 手动清空缓存
调用SqlSession.clearCache()
或通过代码触发缓存管理器(如Cache
对象)的清空操作。
️ 三、事务或会话行为导致失效
- 会话未提交或关闭
二级缓存仅在SqlSession
执行commit()
、close()
后生效,未提交的查询数据不会刷入缓存。 - 跨SqlSession的并发问题
一个会话提交数据更新后,其他会话可能因缓存未同步而读到旧数据(需结合事务隔离级别处理)。
🌐 四、分布式环境失效场景
- 多节点缓存不一致
集群部署时,单节点更新数据后,其他节点的二级缓存不会自动失效,导致脏读。 - 第三方缓存未集成
若使用Redis等中央缓存替代默认二级缓存,但未正确配置同步机制,可能引发数据不一致。
📊 高频失效场景总结
场景类型 | 具体操作 | 失效范围 |
---|---|---|
同namespace写操作 | INSERT/UPDATE/DELETE | 整个Mapper缓存清空 |
会话生命周期异常 | SqlSession未commit/close | 新数据无法存入缓存 |
序列化缺失 | 实体类未实现Serializable | 缓存存储失败 |
分布式环境更新 | 单节点数据更新 | 其他节点缓存未同步失效 |
💡 应对建议
- 强制刷新配置 :对实时性要求高的查询,显式设置
flushCache="true"
(慎用); - 禁用二级缓存 :分布式场景建议关闭二级缓存(配置
cacheEnabled="false"
或<cache blocking="true"/>
),改用Redis等集中式缓存; - 测试验证 :通过日志监控缓存命中率(如
LoggingCache
包装类)。
引用链接:
1.HoRain云--MyBatis一级缓存、二级缓存详解:正确理解缓存机制与实战应用 - HoRain 云助手
2.MyBatis缓存机制(一级/二级缓存失效场景) - 51CTO博客
4.35. MyBatis中的缓存失效机制是如何工作的? - CSDN博客
5.MyBatis 中的缓存失效是什么时候发生的 - www.xth8013.com
6.Mybatis源码解析(十):一级缓存和二级缓存 - 腾讯云
8.【MyBatis】MyBatis的缓存 - CSDN博客
9.Mybatis二级缓存失效及二级缓存使用简介 - CSDN博客
11.MyBatis中二级缓存和其失效的一种情况 - 博客园
12.解锁MyBatis 缓存:深入剖析原理与典型实现示例展示 - 跟我从零开始学编程
13.Mybatis插件失效背后真正你不知道的原因??? - 哔哩哔哩
14.mybatis的二级缓存使用以及禁用 - CSDN博客
15.【为什么要禁用mybatis二级缓存?】 - CSDN博客
16.mysql 禁用mybatis缓存 - 51CTO博客
17.spring boot 关闭mybatis框架一二级本地缓存 - 51CTO博客
18.【MyBatis学习13】MyBatis中的二级缓存[通俗易懂] - 腾讯云
19.21Mybatis中缓存机制_二级缓存失效情况 - 哔哩哔哩
20.【Java面试】阿里一面:MyBatis缓存机制的理解以及优缺点是什么? - 哔哩哔哩
21.springboot mybatisplus 删除时二级缓存未刷新 mybatis二级缓存脏数据 - 51CTO博客
22.Mybatis中一级缓存和二级缓存使用详解 - 阿里云开发者社区
23.MyBatis 一级缓存与二级缓存_mybatis一级缓存和二级缓存-CSDN博客 - CSDN博客
24.MyBatis知识汇总(第十篇)【详解】MyBatis的缓存机制,一级缓存+失效的3种情况,二级缓存,详解,实例,注意事项 - 51CTO博客
26.springboot mybatis缓存失效 - 51CTO博客
27.MyBatis缓存揭秘:两级并存 - 七安Melody会彤彤
30.关于MyBatis缓存你不知道的事 - 千锋Java学习站
32.spring mybatis 缓存失效原因 mybatis缓存key - 51CTO博客
34.mybatis 二级缓存失效_Mybatis09缓存 - CSDN博客
35.二级缓存失效_MyBatis 中的一级和二级缓存 - CSDN博客
36.由Mybatis 源码畅谈软件设计(八):从根上理解 Mybatis 二级缓存 - 京东云
37.MyBatis一级缓存和二级缓存详解 - 胖乎乎的鲸鱼喜欢蓝莓
MyBatis二级缓存有什么用?
MyBatis二级缓存的核心作用是跨SqlSession
共享高频查询数据,显著减少数据库访问压力并提升查询性能。其主要价值体现在以下场景:
🔥 核心作用
-
减少数据库访问
当多个
SqlSession
重复查询相同数据(如商品信息、配置表)时,二级缓存将结果存储在内存中,后续查询直接命中缓存,避免重复访问数据库、。💎 典型场景:高并发下频繁读取静态数据(如省份列表、系统参数)、。
-
加速复杂查询响应
对多表关联、聚合计算等耗时查询,首次执行后结果存入二级缓存,后续相同查询直接从内存返回结果,跳过SQL解析与磁盘I/O,响应速度提升数倍、。
-
跨会话数据共享
不同用户(不同
SqlSession
)访问相同数据时,二级缓存允许直接复用已缓存结果,消除重复查询、。例:用户A查询订单详情后,用户B查询同一订单可直接读缓存。
⚠️ 适用边界(需结合业务设计)
适用场景 | 不适用场景 |
---|---|
读多写少(如配置表、历史数据) | 写多读少(如库存、交易流水) |
数据一致性要求较低 | 强一致性场景(如支付状态) |
单机或集中式部署 | 分布式集群未同步缓存、 |
️ 性能优化对比
缓存层级 | 作用范围 | 性能增益点 | 瓶颈 |
---|---|---|---|
一级缓存 | 单会话内 | 避免会话内重复查询 | 会话结束即失效 |
二级缓存 | 全局跨会话 | 减少跨会话重复查询 | 分布式环境需额外集成 |
📌 关键建议:
- 对更新频繁的数据,可通过
<cache flushInterval="600000">
设置缓存自动刷新间隔;分布式场景建议 关闭 默认二级缓存,改用 Redis 等集中式缓存。
引用链接:
1.【MyBatis学习13】MyBatis中的二级缓存[通俗易懂] - 腾讯云
2.mybatis底层为什么设计二层缓存? - CSDN博客
3.Mybatis源码解析(十):一级缓存和二级缓存 - 腾讯云
4.MyBatis的一级缓存和二级缓存以及优点说明 - 脚本之家
7.MyBatis 一级缓存与二级缓存_mybatis一级缓存和二级缓存-CSDN博客 - CSDN博客
9.2024 springboot mybatis plus redis 二级缓存 mybatis二级缓存弊端 - 51CTO博客
10.Mybatis中的一级、二级缓存是怎么实现的 - 格物信息
11.MyBatis一级缓存和二级缓存详解 - 胖乎乎的鲸鱼喜欢蓝莓
13.MyBatis缓存机制(一级缓存,二级缓存) - 腾讯云
14.MyBatis 有哪些缓存? 一级缓存和二级缓存有什么区别? - CSDN博客
16.MyBatis中一级缓存和二级缓存的区别 - 脚本之家
17.Mybatis缓存的使用(Mybatis一级、二级缓存)_mybatis一级缓存和二级缓存应用场景-CSDN博客 - CSDN博客
18.Spring Boot 整合 MyBatis 中使用一级缓存与二级缓存详解(含完整示例) - CSDN博客
19.由Mybatis 源码畅谈软件设计(八):从根上理解 Mybatis 二级缓存 - 京东云
20.mybatis一级缓存和二级缓存的应用场景及生效条件;为什么mybatis默认不开启二级缓存? - 51CTO博客
22.25 MyBatis 映射文件 cache之二级缓存 - 哔哩哔哩
23.【Java面试】 在微服务架构下,MyBatis 二级缓存的使用会面临哪些挑战? - 哔哩哔哩
25.如何了解MyBatis 的二级缓存? - 知足快乐田园
26.mybatis一级缓存和二级缓存的应用场景及生效条件 - 学亮编程手记
27.【Java面试】阿里一面:MyBatis缓存机制的理解以及优缺点是什么? - 哔哩哔哩
29.MyBatis框架:二级缓存概述及案例 - HelloWorld小码农
31.10分钟带你掌握MyBatis二级缓存,轻松应对复杂查询。 - 笑傲存钱罐
32.HoRain云--MyBatis一级缓存、二级缓存详解:正确理解缓存机制与实战应用 - HoRain 云助手
35._Mybatis一级缓存和二级缓存(带测试方法) - 腾讯云
36.MyBatis一级缓存和二级缓存详解 - CSDN博客
37.Java社招面试题:MyBatis 的一级、二级缓存?面试官问完我直接讲了半小时! - 51CTO博客
38.数据库常见面试题:聊聊Mybatis中的一级缓存,二级缓存 - 哔哩哔哩
39.🚀 MyBatis缓存机制揭秘 🔍 - 此刻的雨一落便是长久
分布式环境下mybatis缓存有什么问题?
在分布式环境下,MyBatis的默认缓存机制(尤其二级缓存)会面临以下核心问题及挑战:
🚨 一、数据一致性问题(最严重)
-
节点间缓存不同步
- 默认二级缓存是本地存储(如
PerpetualCache
基于HashMap
),不同服务节点的缓存相互独立。当一个节点更新数据并清空自身缓存时,其他节点仍持有旧数据,导致脏读。 - 典型场景 :
- 节点A更新用户信息 → 清空自身缓存;
- 节点B读取同一用户 → 返回未更新的缓存旧值。
- 默认二级缓存是本地存储(如
-
跨节点更新失效延迟
- MyBatis仅在同命名空间的DML操作后清空当前节点缓存,但无法通知其他节点同步失效。
⚡ 二、缓存穿透与雪崩风险加剧
-
穿透问题(查询不存在的数据)
- 恶意请求高频访问不存在的数据(如无效ID),穿透缓存直达数据库。分布式环境下,多个节点同时遭受此类攻击会迅速压垮数据库。
-
雪崩问题(缓存集中失效)
- 多个节点缓存设置相同过期时间,到期后所有请求同时冲击数据库,引发连锁故障。
⚠️ 三、性能与资源瓶颈
-
内存占用过高
- 每个节点独立缓存全量数据,造成内存冗余。例如,10个节点缓存同一10GB数据集 → 总占用100GB,资源利用率低下。
-
分布式锁竞争
- 若通过分布式锁(如RedisLock)强制缓存一致性,高并发下锁竞争会显著增加延迟。
🛠️ 四、解决方案与优化实践
✅ 1. 启用分布式缓存替代默认二级缓存
方案 | 实现方式 | 优势 |
---|---|---|
集成Redis | 配置<cache type="org.mybatis.caches.redis.RedisCache"> ,所有节点共享中央缓存。 |
数据全局一致,避免节点间不一致 |
Ehcache集群 | 通过Terracotta或RMI实现节点间缓存同步。 | 减少数据库压力,自动同步失效 |
✅ 2. 防御缓存异常
- 防穿透 :
- 对非法请求参数布隆过滤器(Bloom Filter)拦截,直接拒绝。
- 缓存空值(如
NULL
)并设置短过期时间(例:30秒)。
- 防雪崩 :
- 分散缓存过期时间(基础时间 + 随机偏移量)。
- 热点数据永不过期,通过异步线程刷新。
✅ 3. 降级兜底策略
- 熔断限流 :
当缓存服务宕机时,触发熔断机制(如Hystrix),请求直接降级到本地一级缓存或静态数据。 - 异步核对 :
定时任务比对缓存与数据库数据,修复不一致(如订单库存核对)。
💎 总结建议
📌 分布式环境下的缓存选择优先级 :
Redis集群 > Ehcache集群 > 关闭MyBatis二级缓存
- 强一致性场景:必须依赖Redis等分布式缓存;
- 高频更新数据:直接禁用缓存,改用数据库读写分离。
引用链接:
1.HoRain云--MyBatis一级缓存、二级缓存详解:正确理解缓存机制与实战应用 - HoRain 云助手
2.MyBatis之缓存避坑: MyBatis的一级缓存、二级缓存的实现分析与分布式环境下数据一致性问题 - 腾讯云
3.MyBatis缓存机制(一级/二级缓存失效场景) - 51CTO博客
6.MyBatis Plus整合Redis实现分布式二级缓存的问题 - 脚本之家
10.35. MyBatis中的缓存失效机制是如何工作的? - CSDN博客
12.Mybatis自定义分布式二级缓存实现与遇到的一些问题解决方案! - 博客园
13.详解mybatis的一二级缓存以及缓存失效原因 - CSDN博客
14.【字节Java二面】说说你对Mybatis中缓存机制的理解以及优缺点?面试必问,建议收藏! - 哔哩哔哩
15.mybatis详解,mybatis一级二级缓存机制,以及Ehcache & Redis对比 - CSDN博客
16.2025年大厂实战场景面试题精析(附真题拆解) - Java码农
17.mybatis缓存有哪几种 和redis 缓存有啥区别 mybatis有缓存为什么还要用redis - 51CTO博客
18.mybatis的缓存机制有哪些和Redis的缓存机制比有什么不同 mybatis缓存原理 - 51CTO博客
19.1.【Java面试】让人醍醐灌顶的回答,系统中应该如何使用分布式缓存? - 哔哩哔哩
20.缓存穿透、缓存击穿、缓存雪崩、热key问题怎么解决? - 艾小仙人
22.经典面试题,大厂几个巧妙的方案,复杂高并发系统缓存设计 - 哔哩哔哩
23.【春招预热】2025Java春招面试突击课(7天速成版)MySQL数据库、Redis、Spring全家桶、JVM,分布式微服务...一周刷完,金三银四一路狂飙 - 哔哩哔哩
24.mybatis 二级缓存失效_面试题:MyBatis二级缓存 - CSDN博客
25.浅析mybatis里的缓存机制 - 一级缓存、二级缓存、二级缓存多表查询的问题及解决、二级缓存分布式问题 - 博客园
26.CSDN中mapper.xml更新后,MyBatis缓存失效问题如何解决?_编程语言-CSDN问答 - CSDN问答
27.spring mybatis 缓存失效原因_51CTO博客 - 51CTO博客
28.解锁MyBatis 缓存:深入剖析原理与典型实现示例展示 - 跟我从零开始学编程
29.MyBatis缓存揭秘:两级并存 - 七安Melody会彤彤
31.关于MyBatis缓存你不知道的事 - 千锋Java学习站
33.Mybatis二级缓存 和 用mysql redis实现的缓存 有什么区别? - Java我写的
34.spring mybatis 缓存失效原因 mybatis缓存key - 51CTO博客
35.MyBatis知识汇总(第十篇)【详解】MyBatis的缓存机制,一级缓存+失效的3种情况,二级缓存,详解,实例,注意事项 - 51CTO博客
37.Mybatis 一级缓存,Mybatis 二级缓存,Mybatis 缓存失效 - 博客园