借助一个文件写入的例子来说明两阶段提交,在Flink中使用两阶段提交,需要实现TwoPhaseCommitSinkFunction这个抽象类的四个方法,我们下面来说明。
protected abstract TXN beginTransaction() throws Exception; protected abstract void preCommit(TXN transaction) throws Exception; protected abstract void commit(TXN transaction); protected abstract void abort(TXN transaction);
1. beginTransaction - 在事务开始前,我们在目标文件系统上面的临时目录上创建一个临时文件。随后,我们在程序处理的时候可以将数据写入到这个文件。
2. preCommit - 在预提交阶段,我们刷新文件到磁盘,关闭文件。
3. commit - 在提交阶段,我们原子性的将预提交阶段的文件移动到真正的目标目录。需要注意的是,这增加了输出数据的可见性的延迟,因为不mv是看不到数据的,延迟时间就是设定的checkpoint的时间。
4. abort - 在终止阶段,我们删除临时文件 *如果步骤中有任何错误,Flink会通过最新的checkpoint来恢复程序状态。
比如预提交成功了,在通知到达operator之前失败了。
这时候,Flink将operator的状态恢复到预提交阶段,即还未真正提交的时候。
为了能在重启的时候能够正确的终止或者提交事务,我们需要在预提交阶段将足够的信息保存到checkpoint中。
在这个例子中,这些信息是临时文件以及目标目录的地址, 当从checpoint恢复时,Flink会先执行一个Commit操作。