• Flink 如何通过2PC实现Exactlyonce语义 (源码分析)


    Flink通过全局快照能保证内部处理的Exactly-once语义

    但是端到端的Exactly-once还需要下游数据源配合,常见的通过幂等或者二阶段提交这两种方式保证

    这里就来分析一下Sink二阶段提交的Flink源码是如何实现的

    本文源码基于Flink1.14

    老版本的话看TwoPhaseCommitSinkFunction,现在用SinkWriter逻辑都是差不多的

    先来看下我们的主角  org.apache.flink.streaming.runtime.operators.sink.SinkOperator 类

    1阶段. 在barrier到齐准备触发checkpoint之前

    调用了数据源的预提交方法 prepareCommit

    来看下已kafka为例具体做了什么

     kafkaWriter就是调用了生产者的flush方法,在已经开始的事务里面刷数据

    2阶段. 触发checkpoint保存状态数据的时候 snapshotState 方法

     以kafka为例

     会启动下一个checkpoint的kafka事务,直接就begin事务了,接着

    用这次checkpoint需要commit的kafkaCommiter更新了状态, 会被保存下来,这里有事务信息的后面会用到

    3阶段. 当checkpoint完成以后

     已kafka为例,会直接提交事务了commit

     

    这里可能会有疑问,,如果我只预提交了,还没有commit这时候跪了,那我从checkpoint恢复起来,那不就有问题了吗

    带着疑问看下最后一个阶段

    4阶段. 当任务失败从checkpoint恢复的时候

    初始化的时候会恢复状态

    可以看到会将上面说的上次checkpoint需要commiter的放到recoveredCommittables恢复队列里面

    然后retrayWithDelay,就会根据我们保存的kafka事务信息id等去判断,上一次事务的状态,如果是预提交的话,就会先去commit了

    总结一下流程:

    prepareSnapshotPreBarrier快照触发前, 预提交事务,kafka里面就是flash
    snapshotState快照保存时,开启一个新的事务kafka就是beginTransation,并且保存这次要提交的事务信息
    notifyCheckpointComplete快照完成以后,调用对应的commit提交事务 , kafka就是commitTransation
    initializeState从快照恢复,会先判断上次事务的状态如果还没提交会先提交



     

     

  • 相关阅读:
    响应式后台管理模版
    js数组、对象、正则
    react视频入门
    JSON.parse() JSON.stringify() eval() jQuery.parseJSON() 的区别
    网站生产app的一些网址
    一个博客总结的css常见的兼容性问题
    Js倒计时
    移动端好的博客
    day_4(element对象、node的属性、操作dom树)
    js的常用对象及方法使用
  • 原文地址:https://www.cnblogs.com/ljygz/p/15847847.html
Copyright © 2020-2023  润新知