前面讲到mysql的缓存方案,把读压力放到了redis
正常情况下,两者配合工作完全没有问题
缓存穿透
假设某个数据redis不存在, mysql也不存在,⽽且⼀直尝试读怎么办?缓存穿透,数据最终压⼒
依然堆积在mysql,可能造成mysql不堪重负⽽崩溃;
解决
1. 发现mysql不存在,将redis设置为 <key, nil> 设置过期时间 下次访问key的时候 不再访问
mysql 容易造成redis缓存很多⽆效数据;
2. 布隆过滤器,将mysql当中已经存在的key,写⼊布隆过滤器,不存在的直接pass掉;
缓存击穿
缓存击穿 某些数据redis没有,但是mysql有;此时当⼤量这类数据的并发请求,同样造成mysql
过⼤;
解决
1. 加锁
请求数据的时候获取锁,如果获取成功,则操作,获取失败,则休眠⼀段时间(200ms)再去获
取;获取成功,则释放锁
⾸先读redis,不存在,读mysql,存在,写redis key的锁
整个流程⾛完,才让后⾯的服务器访问
2. 将很热的key,设置不过期
缓存雪崩
表示⼀段时间内,缓存集中失效(redis⽆ mysql 有),导致请求全部⾛mysql,有可能搞垮数据库,
使整个服务失效;
解决
1. 如果因为缓存数据库宕机,造成所有数据涌向mysql;
采⽤⾼可⽤的集群⽅案,如哨兵模式、 cluster模式;
2. 如果因为设置了相同的过期时间,造成缓存集中失效;
设置随机过期值或者其他机制错开失效;
3. 如果因为系统重启的时候,造成缓存数据消失;
重启时间短, redis开启持久化(过期信息也会持久化)就⾏了; 重启时间⻓提前将热数据导
⼊redis当中;
本文探讨了数据库与缓存配合使用时可能出现的问题,包括缓存穿透、缓存击穿和缓存雪崩,并提出了相应的解决方案。缓存穿透可通过设置Redis中不存在数据的过期时间或使用布隆过滤器来避免无效请求。缓存击穿则可以采用加锁机制或确保热数据不过期来缓解。缓存雪崩可以通过采用高可用的Redis集群、设置随机过期时间或重启前预加载热数据来防止。这些策略有助于确保系统的稳定性和性能。
1659

被折叠的 条评论
为什么被折叠?



