1. 介绍

近期在做一些otter->kafka->flume->hbase的数据实时复制问题,因此了解otter本身的分装的Event信息的结构是比较重要的,这样在后续可以方便我们在kafka上做按key哈希或者hbase上列按key拆分。

EventData类在如下包中:

2. 基本结构

EventData是otter自己根据canal解析出来的结果再做了封装的。EventData主要就是保存数据库中的记录消息的。其基本结构如下图:

成员变量:

方法:

可以发现,这个类主要就是个数据库记录的 model类。提供了一些工具方法。

3. toString方法

之所以关注这个类,就是该类直接提供了序列化方法,方便我们做消息传递。假设我们有一张teacher表,表结构如下:

当插入一条数据之后:

在otter中EventData经过toString方法得出的结果如下:

EventData[tableId=7,tableName=teacher,schemaName=test,eventType=INSERT,executeTime=1470991205000,oldKeys=[],
keys=[EventColumn[index=0,columnType=4,columnName=id,columnValue=2,isNull=false,isKey=true,isUpdate=true]],
columns=[
EventColumn[index=1,columnType=12,columnName=name,columnValue=kami,isNull=false,isKey=false,isUpdate=true], EventColumn[index=2,columnType=4,columnName=age,columnValue=19,isNull=false,isKey=false,isUpdate=true]
],
size=49,pairId=10,sql=<null>,ddlSchemaName=<null>,syncMode=<null>,syncConsistency=<null>,remedy=false,hint=<null>,withoutSchema=false]

中括号内的信息按照顺序依次为:

3.1 核心EventData元素

下表是我们一般业务所需的最核心的数据。例如表明、数据库名、列名,已经对应的数据

名称 说明
tableId otter内部维护的一套tableId,与manager中得到的table Id对应
tableName 表的名字
schemaName 即database/schema的名字
eventType 变更数据的业务类型(I/U/D/C/A/E),与canal中的EntryProtocol中定义的EventType一致.
executeTime 变更数据的业务时间
oldKeys 变更前的主键值,如果是insert/delete变更前和变更后的主键值是一样的
keys 变更后的主键值,如果是insert/delete变更前和变更后的主键值是一样的。通过我们例子可以看到,keys的元素实际上是一个EventColumn对象
columns 非主键的其他字段

3.2 运行过程中的附加数据(EventData非核心元素)

之所以我称之为非核心元素,是相对于业务来说的。这些元素对于otter的运行时十分重要的,但是对于我们实际的业务来说,可能并不需要存储这些数据。存储这些运行时数据不仅增加我们网络传输的负担而且会造成存储资源的浪费。

EventData非核心元素说明如下:

名称 说明
size 预计的size大小,基于binlog event的推算,单位byte
pairId 同步映射关系的id
sql 顾名思义
ddlSchemaName ddl/query的schemaName,会存在跨库ddl,需要保留执行ddl的当前schemaName
syncMode 自定义的同步模式, 允许覆盖默认的pipeline parameter,比如针对补救数据同步
syncConsistency 自定义的同步一致性,允许覆盖默认的pipeline parameter,比如针对字段组强制反查数据库
remedy 是否为remedy补救数据,比如回环补救自动产生的数据,或者是freedom产生的手工订正数据
hint 生成对应的hint内容
withoutSchema 生成sql是否忽略schema,比如针对tddl/drds,需要忽略schema

4. 总结

熟悉EventData的结构,根据业务需求做合适的处理,提取自己所需的信息。