使用缓存,可以有效缓解系统大流量压力,显著提升系统性能,降低数据库的频繁读写压力,Redis 在作为缓存服务使用时,以下问题是必须要考虑到的,如:缓存穿透,缓存击穿,缓存雪崩等。
缓存穿透
出现场景:
-
我们在使用缓存时,常常会先在缓存中取值,如果没有,再去数据库中查询,当数据库中不存在时,根据业务需求返回
-
这样,系统每次都会先访问缓存,再查询数据库,每次请求都会读取数据库,造成数据库较大的压力,就达不到缓存的目的,这种情况就是
缓存穿透
解决方案:
- 对于数据库中查询不存在的数据,在
redis
中将对应的key
保存为null
,之后查询就直接返回redis
中的值,同时设置较短的过期时间,比如:30s
,防止数据库中该条数据更新后查询不到该数据 - 使用
布隆过滤器
利用高效的数据结构和算法快速判断key
是否在数据库中
缓存击穿
出现场景
- 对于一个热点
key
,在不停的扛着大量的请求,大量请求集中访问该热点key
,当这个key
在失效的瞬间,持续的大量请求就会穿破缓存,直接访问数据库,瞬间导致数据库压力上升,甚至直接宕机
解决方案
- 对于这种频繁访问的热点
key
可以设置永不过期,这样,就可以防止索引失效而带来的问题 - 使用互斥锁,在缓存失效的时候,不是立即去数据库访问数据,而是利用缓存工具某些带返回值的操作,如
setnx
先设置一个互斥锁,当操作成功后从数据库加载数据并缓存数据,否则就重试取缓存的操作
缓存雪崩
出现场景
- 缓存击穿是单个热点
key
突然失效带来的问题,而缓存雪崩就是大量的热点key
在同一时间失效,大量的请求直接访问数据库,导致数据库无法承受而宕机
解决方案
- 把每个热点
key
的失效时间加上随机数,保证缓存数据不会在同一间大量失效 - 使用互斥锁
(如有错误,欢迎指正)