Flink Exactly

  • 时间:
  • 浏览:0
  • 来源:大发5分排列3_大发5分排列3官方

Flink 的 exactly-once sink 均基于快照机制,按照实现原理前要分为幂等(Idempotent) sink 和事务性(Transactional) sink 四种 生活。

然而幂等 sink 的适用场景依赖于业务逻辑,机会下游业务一点一点 就无法保证幂等性,这时就前要应用事务性 sink。

Flink 从 0.9 版本开始英文英语 提供 State API,标志着 Flink 进入了 Stateful Streaming 的时代。State API 简单来说是“不受系统程序重启影响的“数据底部形态,其命名规范也与常见的数据底部形态一致,比如 MapState、ListState。Flink 官方提供的算子(比如 KafkaSource)和用户开发的算子前要使用 State API 来保存情况表信息。和大多数分布式系统一样 Flink 采用快照的最好的妙招 来将整个作业的情况表定期同步到内部内部结构存储,也一点一点 将 State API 保存的信息以序列化的形式存储,作业恢复的过后要是我读取内部内部结构存储即可将作业恢复到先前某个时间点的情况表。机会从快照恢复同前会回滚数据流的处置进度,一点一点 State 是绿帘石的 exactly-once 投递。

Commit 出現错误会意味着 作业自动重启,重启后 Bucketing File Sink 四种 生活已被恢复为上次 checkpoint 时的情况表,不过仍前要将文件系统的情况表也恢复以保证一致性。从 checkpoint 恢复后对应的事务会再次重试 commit,它会将记录的 pending 文件改为 committed 情况表,记录的 in-progress 文件 truncate 到 checkpoint 记录下来的 offset,而其余未被记录的 pending 文件和 in-progress 文件都将被删除。

Exactly-once 是实时系统最为关键的准确性要求,也是当前限制大次要分布式实时系统应用到准确性要求更高的业务场景(比如在线事务处置 OLTP)的间题之一。目前来说流式计算的 exactly-once 在理论上机会有了很大的突破,而 Flink 社区也在积极汲取最先进的思想和实践经验。随着 Flink 在 exactly-once 上的技术愈发心智心智成熟期 图片 图片 图片 ,结合 Flink 四种 生活的流处置底部形态,相信在不远的将来,除了构造数据分析、数据管道应用, Flink 也前要在微服务领域占有一席之地。

10万人关注的大数据成神之路,真的不来了解一下吗?

而在分布式环境下 exactly-once 则更为繁杂,最大的不同点在于分布式系统前要容忍系统程序崩溃和节点丢失,这会带来一点间题,比如下面常见的几条:

Flink 提供 exactly-once 的情况表(state)投递语义,这为有情况表的(stateful)计算提供了准确性保证。其中比较容易令人混淆的一点是情况表投递语义和更加常见的端到端(end to end)投递语义,而实现前者是实现后者的前置条件。

10万人关注的大数据成神之路,不来了解一下吗?

然而仅有下游系统四种 生活提供的事务保证对于 exactly-once sink 来说是存在问题的,机会同有一两个 sink 的子任务(subtask)会有多个,对于下游系统来说它们是存在不同会话和事务中的,未必能保证操作的原子性,如果 exactly-once sink 还前要实现分布式事务来达到所有 subtask 的一致 commit 或 rollback。机会 sink 事务生命周期是与 checkpoint 一一对应的,机会说 checkpoint 一点一点 一点一点 实现作业情况表持久化的分布式事务,sink 的分布式事务也理所当然前要通过 checkpoint 机制提供的 hook 来实现。

下面将分析 Flink 是如可实现 exactly-once Sink 的。

随便说说 消息的 exactly-once 投递并完整版前会有一两个分布式系统产生的新课题(随便说说 它一般特指分布式领域的 exactly-once),早在计算网络发展初期的 TCP 协议机会实现了网络的可靠传输。TCP 协议的 exactly-once 实现最好的妙招 是将消息传递变为有情况表的:首先同步建立连接,如果发送的每个数据包加在递增的序列号(sequence number),发送完毕后再同步释放连接。机会发送端和接受端都保存了情况表信息(已发送数据包的序列号/已接收数据包的序列号),它们前要知道哪此数据包是缺失或重复的。

Checkpoint 提供给算子的 hook 有 CheckpointedFunction 和 CheckpointListener 有一两个,前者在算子进行 checkpoint 快照时被调用,后者在 checkpoint 成功后调用。为了简单起见 Flink 结合上述有一两个接口抽象出 exactly-once sink 的通用逻辑抽象 TwoPhaseCommitSinkFunction 接口,从命名即可看出这是对两阶段提交协议的有一两个实现,其主要最好的妙招 如下:

机会在分布式系统的系统程序间协调前要通过网络,而网络情况表在一点一点情况表下是不可预知的,通常发送消息要考虑四种 生活情况表:正常返回、错误返回和超时,其中错误返回又前要分为可重试错误返回(e.g. 数据库维护暂时不可用)和不可重试错误返回(e.g. 认证错误),而可重试错误返回和超时前会意味着 重发消息,意味着 下游机会接收到重复的消息,也一点一点 at-least-once 的投递语义。而 exactly-once 是在 at-least-once 的基础之加在在了前要识别出重发数据机会将消息包装为为幂等操作的机制。

10万人关注的大数据成神之路,确定真的不来了解一下吗?

运行时,Bucketing File Sink 首先会打开有一两个临时文件未必断地将收到的数据写入(要花费 事务的 beginTransaction 步骤),这时文件存在 in-progress。直到你你这个文件机会大小超过阈值机会一段时间内什么什么都这样 新数据写入,这时文件关闭并变为 pending 情况表(要花费 事务的 pre-commit 步骤)。机会 Flink checkpoint 是异步的,机会有多个并发的 checkpoint,Bucketing File Sink 会记录 pending 文件对应的 checkpoint epoch,当某个 epoch 的 checkpoint 完成后,Bucketing File Sink 会收到 callback 并将对应的文件改为 committed 情况表。这是通过原子操作重命名来完成的,如果前要保证 pre-commit 的事务要么 commit 成功要么 commit 失败,越多再出現一点后边情况表。

随着近来什么什么都这样 来越多的业务迁移到 Flink 上,对 Flink 作业的准确性要求也随之进一步提高,其中最为关键的是如可在不同业务场景下保证 exactly-once 的投递语义。随便说说 不少实时系统(e.g. 实时计算/消息队列)都宣称支持 exactly-once,exactly-once 投递似乎是有一两个已被处置的间题,如果随便说说 它们更多是针对内部内部结构模块之间的信息投递,比如 Kafka 生产(producer 到 Kafka broker)和消费(broker 到 consumer)的 exactly-once。而 Flink 作为实时计算引擎,在实际场景业务会涉及到一点一点不同组件,机会组件底部形态和定位的不同,Flink 并完整版前会对所有组件都支持 exactly-once(见[1]),如果不同组件实现 exactly-once 的最好的妙招 完整版前会所差异,一点实现或许会带来副作用机会用法上的局限性,如果深入了解 Flink exactly-once 的实现机制对于设计稳定可靠的架构有十分重要的意义。

第2点和第3点随便说说 是同有一两个间题,即前要区分出一点一点 系统程序和重启后的系统程序。对此业界机会有比较心智心智成熟期 图片 图片 图片 的处置方案: 引入 epoch 表示系统程序的不同世代并用分布式协调系统来负责管理。随便说说 还有一点衍生的细节间题,但总体来说间题完整版前会大。如果第1点间题造成了有一两个比较深远的影响,即为了减低 IO 成本,情况表的保存必然是微批量(micro-batching)的而完整版前会流式的,这会意味着 情况表的保存总爱 落后于流计算进度,因而为了保证 exactly-once 流计算引擎前要实现事务回滚。

而端到端的一致性则前要上下游的内部内部结构系统配合,机会 Flink 无法将它们的情况表也保存到快照并独立地回滚它们,如果就不叫作内部内部结构系统了。通常来说 Flink 的上游是前要重复读取机会消费的 pull-based 持续化存储,一点一点要实现 source 端的 exactly-once 只前要回滚 source 的读取进度即可(e.g. Kafka 的 offset)。而 sink 端的 exactly-once 则比较繁杂,机会 sink 是 push-based 的。所谓覆水难收,要撤出 发出去的消息是并完整版前会容易的事情,机会这要求下游根据消息作出的一系列反应完整版前会可撤出 的。这就前要用 State API 来保存已发出消息的元数据,记录哪此数据是重启后前要回滚的。

幂等性是分布式领域里十分有用的底部形态,它意味着 分析相同的操作执行一次和执行多次前要获得相同的结果,如果 at-least-once 自然等同于 exactly-once。什么什么都这样 一来,在从快照恢复的过后幂等 sink 便不前要对内部内部结构系统撤出 已发消息,要花费 回避了内部内部结构系统的情况表回滚间题。比如写入 KV 数据库的 sink,机会插入一行的操作是幂等的,如果 sink 前要无情况表的,在错误恢复时一点一点 前要关心内部内部结构系统的情况表。从四种 生活意义来讲,上文提到的 TCP 协议也是利用了发送数据包幂等性来保证 exactly-once。

事务性 sink 顾名思义累似 于于传统 DBMS 的事务,将一系列(一般是有一两个 checkpoint 内)的所有输出包装为有一两个逻辑单元,理想的情况表下提供 ACID 的事务保证。未必说是“理想的情况表下”,主一点一点 机会 sink 依赖于目标输出系统的事务保证,而分布式系统对于事务的支持未必一定很完整版,比如 HBase 就不支持跨行事务,再比如 HDFS 等文件系统是不提供事务的,你你这个情况表下 sink 只前要在客户端的基础上再包装一层来尽最大努力地提供事务保证。

下文将基于 Flink 完整版分析 exactly-once 的难点所在以及实现方案,而哪此结论也前要推广到一点实时系统,很重是流式计算系统。

1.Fault Tolerance Guarantees of Data Sources and Sinks

2.An Overview of End-to-End Exactly-Once Processing in Apache Flink

3.State Management in Apache Flink

4.An Overview of End-to-End Exactly-Once Processing in Apache Flink (with Apache Kafka, too!)

在 Bucketing File Sink 的例子中,存在 in-progress 和 pending 情况表的文件默认情况表下完整版前会隐藏文件(在实践中是使用下划线作为文件名前缀,HDFS 的 FileInputFormat 会将其过滤掉),什么什么都这样 commit 成功后文件才对用户是可见的,即提供了 read-committed 的事务隔离性。理想的情况表下 exactly-once sink 都应该使用在下游系统缓存未 commit 数据的最好的妙招 ,机会这最为符合流式计算的理念。最为典型的是下游系统一点一点 就支持事务,什么什么都这样 未 commit 的数据很自然地一点一点 缓存在下游系统的,如果 sink 前要确定像上例的 Bucketing File Sink 一样在下游系统的用户层面实现被委托人的事务,机会 fallback 到等待的图片 数据变为 committed 再发出的 micro-batching 模式。

Bucketing File Sink 是 Flink 提供的有一两个 FileSystem Connector,用于将数据流写到固定大小的文件里。Bucketing File Sink 将文件分为四种 生活情况表,in-progress/pending/committed,分别表示正在写的文件、写完准备提交的文件和机会提交的文件。

下面以 Bucketing File Sink 作为例子来说明如可基于异步 checkpoint 来实现事务性 sink。

后边主要围绕事务保证的 AC 两点(Atomicity 和 Consistency),而在 I(Isolation)上 Flink exactly-once sink 完整版前会不同的实现最好的妙招 。实际上机会 Flink 的流计算底部形态,当前事务的未 commit 数据是总爱 在积累的,根据缓存未 commit 数据的地方的不同,前要将事务性 sink 分为四种 生活实现最好的妙招 。