每日一题
redis 缓存雪崩、缓存穿透、缓存击穿
Redis 是一个内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。用redis作为告诉缓存时可能出现缓存雪崩、缓存穿透、缓存击穿这三种情况,以下对这三种情况以个人理解做一下总结,欢迎大佬指教
缓存雪崩
缓存雪崩,顾名思义缓存全部失效了,缓存雪崩大多发生在者两种情况下
- redis 或 服务 刚刚启动redis中还没有缓存(缓存冷启动),如果这时 有大量请求打在数据库服务上,就会造成数据的宕机
这种情况下 一般有两种解决方案- 数据持久化:数据通过 RDB或者AOF 的方式持久化,在redis启动从硬盘中加载数据到内存
- 缓存预热: 缓存预热就是系统上线后,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!
- 业务量剧增,导致redis宕机了,请求全部打在数据库上,导致数据库宕机,同时重新启动数据库请求没降下来也会继续宕机
解决方案- 事前:redis 服务高可用配置
- 事中:使用限流,并且降级方式防止数据库被打死 牺牲部分用户的可用性,保证系统存活
- 事后:redis持久化
缓存穿透
大量请求一直访问不存在的 key 导致请求全部搭载数据库上
比如:黑客恶意攻击,查询id 等于 -1 的数据,大量请求打到数据库上造成数据库当局不可用
解决方案
- 当数据库中查不到数据,写一个空值到redis,并设置过期时间,下次有相同的key访问redis,在缓存失效前都可以在缓存中取数据
缓存击穿
某个key访问非常频繁,在这个key在失效的瞬间大量请求就击穿了缓存,直接请求到数据库
解决方案
- 若缓存的数据基本不会变更,可以设置key永不过期
- 若缓存的数据更新不频繁 ,可以通过互斥锁机制,(使用 redis 或者 zookeeper 等分布式锁中间价)在缓存失效时以保证少量请求请求到数据库
- 若缓存的数据更新频繁或者缓存刷新流程比较慢的情况下,可以使用定时任务,在缓存过期前构建缓存,或者延长过期时间