上文介绍了CheckpointBarrier的对齐操作,当CheckpointBarrier完成对齐操作后,接下来就是通过notifyCheckpoint()方法触发StreamTask节点的Checkpoint操作。
一. 调用StreamTask执行Checkpoint操作
如下代码,notifyCheckpoint()方法主要包含如下逻辑。
> 1. 判断toNotifyOnCheckpoint不为空。
> 2. 创建CheckpointMetaData和CheckpointMetrics实例,CheckpointMetaData用于存储
> Checkpoint的元信息,CheckpointMetrics用于记录和监控Checkpoint监控指标。
> 3. 触发StreamTask中算子的Checkpoint操作。
protected void notifyCheckpoint(CheckpointBarrier checkpointBarrier,
long bufferedBytes,
long alignmentDurationNanos) throws Exception {
if (toNotifyOnCheckpoint != null) {
// 创建CheckpointMetaData对象用于存储Meta信息
CheckpointMetaData checkpointMetaData =
new CheckpointMetaData(checkpointBarrier.getId(),
checkpointBarrier.getTimestamp());
// 创建CheckpointMetrics对象用于记录监控指标
CheckpointMetrics checkpointMetrics = new CheckpointMetrics()
.setBytesBufferedInAlignment(bufferedBytes)
.setAlignmentDurationNanos(alignmentDurationNanos);
// 调用toNotifyOnCheckpoint.triggerCheckpointOnBarrier()方法触发Checkpoint
操作
toNotifyOnCheckpoint.triggerCheckpointOnBarrier(
checkpointMetaData,
checkpointBarrier.getCheckpointOptions(),
checkpointMetrics);
}
}
注意:StreamTask是唯一实现了Checkpoint方法的子类,即只有StreamTask才能触发当前Task实例中的Checkpoint操作。
接下来具体看Checkpoint执行细节
1. 执行Checkpoint总体代码流程
Checkpoint触发过程分为两种情况:一种是CheckpointCoordinator周期性地触发数据源节点中的Checkpoint操作;另一种是下游算子通过对齐CheckpointBarrier事件触发本节点算子的Checkpoint操作。
不管是哪种方式触发Checkpoint,最终都是调用StreamTask.performCheckpoint()方法实现StreamTask实例中状态数据的持久化操作。
在StreamTask.performCheckpoint()方法中,首先判断当前的Task是否运行正常,然后使用actionExecutor线程池执行Checkpoint操作,Checkpoint的实际执行过程如下。
- Checkpoint执行前的准备操作,让OperatorChain中所有的Operator执行Pre-barrier工作。
- 将CheckpointBarrier事件发送到下游的节点中。
- 算子状态数据进行快照
执行checkpointState()方法,对StreamTask中OperatorChain的所有算子进行状态数据的快照操作,该过程为异步非阻塞过程,不影响数据的正常处理进程,执行完成后会返回True到CheckpointInputGate中。
- task挂掉情况处理:
- 如果isRunning的条件为false,表明Task不在运行状态,此时需要给OperatorChain中的所有算子发送CancelCheckpointMarker消息,这里主要借助recordWriter.broadcastEvent(message)方法向下游算子进行事件广播。
- 当且仅当OperatorChain中的算子还没有执行完Checkpoint操作的时候,下游的算子接收到CancelCheckpointMarker消息后会立即取消Checkpoint操作。
private boolean performCheckpoint(
CheckpointMetaData checkpointMetaData,
CheckpointOptions checkpointOptions,
CheckpointMetrics checkpointMetrics,
boolean advanceToEndOfTime) throws Exception {
LOG.debug("Starting checkpoint ({}) {} on task {}",
checkpointMetaData.getCheckpointId(),
checkpointOptions.getCheckpointType(),
getName());
final long checkpointId = checkpointMetaData.getCheckpointId();
if (isRunning) {
// 使用actionExecutor执行Checkpoint逻辑
actionExecutor.runThrowing(() -> {
if (checkpointOptions.getCheckpointType().isSynchronous()) {
setSynchronousSavepointId(checkpointId);
if (advanceToEndOfTime) {
advanceToEndOfEventTime();
}
}
//Checkpoint操作的准备工作
operatorChain.prepareSnapshotPreBarrier(checkpointId);
//将checkpoint barrier发送到下游的stream中
operatorChain.broadcastCheckpointBarrier(
checkpointId,
checkpointMetaData.getTimestamp(),
checkpointOptions);
//对算子中的状态进行快照操作,此步骤是异步操作,
//不影响streaming拓扑中数据的正常处理
checkpointState(checkpointMetaData, checkpointOptions,
checkpointMetrics);
});
return true;
} else {
// 如果Task处于其他状态,则向下游广播CancelCheckpointMarker消息
actionExecutor.runThrowing(() -> {
final CancelCheckpointMarker message =
new CancelCheckpointMarker(checkpointMetaData.getCheckpointId());
recordWriter.broadcastEvent(message);
});
return false;
}
}
1.1. StreamTask.checkpointState()
接下来我们看StreamTask.checkpointState()方法的具体实现,如下代码。
- 创建CheckpointStateOutputStream实例。主要有如下两种实现类:
- FsCheckpointStateOutputStream:文件类型系统
- MemoryCheckpointOutputStream:内存的数据流输出。
- 创建CheckpointingOperation实例,CheckpointingOperation封装了Checkpoint执行的具体操作流程,以及checkpointMetaData、checkpointOptions、storage和checkpointMetrics等Checkpoint执行过程中需要的环境配置信息。
- 调用CheckpointingOperation.executeCheckpointing()方法执行Checkpoint操作。
private void checkpointState(
CheckpointMetaData checkpointMetaData,
CheckpointOptions checkpointOptions,
CheckpointMetrics checkpointMetrics) throws Exception {
// 创建CheckpointStreamFactory实例
CheckpointStreamFactory storage = checkpointStorage.resolveCheckpointStorag
eLocation(
checkpointMetaData.getCheckpointId(),
checkpointOptions.getTargetLocation());
// 创建CheckpointingOperation实例
CheckpointingOperation checkpointingOperation