👏作者简介:大家好,我是爱写博客的嗯哼,爱好Java的小菜坤
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
📝个人博客:敬请期待
📕系列专栏:Redis
前言
在项目使用Redis过程中,当数据更新时,我们要保证缓存和数据库的一致性,否则会导致很多脏数据出现。此时我们就要思考如何去进行数据更新。
一、普通删除
在数据更新过程中,大家无非使用两种方法进行缓存和数据库的更新
- 先删除缓存,再更新数据库
- 先更新数据库,再更新缓存
那这两种方法究竟有什么不同呢?
1. 先删除缓存
-
问题:此时缓存有了旧数据,在下次修改此数据之前,所有请求获取的都是旧数据,导致读写不一致
2. 后删除缓存
-
问题1:在小明修改数据库到删除缓存这段时间,所有请求都是旧数据
-
问题2:如果缓存删除失败,后续所有请求都是旧数据(这个问题开启事务的话,就可以解决)
二、双删策略
在普通删除策略中,大家会发现后删缓存策略是比较好的一种,但还是存在一点问题,所以提出了双删策略
关于这个地方我是存在疑问的,因为我认为双删并不会比后删缓存策略更好,反而增加了一次数据库查询的操作。但有的博客却提了这个策略,我就在这里提一下,大家可以在评论进行交流
1. 普通双删
-
问题:因为线程调度一些问题导致查询后写入缓存停止,会导致旧缓存依旧存在
2. 延迟双删
这样的话看似把普通双删的问题给解决了,但并没有完全解决,反而引发新的问题。
-
问题:延时时长问题,时间太长导致性能下降,时间太短又会跟普通双删一样
三、读写锁
读写锁根据字面意思就知道是加锁,因此效率肯定比不加锁效率低,但是可以完全避免旧数据读取的发生。
- 读写锁是读读共享,读写和写写互斥的
四、异步通知
1. 消息中间件异步通知
- 对于这个博主认为是把延迟双删的延迟给优化了,不再占用本线程的时间,只不过部分请求会导致旧数据。
2.Canal
关于Canal,大家可以看这篇文章:Canal原理架构应用场景
Canal是一个开源的数据库数据增量订阅和消费组件,用于实时捕获数据库的变更并将其传递给其他系统。具体而言,Canal主要用于解决数据库之间的数据同步和实时数据分析需求。
Canal支持对MySQL、Oracle等主流数据库进行增量数据订阅和消费。它通过解析数据库的日志(如MySQL的binlog或Oracle的redo log),实时捕获数据库的变更操作,然后将变更数据以事件的形式发送给订阅者。可以将这些变更数据用于数据同步、实时数据仓库、搜索引擎索引更新、缓存更新等应用场景。
Canal的主要特性包括:
- .数据库无侵入:Canal通过解析数据库日志来捕获数据变更,不需要对数据库进行任何修改,不会对数据库的性能产生影响。
- 实时的增量数据:Canal能够几乎实时地捕获到数据库的变更操作,并以事件的形式进行传递,保证了数据的实时性。
- 灵活的订阅和过滤:Canal支持基于数据库、表、列级别的订阅和过滤,可以按需选择需要同步的数据,减少数据传输和处理的压力。
- 多种协议支持:Canal支持多种数据传输协议,如基于TCP的简单文本协议、Kafka、RocketMQ等,可以根据具体需求选择适合的协议进行数据传输。
- 高可用和容错:Canal支持多节点部署,通过主备模式或者集群模式来保证高可用性和容错性。
五. 总结
总体来说这几种方式各有优缺点,不过现在主要用的就是普通删除中的后删缓存的方法,如果一致性要求比较高的话,可以用读写锁的方式,如果没有那么强的一致性要求,可以使用后删缓存或者异步通知的方式。
结语
每个人都有自己独特的才华和潜能,在这个广袤的世界上,你的存在是有意义的。无论你是谁,你的背景如何,你所处的环境怎样,只要你敢于跨出舒适区,付出努力,追求卓越,你就能够开创属于自己的辉煌。
我们下期见。
每一次努力都是一次进步,即使进展缓慢,也要坚持不懈。
往期文章推荐:
- springsecurity加入第三方授权认证
- Java连接mysql常遇时间问题