文章目录
一. 基础逻辑
脏数据管理模块的基本逻辑是:
- 当数据消费失败时,将脏数据拦截并保存到dirtyDataCollector中;
- 全局metric判断:脏数据达到设定值之后,任务报错,flink停止运行,并将脏数据输出到flink日志中、或mysql的配置中。
对于代码实现:
DirtyManager用于管理DirtyDataCollector,串起DirtyDataCollector的生命周期,DirtyDataCollector主要用于收集脏数据并输出(到日志中,mysql中),脏数据数量达到设定值之后,flink停止运行。
具体的DataCollector实现有:
分别用于输出到taskmanager的日志、(最后报错时)jobmanager日志、输出到mysql表中。
所以这里有三层代码结构:
- DirtyManager:管理DirtyDataCollector
- DirtyDataCollector:主要用于收集脏数据并输出,并判断脏数据是否达到临界值
- 具体的DataCollector的实现:具体的输出实现:输出到日志,输出到mysql。
接下来我们逐个看每层的具体实现逻辑
二. DirtyManager
DirtyManager用于管理DirtyDataCollector,串起DirtyDataCollector的生命周期(open、run、close),主要流程如下:
- 设置系统配置给DirtyDataCollector
- 开启DirtyManager线程,主要用于DirtyDataCollector消费脏数据(收集脏数据)
- 关闭资源:DirtyDataCollector、DirtyManager的线程资源。
1. 初始化
初始化DirtyManager
- 根据配置加载特定的DirtyDataCollector:用于脏数据的收集
- 获取系统信息:jobId、jobName、operationName
- 获取脏数据metric,用于定期合并脏数据为全局脏数据。
public DirtyManager(DirtyConfig dirtyConfig, RuntimeContext runtimeContext) {
//通过反射注册DirtyDataCollector
this.consumer = DataSyncFactoryUtil.discoverDirty(dirtyConfig);
Map<String, String> allVariables = runtimeContext.getMetricGroup().getAllVariables();
this.jobId = allVariables.get(JOB_ID);
this.jobName = allVariables.getOrDefault(JOB_NAME, "defaultJobName");
this.operationName = allVariables.getOrDefault(OPERATOR_NAME, "defaultOperatorName");
this.errorCounter = runtimeContext.getLongCounter(Metrics.NUM_ERRORS);
}
2. 收集脏数据并check
被具体的连接器调用:
具体当连接器生产数据或写数据到数据源报错时,调用此方法收集脏数据
- 创建线程,用于异步执行DirtyDataCollector,开始消费脏数据到日志或mysql表中
- 添加脏数据条数,同步到全局脏数据metric中
- 脏数据信息,存到队列中,等待具体的脏数据收集器消费
- 子流程:判断脏数据条数是否大于总脏数据条数
public void collect(Object data, Throwable cause, String field, long globalErrors) {
if (executor == null) {
execute();
}
DirtyDataEntry entity = new DirtyDataEntry();
entity.setJobId