Exactly Once 语义在 Flink 中的实现 | 青训营笔记

120 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第3天

一、本堂课重点内容:

课程主要分为四个部分
第一部分介绍了Flink中数据流和动态表的概念
第二部分介绍了Exactly Once和Checkpoint机制
第三部分介绍了端到端的Exactly Once的实现
第四部分结合账单计费场景介绍了Flink的实际应用

二、知识点介绍:

  • 数据流
    查询从不终止
    查询结果会不断更新,并且会产生一个新的动态表
    结果的动态表也可转换成输出的实时流

  • 动态表
    随时间不断变化的表,在任意时刻,可以像查询静态批处理表一样查询它们

  • 一致性保证语义
    At-most-once:每条数据消费至多一次,处理延迟低
    At-least-once:每条数据消费至少一次,一条数据可能存在重复消费
    Exactly-once:每条数据都被消费且仅被消费一次,仿佛故障从未发生

  • 快照制作
    Chandy Lamport算法

  • Checkpoint对作业性能的影响
    解耦了快照制作和数据处理过程,各个算子制作完成可以继续处理数据,不用等下游完成快照

    在快照制作和Barrier Alignment过程中需要暂停处理数据,仍然会增加数据处理延迟

    快照保存到远端可能非常耗时

  • 两阶段提交协议(2PC)

image.png

  • 两阶段提交协议在 Flink 中的应用
    1.事务开启:sink task向下游写数据之前,均会开启一个事务,后续所有写数据的操作均在事务里,未提交时,下游不可读
    2.预提交阶段:JobManager开始下发Checkpoint Barrier,当各个处理逻辑收到Barrier后停止处理后续数据,制作快照,此时sink也不再当前事务下继续处理数据。状态制作完成向JM发送消息。
    3.提交阶段:当JM收到所有预提交成功的消息,则向所有处理逻辑发送可以提交事务的消息,sink接收到此消息后,完成提交,下游可以读取该事务写下的数据,超时或者失败则回滚,sink丢弃这次事务提交的数据。

三、课后拓展:

  • 2PC的缺点
    二阶段提交看似能够提供原子性的操作,但它存在着严重的缺陷

    网络抖动导致的数据不一致: 第二阶段中协调者向参与者发送commit命令之后,一旦此时发生网络抖动,导致一部分参与者接收到了commit请求并执行,可其他未接到commit请求的参与者无法执行事务提交。进而导致整个分布式系统出现了数据不一致。

    超时导致的同步阻塞问题: 2PC中的所有的参与者节点都为事务阻塞型,当某一个参与者节点出现通信超时,其余参与者都会被动阻塞占用资源不能释放。

    单点故障的风险: 由于严重的依赖协调者,一旦协调者发生故障,而此时参与者还都处于锁定资源的状态,无法完成事务commit操作。 ,会重新选举一个协调者,可无法解决因前一个协调者宕机导致的参与者处于阻塞状态的问题。

  • 3PC
    3PC最关键要解决的就是协调者和参与者同时挂掉的问题,所以3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommitPreCommitDoCommit三个阶段。

    在第一阶段,只是询问所有参与者是否可可以执行事务操作,并不在本阶段执行事务操作。当协调者收到所 有的参与者都返回YES时,在第二阶段才执行事务操作,然后在第三阶段在执行commit或者rollback。

  • 3PC的缺点
    三阶段提交也会导致数据一致性问题。由于网络原因,协调者发送的 abort 响应没有及时被参与者接收到,那么参与者在等待超时之后执行了 commit 操作。

    这样就和其他接到 abort 命令并执行回滚的参与者之间存在数据不一致的情况。

四、引用参考:

  • 深入理解分布式系统的2PC和3PC

www.hollischuang.com/archives/15…

  • 一文读懂Apache Flink技术

juejin.cn/post/684490…