躺着敲代码第一天-----聊聊缓存穿透的解决思路^^
缓存穿透的定义
- 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库,导致数据库压力加剧。
常见的两种解决方法
缓存空对象思路分析:
- 当我们客户端访问不存在的数据时,先请求Redis,但是此时Redis中没有数据,此时会访问到数据库,但是数据库中也没有数据,这个数据穿透了缓存,直击数据库,我们都知道数据库能够承载的并发不如Redis这么高,如果大量的请求同时过来访问这种不存在的数据,这些请求就都会访问到数据库,简单的解决方案就是哪怕这个数据在数据库中也不存在,我们也把这个数据存入到Redis中去,这样,下次用户过来访问这个不存在的数据,那么在Redis中也能找到这个数据就不会进入到缓存了
布隆过滤:
- 布隆过滤器其实采用的是哈希思想来解决这个问题,通过一个庞大的二进制数组,走哈希思想去判断当前这个要查询的这个数据是否存在,如果布隆过滤器判断存在,则放行,这个请求会去访问Redis,哪怕此时Redis中的数据过期了,但是数据库中一定存在这个数据,在数据库中查询出来这个数据后,再将其放入到Redis中,
假设布隆过滤器判断这个数据不存在,则直接返回
这种方式优点在于节约内存空间,存在误判,误判原因在于:布隆过滤器走的是哈希思想,只要哈希思想,就可能存在哈希冲突
两种方法的优缺点分析
-
缓存空对象
- 优点:实现简单,维护方便(只需要在Redis中将得到不存在的数据的请求也存储在Redis)
- 缺点:
- 额外的内存消耗(需要Redis额外存储一些没有实际意义的请求)
- 可能造成短期的不一致( 缓存的空对象存在有效期--------当系统检测到某个键不存在(例如数据库中没有对应的数据),为了防止重复查询数据库,会将一个“空对象”缓存到 Redis 中,并设置一个较短的过期时间。
如果在这个空对象的有效期内,数据库中的数据发生变化(例如插入了新的记录),但缓存还未过期,客户端会继续从缓存中获取到空对象,导致返回的结果与实际数据不一致。
示例:
数据库:原本 key1 不存在,后来插入了值 value1。
Redis:缓存了 key1 的空对象,有效期为 5 分钟。
在空对象的有效期内,客户端仍然会从缓存中获取到“空值”,而不是最新的 value1。)
-
布隆过滤
- 优点:Redis内存占用较少,没有多余key
- 缺点:
- 实现复杂(需要一个尽可能优秀的哈希算法(哈希冲突尽量少))
- 存在误判可能(hash算法会出现哈希冲突)
来源参考:黑马程序员Redis实战篇