canal 源码解析系列-工程结构说明
这个是下载的源码在idea里的工程结构,我们从上到下开始捋。
admin模块
canal-admin设计上是为canal提供整体配置管理、节点运维等面向运维的功能,提供相对友好的WebUI操作界面,方便更多用户快速和安全的操作。
client模块
顾名思义,这是canal的客户端源码。canal采用的是client-server模式,通常我们使用canal的功能,是作为client接入,如果是java,就要引用下面这个依赖:
<dependency> <groupId>com.alibaba.otter</groupId> <artifactId>canal.client</artifactId> <version>${project.version}</version> </dependency>复制代码
而client模块就是这个依赖的源码模块。client主要是通过CanalConnector
这个接口的实现类完成客户端的大部分功能,包括连接、订阅、数据获取等。
client-adapter模块
客户端适配器,如果你展开模块的目录结构,从名字就能大概才出来它是干啥的了。canal 1.1.1版本之后,增加客户端数据落地的适配及启动功能, 目前支持功能:
客户端启动器
同步管理REST接口
日志适配器, 作为DEMO
关系型数据库的数据同步(表对表同步), ETL功能
HBase的数据同步(表对表同步), ETL功能
ElasticSearch多表数据同步,ETL功能
有人可能疑惑,为啥有了cient模块,还要有clent-adapter模块。事实上adapter是为了让用户能快速的运行canal而开发的一个模块。如果你要sink的数据端已经在adapter里实现了,你就可以快速的落地。
common模块
common模块主要是提供了一些公共的工具类和接口。
connector模块
connector模块里有几个实现:
kafka-connector
rabbitmp-connector
tcp-connector
rocketmq-connector
dbsync模块
原始的binlog都是二进制流,需要解析成对应的binlog事件,这些binlog事件对象都定义在dbsync模块中。
deploy模块
部署模块。canal是可以独立部署的,deploy模块就是用来独立部署canal服务的。
deploy模块负责启动canal server以及canal instance。在deploy目录下,含有canal的启停脚本,比如如果我们要启动canal,可以这样:
sh bin/startup.sh复制代码
docker模块
自带了一些docker启动的脚本,如果需要在docker环境使用canal,可以参考里面的脚本。
driver模块
parser 是通过driver模块与mysql建立连接,从而获取到binlog。
example模块
顾名思义,就是一些使用example的demo。
filter模块
filter 模块主要用于过滤 binlog 过来的表和字段数据。使用 canal 的时候,可以在服务端或客户端进行配置。filter基于aviater来做匹配,有几个实现类:
AviaterELFilter EL表达式匹配
AviaterRegexFilter 正则匹配
AviaterSimpleFilter 简单匹配
instance模块
最核心的模块之一。在一个 Canal 实例中只有启动 Instace,才能实现数据的同步。一个 Canal Server 实例中可以创建多个 Instance 实例。比如我们有个场景需要同步两个数据库(分库分表),可以创建两个instance实例。
instance模块有四个核心组成部分:parser模块、sink模块、store模块,meta模块。核心接口为CanalInstance。
meta模块
核心接口为CanalMetaManager,实现了订阅&消费的机制,主要用于记录canal消费到的mysql binlog的位置。CanalMetaManager接口有几个实现类:
FileMixedMetaManager
MemoryMetaManager
MixedMetaManager
PeriodMixedMetaManager
ZooKeeperMetaManager
这些实现类之间有些会持有其它实现的引用来装饰自己的功能(装饰器模式),
parser模块
parser模块用来订阅binlog事件,然后通过sink投递到store。parser模块底层依赖dbsync、driver模块。
prometheus模块
这个从名字也能看出来,是为了监控收集指标用的。
protocol模块主要定义了client和server的通信协议。canal的数据传包含两部分,一部分是进行binlog订阅时,binlog转换为我们所定义的Message,第二部分是client与server进行传输的TCP协议。这两部分采用的都是采用protobuff格式。
server模块
canal服务器端,对应canal整个服务实例,一个jvm实例只有一份server。
核心接口为CanalServer,有两个实现:
CanalServerWithEmbedded
CanalServerWithNetty
这两个实现代表了canal的两种应用模式,CanalServerWithNetty在canal独立部署场景发挥作用,开发者只需要实现cient,不同的应用通过canal client与canal server进行通信,canal client的请求统一由CanalServerWithNetty接受进行处理。
而通过CanalServerWithEmbeded,可以不需要独立部署canal,而是把canal嵌入到我们自己的服务里。但是这种对开发者的要求就比较高。
sink模块
Sink阶段所做的事情,就是根据一定的规则,对binlog数据进行一定的过滤。另外还会做一些数据分发的工作。它的核心接口是CanalEventSink,它的核心方法sink用来提交数据的。
store模块
用来执行最终的落库,数据存储。核心接口为CanalEventStore。
各个模块介绍完了,下面这幅图是canal的功能架构图:
参考:
作者:犀牛饲养员
链接:https://juejin.cn/post/7015182078341808164