一:正常缓存流程
https://www.bilibili.com/video/BV1sK4y1x749?p=16&spm_id_from=pageDriver
二:雪崩(直接连接数据库,如双十一)
解决方案:
1.缓存数据的过期时间设置随机数,防止统一时间,大量数据失效;
2.定时任务同步缓存;
3.给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,如果缓存标记失效,则更新缓存;
4.缓存预热,启动服务之前,调接口缓存热点key数据;
5.加互斥锁,(本质就是请求排队查数据库,查数据key锁起来,缓存后,释放锁,防止大量对同一个key查询数据库)
三:穿透(redis与mysql均无,如攻击)
现象:恶意请求:redis不能存储id<0的数据,不断有id=-1请求,redis没有再请求mysql,都没有返回null
如:工作人员将数据从mysql 以及 redis全部删除,客户请求时,缓存以及数据库没有数据;
解决方案:
- 从接口层做校验(从业务的角度判断,某一类数据不会存在进行拦截)
2.缓存抗暴击: 如果redis 与 mysql 中数据均查询不到,此时也可以新增key-null,或者空字符串,同时做缓存(缓存时间短一点,如30s,设置太长导致正常情况无法使用,设置缓存时间是防止黑客采用不同不存在的值不断的请求,避免出现直接大量访问数据库),防止使用同一个id暴力攻击; - 布隆过滤器(将所有可能存在的哈希存储到bitmap中,不存在的数据一定会被bitmap 过滤掉)
四:击穿(缓存失效,redis突然key失效,链接数据库,常见在极端环境下出现)
现象:不断打热点key,key突然失效,直接请求到mysql;
解决方案:
- 设置热点key永不过期;或者key添加随机时间失效;
- 加互斥锁,(本质就是请求排队查数据库,查数据key锁起来,缓存后,释放锁,防止大量对同一个key查询数据库)
五:突发性热点缓存重建导致压力暴增
如直播间卖的平常冷门商品,大量用户请求
解决方案:
- 添加分布式锁;
六:双写不一致问题,脏数据问题
现象:
线程A 查询redis中key无 ==》mysql查询为10 ==> 线程B更新数据库key值为6 ==》线程b同步缓存为6 ==》线程a此时更新缓存为10;
实际数据库为10,缓存为6;
解决方案:分布式锁;
对同一个数据进行操作,会出现双写不一致;
分布式锁本质查询key存在表示已锁,需要释放后再进行加锁操作,不会出现同时操作的情况;
七:redis集群
主从:当一台服务宕机的时候,此服务则不可用;(缺点)特别是当主服务器宕机时,从服务只可读不可写;
哨兵模式:和主从相比,当主服务宕机时,监控到后会推荐一个从服务作为主服务;
分片集群:集群里面的数据分别存储各个节点,每个节点都是主从;
八:redis底层原理实现
redis键的过期删除策略
- 惰性过期:只有访问一个key时,才会查询是否过期,过期则清除;(节省CPU资源,内存不友好,可能存在大量key没有被访问,占用内存)
- 定期过期:每隔一定时间,会扫描一定数量的key,清除过期的key,(折中,CPU和内容资源达到最优)
- 定时过期:设置每个key定时过期时间;
redis 中同时存在 惰性过期 与 定期过期;
六:redis是单线程,但是快的原因?
七:
九:redis 同步数据
redis持久化方案