关系型数据库讲究的是ACID 4个特性,故引入了数据库事务的概念,一个数据库事务中的多条SQL引发的多条数据变更要么全部成功,要么全部失败,即数据的一致性,那同样在数据同步的场景,在解析一个事务的 binlog 日志时,一次数据同步应该至少以事务为单位,一个事务内的所有 Event 应该作为一个批次提交到数据消费端,让消费端有能力一次同步一个事务中的数据,而不是一条一条变更日志的处理,这样容易造成数据不一致。
环形缓存区的引用就是为了解决将一个事务的完整数据一次提交到消费端,既然是多条消息,故一定需要用到缓存,环形缓存区就在这样的背景下被引入。
在 Canal 中关于事务 Event 的环形缓存区实现类为 EventTransactionBuffer。
1.1 类图
EventTransactionBuffer 的类图如下:
根据类图我们可以到其存储结构还是比较简单的。
-
int bufferSize环形缓存区的长度,默认为 1024,该长度必须为 2 的幂次方,因为对位运算非常友好。
-
int indexMask环形缓存区下标掩码,其值为 bufferSize - 1 ,sequence * indexMask 能快速定位序号 sequence 所在环形缓存区中的具体下标。
-
CannalEntry.Entry[] entries环形缓存区数据数组,即缓存区实际存储数据的内存区域,为数组结构,长度为 bufferSize。
-
AtomicLong putSequence当前写入的序号,每调用 add 方法添加一条数据,该值增加一,可超过缓存区的实际长度。
-
AtomicLong flushSequence当前已处理的数据序号,flushSequence <= putSequence,(putSequence - flushSequence)表示未处理的数据,即缓存区累积的有效数据。
-
TransactionFlushCallback flushCallbackflush 回调函数,这个和环形缓存区本身关系不大,这个与 Canal 特定业务的,环形缓存区中收集到一个完整的事务变更日志列表后,将这部分内容传入业务回调方法,并重新利用这些缓存空间。
环形缓存区的重大要义就是循环利用。
1.2 环形缓存区存储实现
接下来我们通过其 add 方法来看一下环形缓存区的,在研究环形缓存区之前,将结合8个元素的环形缓存区进行讲解。
EventTransactionBuffer 的 add 方法代码如下:
首先根据 binlog 事件类型来决定是否调用 flush 方法,这个就是实现将一个事务的事务一起提交到消费端,回到环形缓存区的具体实现,我们重点关注 put 方法 与 flush 方法的实现。
EventTransactionBuffer#put
其实现的核心步骤:
- 检测当前环形缓存区是否已满,如果未满,则向缓存区中添加一条数据。添加数据的具体逻辑:
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
总结
至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
B-1711383967259)]
[外链图片转存中…(img-hEPGBUDP-1711383967259)]
[外链图片转存中…(img-CNCQUHNy-1711383967259)]