百万级抽奖系统(redis的延时双删)
笔记链接:https://www.bilibili.com/read/cv15241402?from=note
视频链接:https://www.bilibili.com/video/BV1t5411o7yn
延时双删的博客地址:https://blog.csdn.net/qq_35890572/article/details/108538712
【面试】太卷了!大厂面试考健康码!如何结合八股文讲好思路?
mysql数据更新,需要删除同步redis的旧数据,就需要考虑使用延时双删(更新数据前删一次缓存,更新数据后延时一段时间再删一次缓存,让访问旧数据的线程执行结束,这样删除缓存后再次命中就更新的是新数据)
数据库与缓存的数据一致性问题分析
mysql和redis的三个情况
更新时会存在四种情况,对其分析缓存一致性问题
1: 换更新缓存,再更新数据库
很笨的做法,如果更新数据库失败了,就需要回滚,回滚后需要回滚缓存,如果之前更新的数据是经过大量计算得到的那么这些计算就白算了,因为数据库持久化更好,更好回滚,而且存储以数据库为中心,所以应该先去更新数据库。
2:先更新数据库,再更新缓存
会导致更新的数据被拿到之前数据还没写redis的线程覆盖掉。
3:先删缓存,再更新数据库
存在缓存不一致问题
4:先更新数据库,再删缓存
旧数据被拿到,更新后写入redis,概率低,因为更新时间大于写的时间。
可以删除缓存操作延时一段时间
大数据库读写分离
同步出现问题,会导致获取到旧数据
更新架构
直接去主mysql的日志拿数据变更到redis,可以使canel,存在更新缓存失败问题。从mysql相当于备份了。
引入mq,mq可以保证更新数据有序,不会乱,还能保证不丢失,消费不成功可以重复消费,redis采用单线程订阅保证有序性,但是mq也有崩溃的存在,对于强一致性的场景就需要考虑整个流程加事物了,这个只是满足最终一致性。