首页 » 智能 » 一文搞懂 Exactly once_事宜_算子

一文搞懂 Exactly once_事宜_算子

雨夜梧桐 2024-12-22 22:36:54 0

扫一扫用手机浏览

文章目录 [+]

一、背景

流处理(有时称为事宜处理)可以大略地描述为是对无界数据或事宜的连续处理。
流或事宜处理运用程序可以或多或少地被描述为有向图,并且常日被描述为有向无环图(DAG)。
在这样的图中,每个边表示数据或事宜流,每个顶点表示运算符,会利用程序中定义的逻辑处理来自相邻边的数据或事宜。
有两种分外类型的顶点,常日称为 sources 和 sinks。
sources读取外部数据/事宜到运用程序中,而 sinks 常日会网络运用程序天生的结果。
下图是流式运用程序的示例。

一文搞懂 Exactly once_事宜_算子 一文搞懂 Exactly once_事宜_算子 智能

A typical stream processing topology

一文搞懂 Exactly once_事宜_算子 一文搞懂 Exactly once_事宜_算子 智能
(图片来自网络侵删)

流处理引擎常日许可用户指定可靠性模式或处理语义,以指示它将为全体运用程序中的数据处理供应哪些担保。
这些担保是故意义的,由于你始终会碰着由于网络,机器等可能导致数据丢失的故障。
流处理引擎常日为运用程序供应了三种数据处理语义:最多一次、至少一次和精确一次。

如下是对这些不同处理语义的宽松定义:

最多一次(At-most-once)

这实质上是一『尽力而为』的方法。
担保数据或事宜最多由运用程序中的所有算子处理一次。
这意味着如果数据在被流运用程序完备处理之前发生丢失,则不会进行其他重试或者重新发送。
下图中的例子解释了这种情形。

At-most-once processing semantics

至少一次(At-least-once)

运用程序中的所有算子都担保数据或事宜至少被处理一次。
这常日意味着如果事宜在流运用程序完备处理之前丢失,则将从源头重放或重新传输事宜。
然而,由于事宜是可以被重传的,因此一个事宜有时会被处理多次,这便是所谓的至少一次。

下图的例子描述了这种情形:第一个算子最初未能成功处理事宜,然后在重试时成功,接着在第二次重试时也成功了,实在是没有必要的。

At-least-once processing semantics

精确一次(Exactly-once)

纵然是在各种故障的情形下,流运用程序中的所有算子都担保事宜只会被『精确一次』的处理。
(也有文章将 Exactly-once 翻译为:完备一次,恰好一次)

常日利用两种盛行的机制来实现『精确一次』处理语义。

分布式快照 / 状态检讨点至少一次事宜通报和对重复数据去重

实现『精确一次』的分布式快照/状态检讨点方法受到 Chandy-Lamport 分布式快照算法的启示[1]。
通过这种机制,流运用程序中每个算子的所有状态都会定期做 checkpoint。
如果是在系统中的任何地方发生失落败,每个算子的所有状态都回滚到最新的全局同等 checkpoint 点。
在回滚期间,将停息所有处理。
源也会重置为与最近 checkpoint 相对应的精确偏移量。
全体流运用程序基本上是回到最近一次的同等状态,然后程序可以从该状态重新启动。
下图描述了这种 checkpoint 机制的根本知识。

Distributed snapshot

在上图中,流运用程序在 T1 韶光处正常事情,并且做了checkpoint。
然而,在韶光 T2,算子未能处理输入的数据。
此时,S=4 的状态值已保存到持久存储器中,而状态值 S=12 保存在算子的内存中。
为了修复这种差异,在韶光 T3,处理程序将状态回滚到 S=4 并“重放”流中的每个连续状态直到最近,并处理每个数据。
终极结果是有些数据已被处理了多次,但这没紧要,由于无论实行了多少次回滚,结果状态都是相同的。

另一种实现『精确一次』的方法是:在每个算子上实现至少一次事宜通报和对重复数据去重来。
利用此方法的流处理引擎将重放失落败事件,以便在事宜进入算子中的用户定义逻辑之前,进一步考试测验处理并移除每个算子的重复事宜。
此机制哀求为每个算子掩护一个事务日志,以跟踪它已处理的事宜。
利用这种机制的引擎有 Google 的 MillWheel[2] 和 Apache Kafka Streams。
下图解释了这种机制的要点。

At-least-once delivery plus deduplication

二、『精确一次』是真正的『精确一次』吗?

现在让我们重新核阅『精确一次』处理语义真正对终极用户的担保。
『精确一次』这个术语在描述正好处理一次时会让人产生误导。

有些人可能认为『精确一次』描述了事宜处理的担保,个中流中的每个事宜只被处理一次。
实际上,没有引擎能够担保恰好只处理一次。
在面对任意故障时,不可能担保每个算子中的用户定义逻辑在每个事宜中只实行一次,由于用户代码被部分实行的可能性是永久存在的。

考虑具有流处理运算符的场景,该运算符实行打印传入事宜的 ID 的映射操作,然后返回事宜不变。
下面的伪代码解释了这个操作:

Map (Event event) { Print \公众Event ID: \"大众 + event.getId() Return event}

每个事宜都有一个 GUID (全局惟一ID)。
如果用户逻辑的精确实行一次得到担保,那么事宜 ID 将只输出一次。
但是,这是无法担保的,由于在用户定义的逻辑的实行过程中,随时都可能发生故障。
引擎无法自行确定实行用户定义的处理逻辑的韶光点。
因此,不能担保任意用户定义的逻辑只实行一次。
这也意味着,在用户定义的逻辑中实现的外部操作(如写数据库)也不能担保只实行一次。
此类操作仍旧须要以幂等的办法实行。

那么,当引擎声明『精确一次』处理语义时,它们能担保什么呢?如果不能担保用户逻辑只实行一次,那么什么逻辑只实行一次?当引擎声明『精确一次』处理语义时,它们实际上是在说,它们可以担保引擎管理的状态更新只提交一次到持久的后端存储。

上面描述的两种机制都利用持久的后端存储作为真实性的来源,可以保存每个算子的状态并自动向其提交更新。
对付机制 1 (分布式快照 / 状态检讨点),此持久后端状态用于保存流运用程序的全局同等状态检讨点(每个算子的检讨点状态)。
对付机制 2 (至少一次事宜通报加上重复数据删除),持久后端状态用于存储每个算子的状态以及每个算子的事务日志,该日志跟踪它已经完备处理的所有事宜。

提交状态或对作为真实来源的持久后端运用更新可以被描述为恰好发生一次。
然而,如上所述,打算状态的更新 / 变动,即处理在事宜上实行任意用户定义逻辑的事宜,如果发生故障,则可能不止一次地发生。
换句话说,事宜的处理可以发生多次,但是该处理的效果只在持久后端状态存储中反响一次。
因此,我们认为有效地描述这些处理语义最好的术语是『有效一次』(effectively once)。

那么,当引擎声明『精确一次』处理语义时,它们能担保什么呢?如果不能担保用户逻辑只实行一次,那么什么逻辑只实行一次?当引擎声明『精确一次』处理语义时,它们实际上是在说,它们可以担保引擎管理的状态更新只提交一次到持久的后端存储。

三、分布式快照与至少一次事宜通报和重复数据删除的比较

从语义的角度来看,分布式快照和至少一次事宜通报以及重复数据删除机制都供应了相同的担保。
然而,由于两种机制之间的实现差异,存在显著的性能差异。

机制 1(分布式快照 / 状态检讨点)的性能开销是最小的,由于引擎实际上是往流运用程序中的所有算子一起发送常规事宜和分外事宜,而状态检讨点可以在后台异步实行。
但是,对付大型流运用程序,故障可能会更频繁地发生,导致引擎须要停息运用程序并回滚所有算子的状态,这反过来又会影响性能。
流式运用程序越大,故障发生的可能性就越大,因此也越频繁,反过来,流式运用程序的性能受到的影响也就越大。
然而,这种机制是非侵入性的,运行时须要的额外资源影响很小。

机制 2(至少一次事宜通报加重复数据删除)可能须要更多资源,尤其是存储。
利用此机制,引擎须要能够跟踪每个算子实例已完备处理的每个元组,以实行重复数据删除,以及为每个事宜实行重复数据删除本身。
这意味着须要跟踪大量的数据,尤其是在流运用程序很大或者有许多运用程序在运行的情形下。
实行重复数据删除的每个算子上的每个事宜都会产生性能开销。
但是,利用这种机制,流运用程序的性能不太可能受到运用程序大小的影响。
对付机制 1,如果任何算子发生故障,则须要发生全局停息和状态回滚;对付机制 2,失落败的影响更加局部性。
当在算子中发生故障时,可能尚未完备处理的事宜仅从上游源重放/重传。
性能影响与流运用程序中发生故障的位置是隔离的,并且对流运用程序中其他算子的性能险些没有影响。
从性能角度来看,这两种机制的优缺陷如下。

分布式快照 / 状态检讨点的优缺陷:

优点:较小的性能和资源开销缺陷:对性能的影响较大拓扑越大,对性能的潜在影响越大

至少一次事宜通报以及重复数据删除机制的优缺陷:

优点:故障对性能的影响是局部的故障的影响不一定会随着拓扑的大小而增加缺陷:可能须要大量的存储和根本举动步伐来支持每个算子的每个事宜的性能开销

虽然从理论上讲,分布式快照和至少一次事宜通报加重复数据删除机制之间存在差异,但两者都可以简化为至少一次处理加幂等性。
对付这两种机制,当发生故障时(至少实现一次),事宜将被重放/重传,并且通过状态回滚或事宜重复数据删除,算子在更新内部管理状态时实质上是幂等的。

四、结论

在这篇博客文章中,我希望能够让你相信『精确一次』这个词是非常具有误导性的。
供应『精确一次』的处理语义实际上意味着流处理引擎管理的算子状态的不同更新只反响一次。
『精确一次』并不能担保事宜的处理,即任意用户定义逻辑的实行,只会发生一次。
我们更喜好用『有效一次』(effectively once)这个术语来表示这种担保,由于处理不一定担保只发生一次,但是对引擎管理的状态的影响只反响一次。
两种盛行的机制,分布式快照和重复数据删除,被用来实现精确/有效的一次性处理语义。
这两种机制为处理和状态更新供应了相同的语义担保,但是在性能上存在差异。
这篇文章并不是要让你相信任何一种机制都优于另一种,由于它们各有利弊。

五、参考

Chandy, K. Mani and Leslie Lamport.Distributed snapshots: Determining global states of distributed systems. ACMTransactions on Computer Systems (TOCS) 3.1 (1985): 63-75.Akidau, Tyler, et al. MillWheel:Fault-tolerant stream processing at internet scale. Proceedings of the VLDBEndowment 6.11 (2013): 1033-1044.

一文

标签:

相关文章