Redis 分布式缓存实现(一)
1. 什么是缓存(Cache)
定义:就是计算机内存中的一段数据;
2. 内存中数据特点
a. 读写快 b. 断电立即丢失
3. 缓存解决了什么问题?
a. 提高网站吞吐量,提高网站运行效率;
b. 核心解决问题:缓存的存在是用来减轻数据库访问压力;
4. 既然缓存能提高效率,那项目中所有数据加入缓存岂不是更好?
注意:使用缓存时一定是数据库中数据极少发生修改,更多用于查询这种情况 例如:省份 城市 县 村
5. 本地缓存和分布式缓存的区别
本地缓存:存储在当前应用服务器内存中的数据称之为本地缓存(local cache)
分布式缓存:存储在当前应用服务器内存之外的数据称之为分布式缓存(distribute cache)
集群:将同一种服务的多个节点放在一起,共同对系统提供服务的过程称之为集群(cluster)
分布式:有多个不同服务集群共同对系统提供服务的这个系统称之为分布式系统(distribute system)
6. 利用 MyBatis 自身本地缓存结合 Redis 实现分布式缓存
a. MyBatis 中应用级缓存(二级缓存)SqlSessionFactory 级别缓存,所有会话共享同一个 namespace
b. 如何开启(二级缓存)
在对应模块的Mapper.xml文件中开启二级缓存,例如:UserMapper.xml
<cache/> ---- 本地缓存
c. 查看 Cache 标签缓存实现
结论:MyBatis底层默认使用的是:org.apache.ibatis.cache.impl.PerpetualCache 实现【底层就是一个 Map 数据结构存储】
d. 自定义 RedisCache 实现,替换默认的 PerpetualCache
(1)通过 MyBatis 默认 Cache 源码得知,可以只用自定义 Cache 接口的实现类 implements Cache 接口,并对里面的方法进行实现
public class RedisCache implements Cache { }
(2)在指定 Mapper 对应的 namespace 中开启二级缓存
<cache type="com.study.cache.RedisCache"/>
Redis 分布式缓存实现(二)
1. 缓存在项目中应用
a. 如果项目中表查询之间没有任何关联查询时,使用现在的这种缓存方式没有任何问题,比如:只是使用单表查询;
b. 现有缓存方式在表连接查询过程中一定存在问题;比如:Depart 部门中有 多个 User 用户,Depart { List<User> users; }
2. 在 MyBatis 的缓存中如何要解决关联关系时更新缓存信息的问题【可参考文档:MyBatis 一级缓存和二级缓存 MyBatis 缓存 Cache】
<cache-ref /> 用来将多个有关联关系查询缓存放在一起处理;
在 UserMapper.xml 文件中加入以下内容:
<cache-ref namespace="com.study.mapper.DepartMapper"/>
(1)关联关系缓存处理【用来将两个关联关系查询的结果缓存放在一起处理】
(2)存在关联关系的多个模块中,只要有一个模块更新,就应该把有关联的模块缓存都清空,否则会出现脏数据情况;
(3)此时不能使用<cache type=""/> 【只适合单模块的缓存】 要使用 <cache-ref namespace=""> 标签; <cache-ref namespace=""/> 当前模块的缓存去引用其他模块的缓存【用户模块的查询缓存放入部门模块的查询缓存中】
由于用户和部门关联,共享缓存,首先两模块的查询缓存放在一起 DepartMapper 下,无论用户或者部门做增删改,都会将 departMapper 下的缓存清空,进而关联的用户缓存也一并清空;
Redis 分布式缓存实现(三)
1. 缓存优化策略
a. 对放入 Redis 中 Key 进行优化:Key 的长度不能太长;
b. 尽可能将 Key 设计简洁一些:
算法:MD5处理 加密
特点:(1)一切文件字符字符串等经过MD5加密处理后,都会生成32位16进制字符串;(2)不同内容文件经过MD5进行加密,加密结果一定不一致;
(3)相同内容文件多次经过MD5加密生成的结果始终一致;
推荐:在 Redis 整合 SpringBoot 过程中建议将 Key 进行 MD5 加密优化处理;
2. 面试相关概念
a. 什么是缓存穿透 击穿
定义:客户端查询了一个数据库中没有的数据记录,导致缓存在这种情况下无法使用,称之为缓存穿透 缓存击穿
MyBatis 中 Cache 解决了缓存穿透问题:将数据库中没有查询到的结果也进行缓存
b. 什么是缓存雪崩
定义:在系统运行的某一时刻,突然系统中缓存全部失效,恰好在这一时刻涌来大量客户的请求,导致所有模块缓存无法使用,大量请求涌向数据库导致极端情况,数据库阻塞获取挂起;
缓存存储时:业务系统非常大,模块多,业务数据不同,不同模块在放入缓存时,都会设置一个缓存超时时间;
解决方案:1. 缓存永久存储(不推荐) 2. 针对于不同业务数据一定要设置不同超时时间,避免同一时刻 或者 一极短时间内大量缓存失效。
目前只展示相关概念,代码实现没有展示出来,有问题大家一块讨论哈!