13- Redis和Mysql如何保证数据⼀致?
-
先更新Mysql,再更新Redis,如果更新Redis失败,可能仍然不⼀致
-
先删除Redis缓存数据,再更新Mysql,再次查询的时候在将数据添加到缓存中
这种⽅案能解决1 ⽅案的问题,但是在⾼并发下性能较低,⽽且仍然会出现数据不⼀致的问题, ⽐如线程1删除了 Redis缓存数据,正在更新Mysql, 此时另外⼀个查询再查询,那么就会把Mysql中⽼数据⼜查到 Redis中
- 使用MQ异步同步, 保证数据的最终一致性
我们项目中会根据业务情况 , 使用不同的方案来解决Redis和Mysql的一致性问题 :
-
对于一些一致性要求不高的场景 , 不做处理
例如 : 用户行为数据 , 我们没有做一致性保证 , 因为就算不一致产生的影响也很小
-
对于时效性数据 , 设置过期时间
例如 : 接口缓存数据 , 我们会设置缓存的过期时间为 60S , 那么可能会出现60S之内的数据不一致, 60S后缓存过期, 重新从数据库加载就一致了
-
对于一致性要求比较高但是时效性要求不那么高的场景 , 使用MQ不断发送消息完成数据同步直到成功为止
例如 : 首页广告数据 , 首页推荐数据
数据库数据发生修改----> 发送消息到MQ -----> 接收消息更新缓存
消息不丢失/重复消费 : 消息状态表/消息消费表
-
对于一致性和时效性要求都比较高的场景 , 使用分布式事务 , Seata的TCC模式
很少用
14- 什么是缓存穿透 ? 怎么解决 ?
缓存穿透是指查询一条数据库和缓存都没有的一条数据,就会一直查询数据库,对数据库的访问压力就会增大,缓存穿透的解决方案
有以下2种解决方案 :
-
缓存空对象:代码维护较简单,但是效果不好。
-
布隆过滤器:代码维护复杂,效果很好
15- 什么是缓存击穿 ? 怎么解决 ?
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大
解决方案 :
-
热点数据提前预热
-
设置热点数据永远不过期。
-
加锁 , 限流
16- 什么是缓存雪崩 ? 怎么解决 ?
缓存雪崩/缓存失效 指的是大量的缓存在同一时间失效,大量请求落到数据库 导致数据库瞬间压力飙升。
造成这种现象的 原因是,key的过期时间都设置成一样了。
解决方案是,key的过期时间引入随机因素
17- 数据库有1000万数据 ,Redis只能缓存20w数据, 如何保证Redis中的数据都是热点数据 ?
配置Redis的内容淘汰策略为LFU算法 , 这样会把使用频率较低的数据淘汰掉 , 留下的数据都是热点数据