这是我参与「第四届青训营」笔记创作活动的第4天。
知识点小记
端到端 Exactly-Once 实现
虽然有了上次笔记中的方法二的方法,flink能通过Checkpoint机制对所有算子的状态实现Exactly-Once,但是这种方法对sink节点而言,其实是一直往下游发数据的状态,所以当发生故障需要回滚的时候,会导致sink中的数据重复发的现象,不能保证数据只下发一次,即不能实现严格的端到端 Exactly-Once。例如在账单服务中会发生重复扣费的情况。
两阶段提交协议
图源:青训营课堂
协作者(Coordinator):统一处理所有节点的执行逻辑的中心节点。
参与者(Participant):被中心节点调度的其他业务节点。
- 预提交阶段
①协作者向参与者发送一个query to commit消息。
②每个参与的协作者收到消息后,执行事务,但是不真正提交,事务的执行结果(成功 or 失败)会发送给协作者。
- 提交阶段
情况一、若协作者成功的收到所有参与者成功的消息。则执行以下过程:
①协作者向所有参与者发送commit消息。
②每个收到commit的参与者执行释放执行事务所需要的资源并结束这次事务的执行,发送给ack给协作者。
③协作者收到所有参与者的ack后,该事务执行完毕。
情况二、若协作者收到了一个或多个失败的消息(或发生超时),则执行以下过程:
①协作者向所有参与者发送rollback消息。
②每个收到rollback的参与者进行事务回滚且释放执行事务所需要的资源,发送给ack给协作者。
③协作者收到所有参与者的ack后,该事务回滚执行完毕。
总结
虽然前面的方法二可以实现Exactly-Once,但其无法实现真正意义上端到端的Exactly-Once,可通过此次笔记中的两阶段提交协议来实现,从而可以使下游节点读到的数据不丢不重。