缓存一致性解决方案——改数据时如何保证缓存和数据库中数据的一致性

网友投稿 984 2022-11-21

缓存一致性解决方案——改数据时如何保证缓存和数据库中数据的一致性

缓存一致性解决方案——改数据时如何保证缓存和数据库中数据的一致性

文章目录

​​写在前面​​​​缓存数据一致性的方式​​

​​双写模式​​

​​弊端​​

​​失效模式​​

​​弊端​​

​​分析​​

​​总结​​​​我们通常用的方式​​​​拓展:使用canal订阅binlog​​

写在前面

我们都知道,缓存是为了提高数据的读取速度的,应对的场景是读多写少的场景。

读数据我们通常先读缓存,如果缓存没有再读数据库然后更新缓存。​​​从查询数据库性能优化谈到redis缓存-谈一谈缓存的穿透、雪崩、击穿​​

当缓存的数据需要修改的时候,既要修改缓存,又要修改数据库,如何保证缓存和数据库中的数据是一致的呢?

缓存数据一致性的方式

双写模式

弊端

高并发下,由于卡顿等原因,导致写缓存2在最前,写缓存1在后面,就导致了缓存与数据库数据不一致的情况,也就是出现了脏数据。

但是,这种脏数据只是暂时的,取决于缓存的过期时间,当缓存过期以后,再次读取数据库就又会得到最新的正确数据。也就是说,最新的数据是有可能会有一定的延迟,但是最终结果是一致的。

失效模式

弊端

高并发读写情况下,写db2的删缓存执行在了读db1的更新缓存的前面,就会造成缓存与数据库的不一致,也就是出现了脏数据。

但是,这种脏数据只是暂时的,取决于缓存的过期时间,当缓存过期以后,再次读取数据库就又会得到最新的正确数据。也就是说,最新的数据是有可能会有一定的延迟,但是最终结果是一致的。

分析

无论是双写模式还是失效模式,都会导致缓存的不一致问题。即多个实例(数据库、缓存)同时更新会造成脏数据。怎么办?

总结

1、我们能放入缓存的数据本就不应该是实时性、一致性要求超高的。所以缓存数据的时候加上过期时间,保证每天或者一段时间后拿到当前最新数据即可。 2、我们不应该过度设计,增加系统的复杂性,对于分布式锁,能不加就不加;对于缓存的脏数据,能容忍一段时间的脏数据那就不需要处理,否则系统过重维护起来会很麻烦。 3、遇到实时性、一致性要求高的数据,并且写场景比较多的话,就应该查数据库,即使慢点。 4、读多写少的场景下,又对数据一致性要求比较高的话,可以通过加锁保证并发读写,写写的时候按顺序排好队。读读无所谓。所以适合使用读写锁。 5、使用canal订阅binlog的方式可以解决数据一致性问题,但是又引入了新的中间件。

我们通常用的方式

1、缓存的所有数据都加过期时间,数据过期下一次查询触发主动更新。 2、读写数据的时候,加上分布式的读写锁。

拓展:使用canal订阅binlog

binlog是mysql的二进制日志,对于操作数据库的语句,都以此形式保存。Canal是阿里MySQL数据库Binlog的增量订阅&消费组件 。基于数据库Binlog可以监控数据库数据的变化进而用于数据同步等业务。

该方式引入了新的中间件,使系统更加复杂化。但是完美确保了缓存一致性,通常只需要维护一次,后续不需要单独维护。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:教你快速学会JPA中所有findBy语法规则
下一篇:Spring学习(1) 初识Spring
相关文章

 发表评论

暂时没有评论,来抢沙发吧~