一、背景
当备库回放业务时,多个相互不依赖的业务能够并发回放,本方法首要用于解决多个可并发回放的业务的并发回放问题。经过并发的多个扫描线程实现并发对事物回放行列进行扫描,生成多个能够并发回放的事物,而且通知回放线程进行并发的回放。
二、数据结构设计
备库的事物数据依照事物 ID 分段存储到备库的事物数据行列中,参阅如下图 1;依据事物 ID 为 UUID 完全无序的特性,能够对 UUID 进行事物 ID 分段并发扫描。将事物 ID UUID 分段后,交给多个扫描线程协程,每个扫描线程负责某个 UUID 分区进行多个扫描线程并发扫描,扫描可回放的事物。
三、线程生命周期
当扫描线程发现可回放的事物后,会将事物 ID 参加 txnList 履行 enqueu 操作,参加事物 ID 后,扫描线程会履行 notify 操作,唤醒正在睡眠的回放线程进行业务回放操作,示意图参阅如下图 2。
![图片](p3-juejin.byteimg.com/tos-cn-i-k3…
回放线程协程的生命周期如下如图 3,回放线程刚启动后处于睡眠状况,当有业务回放时,会被随机唤醒。被唤醒的回放线程协程会履行业务回放任务,而且清理业务的依赖联系。
当发现可回放的业务时,假如发现可回放的业务数等于 1,则由当前协程进行回放削减一次 CPU 切换的开支;当发现多余 1 个可回放业务时,回放线程协程会将除掉第一个的可回放业务,参加 txnList 唤醒其他协程进行业务回放,以实现更好回放的并发功能。
四、并发切换问题
在采取了并发清理时,因为 CPU 切换的问题,需求处理重复发现的可回放业务,对重复发现相同的业务 ID 进行防御性幂等处理,如下图 4。因此,需求对每个可回放业务引入 txnIDSet 进行幂等处理。
五、如何判断回放是否完毕
因为采取了并发扫描以及并发回放,所以需求在悉数可回放业务悉数回放完毕后,完毕回放的流程,在此给出回放完毕的定义。
当可回放业务悉数回放完毕后,认为回放完毕。可回放业务分为 3 类,曩昔发现的可回放业务/现在发现的可回放业务/将来发现的可回放业务。
曩昔发现的可回放业务都会被参加到 txnList 中,现在发现的可回放业务正在由回放线程进行回放,将来发现的可回放业务是由扫描线程扫描 UUID 进行发现的。
-
曩昔发现的业务回放完毕的条件为 txnList 为空;
-
现在发现的业务回放完毕的条件为一切的 workerStatus 总和为 0;
-
将来发现的业务回放完毕的条件为一切的扫描线程,GatherAll 扫描可回放业务无法发现。
六、功能调优
依据 CPU 数量,可经过动态调整扫描线程和回放线程的回放协程数量,以合理分配两组协程的负载。这样做能够充分利用多核处理器的功能,并提高系统的吞吐量和呼应能力。