一、缓存穿透问题
(一)什么是缓存穿透?
缓存穿透就是指在访问数据时,缓存中没有,数据库中也没有,感觉就像是穿透了缓存层,直接就到达数据库。
(二)如何解决缓存穿透?
- 再查看一个不存在的数据时,给一个设置,一定会查到的数据;意思就是在第一次查询的时候,发现该数据数据库和缓存中都没有的话,会生成一个可以查到的空数据返回,以防缓存穿透。
- 使用布隆过滤器 ↓↓↓↓↓↓
(三)什么是布隆过滤器?
-
布隆过滤器就是先把缓存中的数据存入到布隆过滤器中:
- 通过布隆过滤器提供的多个Hash函数来对key进行Hash运算,然后对位数组长度进行取余,这样就会得到一个下标,将该下标的值设置成1。
-
在进行查询数据时,会先将数据按照数据存储redis到布隆过滤器的方法进行运算,然后去判断key是否在布隆过滤器中。根据需要查询的数据在布隆过滤中的key的值来判断是否包含该数据:
-
如果位数组对应下标的key的值只要有一个为0,就说明该数据不存在,就返回。
-
如果位数组对应下标的key的值全部为1,就说明该数据可能会存在。
因为可能会存在查询数据的所有位数组下标对应的key值都为1,但这些key不一定是同一个数据对应的key,可能是a的一个key+b的一个key组成。所以说是可能存在。
-
二、缓存击穿问题
(一)什么是缓存击穿?
缓存击穿就是指当一个热点数据在缓存中过期,导致大量请求直接到达数据库
(二)如何解决缓存击穿?
- 设置热点数据缓存永不过期
- 设置定时任务,每天设置一个时间定时更新(先删除原来的缓存数据,在进行查询数据,存入缓存)
- 设置降级限流操作
- 分布式锁
- 在分布式环境下,传统锁会失效,因为传统锁是基于JVM的
- 基于临时序号节点+监听机制
- 因为项目本身就有了Redis,虽然性能不如ZK,但是我不用ZK,就不需要动项目的整体架构,而我们的项目用Redisson实现分布式锁对性能没有那么强的要求。
三、缓存雪崩问题
(一)什么是缓存雪崩?
缓存中在同一个时间点有大量的key同时过期,请求查询缓存中没有,直达数据库
(二)如何解决缓存雪崩?
- 分布式锁
- 热点数据永不过期
- key随机过期时间
四、缓存数据不一致问题
1、弱一致【最终一致性】
- 先更新数据库,再删除缓存
- 在更新数据库之后,删除缓存之前,虽然会有短暂的不一致情况,但是最终会一致的
- 会最终保证数据的一致性
- 基于mysql binlog 日志进行异步更新缓存
- canal
- 克奈哦
- 可以监听binlog日志
- MQ
- canal
2、强一致
-
加分布式锁
-
把 更新数据库,再删除缓存 的操作当成一个原子性操作,给这个操作加锁——性能较差
-