赞
踩
通常情况下,流式计算系统都会为用户提供数据处理的可靠模式功能,用来表明在实际生产运行中会对数据处理做哪些保障。一般来说,流处理引擎通常为用户的应用程序提供三种数据处理语义:最多一次,至少一次和精确一次。
Exactly-Once是Flink,Spark等流处理系统的核心特性之一,这种语义会保证每一条消息只被流处理系统处理一次。”精确一次“语义是Flink 1.4.0版本引入的一个重要特性,而且,Flink号称支持”端到端的精确一次“语义。
这里解释一下”端到端的精确一次“,它指的是Flink应用从Source端开始到Sink端结束,数据必须经过的起始点和结束点。Flink自身是无法保证外部系统”精确一次“语义的,所以Flink若要实现所谓”端到端的精确一次“的要求,那么外部系统必须支持”精确一次“语义,然后借助Flink提供的checkpoint和两阶段提交才能实现。
来自:https://segmentfault.com/a/1190000022891333
要真正实现流数据处理的Exactly-Once语义,一共要保证三个地方。
1)外部应用数据输入到source要保证Exactly-Once语义。
2)flink内部的数据处理要保证Exactly-Once语义。
3)sink将数据输入到外部应用要保证Exactly-Once语义。
那么flink对这三个阶段是如何保证的呢?这里以kafka-flink-kafka为例简单概述:
如果对checkpoint不太了解的同学可以看这篇文章:
https://blog.csdn.net/weixin_44844089/article/details/117192040
source算子会向数据流中添加barrier,对于source任务而言,就会把当前的offset作为状态保存起来。下次从checkpoint恢复时,source任务可以重新提交偏移量,从上次保存的位置开始重新消费数据。
这个就是flink内部的checkpoint机制就可以完成
sink阶段实际上就比较麻烦,需要使用两段式提交的过程来保证Exactly-Once语义。
sink 任务首先把数据写入外部 kafka,这些数据都属于预提交的事务(还不能被消费);当遇到 barrier 时,把状态保存到状态后端,并开启新的预提交事务。
当所有算子任务的快照完成,也就是这次的 checkpoint 完成时,JobManager 会向所有任务发通知,确认这次 checkpoint 完成。
当sink 任务收到确认通知,就会正式提交之前的事务,kafka 中未确认的数据就改为“已确认”,数据就真正可以被消费了。
所以我们看到,执行过程实际上是一个两段式提交,每个算子执行完成,会进行“预提交”,直到执行完sink操作,会发起“确认提交”,如果执行失败,预提交会放弃掉。
具体的两阶段提交步骤总结如下:
需要实现TwoPhaseCommitSinkFunction,里面有四个核心抽象方法:
1、beginTransaction 这是是开始一个事务
2、preCommit 预提交操作
3、commit 提交操作
4、abort 终止 放弃一个事务
具体怎么实现我就不会了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。