kronos是一个解决宽表同步的框架,它的定位类似flink cdc,比起flink cdc要轻巧、简单、灵活。尤其是解决了存储到es,并存在嵌套类型结构的数据。下面是对kronos的框架实现的一个原理解析。关于该项目的更多适用场景,将在其他文章中描述
上图是kronos的一个整体架构图,当前是一个单节点的实现,后续会有分布式的原理解析
如上图所示,存在来自不同的数据源的6张表,合并相关的元素。假设相关的schema如下表
表名 | 相关字段 | 是否为主表 | 关联关系 | |
---|---|---|---|---|
f | f1 、f2、 f3 、fc_fk、fd_fk | 是 | ||
c | c1、 c2、 c3 | 否 | c.c1 = f.fc_fk | |
d | d1、 d2、 d3 | 否 | d.d1 = f.fd_fk | |
e | e1、 e2、 e3、ef_fk | 否 | e.ef_fk = f.f1 | |
b | b1、 b2、 b3、be1 | 否 | b.be1 = e.e1 | |
a | a1、 a2、 a3、ab1 | 否 | a.ab1 = b.b1 | |
配置信息中需要饱含以下几个核心配置
- 各表的连接信息
- 各表可能来自于同一个数据源、也可能是不同的数据源
- 各表的关联关系
- 如schema表中的关联关系
- 目标表的连接信息
- 支持不同的数据库
- 最后组装的数据结构
第一个版本应该会以json或yml的方式设计配置结构
根据配置信息可以获取构建一个以主表为头节点的树状结构,并将各种环境变量设置到各节点中
根据逻辑算子生成一个可执行的物理算子模型,该模型支持多线程。通过OrderQueue保证数据的顺序性
相关表的binlog事件可能会从多个source端获取,所以他们是一个无顺序的事件
这个结构有点类似netty中的事件分发器,所有的binlog事件都会发送到这个事件环,随后会分别发送到OrderQueue与不同的算子路径中
关于dispatch实现逻辑,一个事件会在事件环中封装相关的信息(比如应该执行什么样的数据查询逻辑),然后分发到不同算子源,比如a表的事件会被 a->b->c...这个链路消费,d表的事件会被位于中间的d-->f...消费
orderQueue是一个有序的队列,所有的事件都会在该队列中等待被sink端算子消费,而能被消费的唯一条件是:如算子图最后的return虚线
都返回相应的数据,将事件数据标记为ok状态
tip: 理论上,根据事件数据
中的主表id,sink端的消费可以跳跃式的消费OrderQueue中的数据
sink端拿到完整的数据后,会按照配置中用户要求的输出结构,构造数据,最后保存到响应的数据源
tip:该模块后期会要求支持update的方式直接更新数据源,以提高性能
local db模块确切的应该被称为search模块,因为各算子需要的所有关联数据都是从这个模块获取。kronos的第一个版本会按照反查的逻辑实现,所以该模块只是一个实现了jdbc查询的模块,但是在后续的优化阶段会要求该模块能够支持缓存数据、高性能查询的能力