缓存穿透
如果请求查询的数据,在缓存中查不到,会将请求打到下游数据库上,这就是缓存穿透。如果有人恶意并发访问数据库中不存在数据(比如id=-1),就可能会导致数据库因扛不住较大流量而导致系统宕机。
解决方案
缓存空对象
当请求数据没有命中redis缓存时,请求会打到mysql上,如果mysql也不存在该数据,则缓存一个空对象到redis中。
但是这种解决方案会有两个问题:
1.如果数据库中真的插入了该条数据,然后没有同步到redis,这时候redis还是缓存了一个空对象。这样就会存在redis与数据库的数据不一致问题。针对该问题,我们可以对这种数据设置一个较短的过期时间,保证数据库和redis的弱一致性。
2.假设黑客攻击,随机生成大量非法数据高并发访问系统,首先这些非法数据会穿过redis访问数据库增加数据库压力,同时redis还会缓存大量的值为空的key,不仅耗费大量内存资源还会导致redis将缓存中有价值数据给淘汰掉。
布隆过滤器
Bloom Filter是一个占用空间很小、效率很高的随机数据结构,它由一个bit数组和一组Hash算法构成。可用于判断一个元素是否在一个集合中。
缓存击穿
缓存击穿是缓存穿透的一种特殊体现。
当某个数据被高并发访问时,如果这个数据redis的key的突然失效,会导致这些请求同一时间打到数据库,数据库扛不住就会导致系统瘫痪。
解决方案
热点数据不过期
不设置过期时间
但是当数据库数据发生变化,缓存没有变会导致数据不一致的问题。所以当数据库数据发生变化时需要同步更新redis。可以通过相关的中间件监控mysql的binlog日志并更新redis。
加锁
查询数据库并重新写入缓存加分布式锁,防止并发访问数据库。
缓存雪崩
缓存雪崩是多个热点key同时失效。
缓存雪崩原因:
- 缓存过期的时间比较一致,某一时刻key大面积失效。
- redis宕机或者网络问题访问不到redis。
解决方案
缓存时间随机
设置随机的失效时间。
在设置数据缓存有效期时,在时间后加上一个随机因子。
热点数据不过期
不设置过期时间
redis集群
防止redis宕机,可采用redis集群实现高可用。