缓存使用场景的理解

      我们先来看一个互联网的应用场景,一个电子商务网站里面有N多的商品,而商品是不会频繁更改而读取频率又是很高的数据,如果按普通的业务架构的话,就是程序直连DB,但是DB的QPS和TPS因为ACID的限制,在虚拟容器下(例vmware,kvm)的吞吐量基本就是5000左右,在硬件环境下,根根据配置的高低,基本就是1W左右,而在一个每天有亿次pv的网站,切不说在限时促销、折扣的高并发场景下,就是普通时间段,热销的产品的访问量也是极高的,这不仅是对DB持续的压力(因为DB还要接受其他的请求),而且还是数据的重复访问效率极低。所以,对于这种场景下的数据读取,现在流行的做法就是将这些数据(商品的信息)存放在缓存里。在这里,我们遇到一个问题,缓存怎么用?


       我们先解释下缓存, 顾名思义,就是数据暂存的地方,你可以理解为从磁盘里取出来数据,暂时存放在内存,以待后面处理来读取。而能存放在缓存的数据,通常是频繁访问的,不会经常修改的数据。知道了什么是缓存,什么数据可以放缓存,就可以寻找合适的缓存(这里说的缓存,就是对象或者容器了)。


       目前,缓存的操作主要是两种方式,一种是使用程序自带的
map对象(像jdk的hashmap),一种是缓存软件,第一种不细说,大家可以看看hashmap的实现和应用,这里主要说缓存软件。现在流行的缓存软件是memcached、redis(如果有不了解的,google),有的博客还说到mongodb。个人认为,因为要兼顾DB的某些特性,所以做不到其他两个缓存的为了实现极高的吞吐量而采用的epoll 或 libevent事件驱动的方案,所以这里排除。下面所说的缓存,就指的是第二种。


       下面我们来看看怎么用缓存,缓存通常是单独一个服务器上的一个实例、一个虚拟机上的实例、或者多个实例,当然,你也可以在多台服务器上部署1个或者多个缓存,这就得看你的缓存的访问量了。最常见的缓存架构如下图

           服务器端写数据时,同时更新redis和mysql,读的话,如果缓存有数据,就从缓存里取,如果没有,就从mysql里取。

        还在上班,之后继续补充。。

<think>好的,我现在需要回答用户关于MyBatis一级缓存和二级缓存使用场景、区别和适用情况的问题。首先,我需要回顾一下MyBatis的缓存机制,确保自己的理解正确。 根据用户提供的引用资料,一级缓存是默认开启的,作用域是SqlSession级别的。而二级缓存需要手动配置,作用域是Mapper级别的,可以被多个SqlSession共享。不过,用户提到了一些关键点,比如一级缓存在Spring Boot中默认可能无效,需要事务支持才能生效,而二级缓存在分布式环境下可能会有脏读问题,建议使用Redis等外部缓存来解决。 接下来,我需要整理两者的区别,包括作用域、存储结构、开启方式、失效机制和应用场景。比如,一级缓存的哈希表结构存储SQL语句和结果,而二级缓存是双向链表。同时,一级缓存在同一SqlSession内有效,而二级缓存跨SqlSession。用户可能关心它们的性能影响和适用情况,比如高并发或分布式环境下如何选择。 还要注意引用中的细节,比如一级缓存在Spring Boot中的问题,需要事务支持,否则可能因为每次使用不同的SqlSession而失效。此外,二级缓存的脏读问题在分布式系统中更明显,需要第三方缓存解决方案,如Redis。这些点都需要在回答中明确说明。 最后,生成相关问题时要围绕用户可能进一步询问的方向,比如性能调优、脏读处理、配置步骤、与第三方整合以及适用场景对比等。确保问题能够引导用户深入理解MyBatis缓存机制。</think>### MyBatis 一级缓存与二级缓存的对比分析 #### 一、核心区别 | **特性** | **一级缓存** | **二级缓存** | |------------------|--------------------------------------------|--------------------------------------------| | **作用域** | SqlSession 级别(默认开启) | Mapper/Namespace 级别(需手动配置) | | **存储结构** | 哈希表(键为 SQL 语句,值为结果)[^3] | 双向链表(节点包含 SQL 语句和结果) | | **开启方式** | 默认开启(可通过配置关闭) | 需在映射文件中添加 `<cache/>` 标签开启 | | **失效机制** | 执行更新操作或关闭 SqlSession 时失效 | 执行更新操作或配置超时时间后失效 | | **适用场景** | 单次请求内重复查询优化 | 跨请求的共享查询优化 | --- #### 二、使用场景与注意事项 1. **一级缓存** - **适用场景** 适用于短时间内同一 SqlSession 内重复执行相同 SQL 的查询,例如事务中的多次相同查询。 - **典型问题** - 在 Spring Boot 中默认无效(需开启事务才能生效)[^4] - 易产生脏读(无法感知其他 SqlSession 的更新)[^4] - 建议设置为 `STATEMENT` 级别关闭,避免数据不一致 2. **二级缓存** - **适用场景** 适用于跨 SqlSession 的频繁查询且数据更新较少的场景(如配置表、静态数据)。 - **典型问题** - 分布式部署时本地缓存导致脏读(需用 Redis 等第三方缓存替换)[^2] - 多表关联查询需配置 `<cache-ref>` 实现缓存共享 - 需注意缓存淘汰策略(如 LRU、FIFO)和序列化问题 --- #### 三、生产环境建议 1. **单机应用** - 关闭一级缓存(设为 `STATEMENT`) - 选择性开启二级缓存(仅对低频更新数据生效) 2. **分布式应用** - 禁用默认二级缓存,改用 Redis 等分布式缓存 - 结合注解 `@CacheNamespace` 实现细粒度控制 --- #### 四、配置示例(二级缓存 + Redis) ```xml <!-- Mapper.xml 中启用 Redis 缓存 --> <cache type="org.mybatis.caches.redis.RedisCache"/> ``` ```properties # redis.properties host=localhost port=6379 ``` 需引入依赖: ```xml <dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-redis</artifactId> <version>1.0.0-beta2</version> </dependency> ``` --- §§ 1. MyBatis 如何通过 Redis 实现分布式二级缓存? 2. 为什么 Spring Boot 中一级缓存默认无效?如何修复? 3. 多表联查时如何配置二级缓存避免脏数据? 4. MyBatis 缓存与 Spring Cache 整合的优缺点是什么? 5. 如何监控 MyBatis 缓存命中率以进行性能调优?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值