关于数据库:流计算引擎数据一致性的本质

6次阅读

共计 11041 个字符,预计需要花费 28 分钟才能阅读完成。

简介:本篇文章从流计算的实质登程,重点剖析流计算畛域中数据处理的一致性问题,同时对一致性问题进行简略的形式化定义,提供一个一窥当下流计算引擎倒退脉络的视角,让大家对流计算引擎的意识更为深刻,为可能的流计算技术选型提供一些参考。

作者 | 齐光
起源 | 阿里技术公众号

流计算的利用与实际在大数据畛域越来越常见,其重要性显而易见,常见的流计算引擎有 Google DataFlow、Apache Flink,Apache Kafka Streams,Apache Spark Streaming 等。流计算零碎中的数据一致性个别是用音讯解决语义来定义的,如某引擎宣称能够提供「恰好一次(Exactly-once Processing Semantics)流解决语义,示意(或暗示)引擎具备保证数据一致性的能力。事实上,「恰好一次(Exactly-Once)」并不等价于流计算的输入数据就合乎一致性的要求,该术语存在很多了解和应用上的误区。

本篇文章从流计算的实质登程,重点剖析流计算畛域中数据处理的一致性问题,同时对一致性问题进行简略的形式化定义,提供一个一窥当下流计算引擎倒退脉络的视角,让大家对流计算引擎的意识更为深刻,为可能的流计算技术选型提供一些参考。文章次要分为三个局部:第一局部,会介绍流计算零碎和一致性难题的实质;第二局部,会介绍一致性难题的通用解法以及各种计划间的取舍;第三局部,会介绍支流的流计算引擎是如何对通用解法进行泛化以实现一致性。

一 流计算中的一致性

在意识流计算零碎一致性之前,咱们须要准确定义流计算。流(Streaming)计算是一种在无边界数据(unbounded data)上进行低提早计算的数据处理过程。相应的,批计算更精确的说法是有界数据(bounded data)的解决,亦即有明确边界的数据处理,流和批只是两种不同数据集的传统数据计算方法,它们并不是若明若暗的,譬如也能够通过批量的形式(e.g. Spark Streaming 中的 micro-batch)来实现无界数据上的流处理过程。

1 一致性定义及挑战

如果咱们将流计算的过程(获取输出数据、解决数据、输入计算结果)视为数据库的主从同步过程,抑或视为一种从流数据生成衍生数据集(表)的过程,则流计算中的数据一致性同关系型数据库事务 ACID 实践中的 Consistency 有殊途同归之妙,后者指的是在事务开始或完结时,数据库中的记录应该在统一状态,相应地,流计算中的一致性能够定义为:流计算零碎在计算过程中,或是呈现故障复原计算后,流零碎的外部状态和内部输入的数据应该处在统一的状态。譬如,当故障复原后开始从新计算,计算的后果是否满足数据的一致性(即用户无奈辨别复原前和复原后的数据)?记录是否会反复 / 失落,第三方系统对同一条计算结果的屡次获取,是否会存在值上的不统一?对一致性有了清晰的认知和定义后,咱们来看看为什么实现一致性这么难。

在定义一中咱们能够看到,流计算输出的数据是无边界的,所以零碎中会存在音讯到达流计算零碎提早、程序错乱、数量 / 规模未知等不确定因素,这也是流计算零碎一致性复杂性远远大于批处理零碎的起因:批处理零碎中的输出是确定的,计算过程中能够通过计算的原子性来保证数据的一致性(如 Spark 中的 RDD 血统)。此外,同其余分布式应用一样,流计算零碎常常也会受到各类意外因素的影响而产生故障,比方流量激增、网络抖动、云服务资源分配呈现问题等,产生故障后从新执行计算,在存在不确定输出的前提下设计强壮的容错机制难度很大。

除了数据输出带来的挑战,流计算输入的数据会被实时生产,相似这样不同于批处理的利用场景,也给数据的一致性带来的诸多挑战,如呈现 FO 后,是撤回之前收回的数据,还是是同上游进行协商实现一致性,都是须要思考的。

2 一致性相干概念祛魅

正确认识流计算零碎一致性的外在含意和其能力领域,对咱们构建正确且强壮的流计算工作至关重要。上面我会介绍几组概念,以便于大家更好地了解流计算零碎的一致性。

恰好一次≠恰好统一

明天大多数流计算引擎用「Exactly-Once」去暗示用户:既然输出的数据不是动态汇合而是会间断变动的,那对每一条音讯「恰好解决」了一次,输入的数据必定是统一的。上述逻辑的推导过程是没问题的,但并不谨严,因为 Exactly-Once 作为一个形容词,前面所连贯的动词或者宾语被成心抹去了,不同的表白含意也会天壤之别。

例子 1,后接不同的动(名)词:Exactly-once Delivery 和 Exactly-once Process。前者是对音讯传输层面的语义表白,和流计算的一致性关系不是很大,后者是从流计算的利用层面去形容数据处理过程。

例子 2,后接不同的名词:Exactly-once State Consistency 和 Exactly-once Process Consistency。前者是 Flink 在官网中对其一致性的叙述,后者是 Kafka Streaming 的一致性保障,前者的语义束缚弱于后者。Exactly-once State Consistency 只是表白了:流计算要求对状态的更新只提交一次到长久后端存储,但这里的状态个别不包含「输入到上游后果」,而仅指引擎外部的状态,譬如各个算子的状态、实时流的生产偏移等,流计算引擎外部状态变更的保障,并不能等价于从输出到输入的一致性,端到端一致性须要你本人关怀。

总之,如何咱们前面再看到 Exactly-once XXX,肯定要警觉引擎想要走漏出什么信息。

端到端的数据一致性

端到端一致性(End-To-Ene Consistency),行将数据的输入也作为流计算引擎的一致性设计的一部分,正确的后果贯通着这整个流计算利用的始终:从输出、处理过程、输入,每一个环节都须要保障其本身的数据一致性,同时在整个流计算流程中,作为整体实现了端到端的一致性。

上面叙述中,如果不是特意阐明,一致性指的是引擎本身状态的一致性,端到端统一指的是蕴含了输入的一致性。

二 流计算零碎的实质

后面咱们定义了流计算一致性的概念,这一部分将会从概念登程将问题进行形式化拆解,以便失去通用化的解法。

1 再次意识流计算

下面提到,流计算的输出数据是没有边界的,这合乎咱们传统上对流计算认知。在《System Streaming》一书中,作者提出了一个将流批对立思考的流计算实践形象,即,任意的数据的解决都是「流(Stream)」和「表(Table)」间的相互转换,其中流用来表征静止中的数据,表用来表征静止的数据:

流 -> 流:没有聚合操作的数据处理过程;
流 -> 表:存在聚合操作的数据处理过程;
表 -> 流:触发输出表数据变动的状况;
表 -> 表:不存在这样的数据处理逻辑。

在这个对立的实践框架下,批处理过程的一致性也能够纳入本文探讨的领域中来。但无论是纯正的流计算,还是下面对立的数据处理模型,咱们都能够将流(批)数据处理的过程形象为「读取数据 - 解决数据 - 输入数据」这样的三个局部,可用上面的无向图来表白,其中点代表数据加工逻辑,边示意数据流向,数据处理过程中的中间状态(State)个别须要做长久化存储。

2 确定性 / 非确定性计算

流计算中的确定性指的是,给定雷同的一组数据,反复运行屡次或者打乱数据进入引擎的程序,计算实现后将会输入雷同的后果,否则就是非确定性计算。常见的非确定性计算包含应用了随机数、应用零碎工夫、字符串拼接等。如果流计算中存在非确定性的计算,则会给端到端一致性的实现造成很多艰难,局部引擎并不能很好地反对此类场景。

3 一致性问题的形式化定义

在存在不确定性计算的流计算中,不确定性计算的(两头)后果可视为流计算引擎状态的一部分。从整体上看,任何一个工夫点的引擎状态等于之前所有事件计算结果(两头后果和输入后果)的累计。如果定义流计算的输出汇合为:E,t 时刻以来的输出汇合为 E(t),输入汇合为 Sink(t),引擎此时状态为 State(t),State(t) 包含各个算子的状态(包含下面提到的不确定性计算)、数据源的生产偏移量(或文件读取偏移等)等:

State(t) = OperatorState(t) + SourceState(t)

则定义流计算引擎的计算过程为,存在计算计算逻辑 F 使得:

F(E(t), Sink(t), State(t)) = Sink(t+1) + State(t)

令 O(t) = Sink(t) + State(t),行将计算对引擎状态的更新视为一种非凡的输入,则流计算过程可简化为:

F(E(t), O(t)) = O(t+1)

联合流计算下面流计算一致性的定义,咱们心愿在引擎产生故障 FailOver 时,存在一种复原函数 R 使得

R(E(t), O(t)) = O'(t+1),且 O'(t+1) = O(t+1)

咱们在这里将引擎状态作为一种非凡输入的思考有两点。其一,引擎的状态个别也是输入到内部存储如 RocksDB/HDFS,这和计算上游的输入别无二致。其二,通过屏蔽引擎外部的容错机制实现,简化端到端一致性问题的形象过程,便于更好地了解问题自身。

三 一致性的通用解法

1 通用解法的推导

咱们在下面定义了端到端一致性难题:R(E(t), O(t)) = O(t+1)。从输入后果的应用方(引擎外部和引擎上游数据生产方)的视角来看:对于记录 O(t+1),当在故障产生的工夫小于 t(数据没有输入)或者 大于 t + 1(数据曾经输入了),数据必定是统一的。

当在 t ~ t + 1 时刻产生故障,复原函数 R 能够屏蔽此次故障产生的副作用,让应用方认为没有故障产生,能够失去正确的 O(t+1),显然,解决的思路是:将 E(t) 和 O(t) 作为输出,从新执行计算 F,则能够失去正确的 O(t+1),具体地,E(t) 能够通过回拨数据偏移量失去,O(t) 须要从长久化存储中获取。O(t) 是否能够通过递归重算失去呢,即 O(t) = F(E(t-1), O(t-1)),答案是不能够,因为计算过程中可能存在不确定的计算逻辑,如果重算,则有肯定概率 O(t) ≠ F(E(t-1), O(t-1))。

因而,咱们失去流计算引擎要实现端到端一致性数据处理语义的充沛必要条件:在流计算过程中,须要实时存储每一条两头和最终计算结果,如果思考吞吐率不能存储每一条,则需定期以事务的形式进行批量存储。对于每一个 O(t) 存储后,复原函数 R 的实现就简略多了:工作复原时,将 O(t) 从新加载,应用 F 执行重算操作。

2 通用解法的工程实现

咱们将端到端一致性问题的解法联合工程实际,剖析一下通用解法下的若干实现场景。

在通用解法中,咱们须要存储每一次计算的两头后果,这对引擎的架构设计、配套基建能力有着很高的要求,如须要高可用、高吞吐的存储后端用于状态存储。因而,咱们将条件进化为能够通过事务的形式进行批量存储,这是因为事务的 ACID 个性能保障后果能以原子提交的形式作用于上游算子或者是内部的音讯零碎 / 数据库,在保障了后果(状态)一致性的前提下,能达到较高的吞吐率。

进一步剖析,每一次存储或者批量事务存储 O(t) 时,引擎到底做了什么?后面咱们定义了 O(t) = Sink(t) + State(t) -> O(t) = Sink(t) + OperatorState(t) + SourceState(t),对于引擎来说,当呈现 FailOver 时,都会通过 SourceState(t) 回拨数据源偏移量进行局部重算,即音讯读取语义是 At-Least-Once 的,当反复计算时,后面存储的后果(每一次计算)或者空的后果(批量事务)能够实现幂等变更的成果:如果后果曾经存在了,则应用已有的后果,打消不确定性计算带来的副作用,如果之前的后果不存在,就更不会对外部零碎有影响了。

如果咱们的计算过程都是确定性的,那么上述的充沛必要条件会有什么变动呢?在确定性计算的前提下,如果引擎输入后果的承受端是能够实现为幂等,则很多约束条件会有所简化。因为 O(t) = Sink(t) + State(t),引擎外部很好实现幂等状态更新,若引擎上游零碎也实现了数据幂等,当在 t ~ t + n 间内呈现 FailOver 时,引擎能够通过从新计算 t ~ t + n 之间的所有值,间接输入给上游应用。

因而,在仅有确定性计算的流计算零碎中,实现端到端的充沛必要条件可进化为:在流计算过程中,须要内部的最终后果承受端实现幂等,实时存储每一条两头和最终计算结果,如果思考吞吐率不能存储每一条,则需定期批量存储,上述条件中去掉了对「事务」的要求的起因:如果在提交这一批数据的提交过程中又产生了异样,譬如只有局部节点的后果输入了,其余节点产生了故障后果失落,则能够通过回到上个批次提交的状态,重算此批次数据,重算过程中,因为仅存在确定性计算,所以无论是引擎内还是引擎外,是能够通过幂等来保证数据的的一致性的。

在理论的流计算引擎实现中,对于后果内容的定义大都是统一的,次要包含输出源的生产偏移 SourceState(t),e.g. Kafka Offset,算子状态 OperatorState(t),e.g. Spark RDD 血统,输入的后果 Sink(t),e.g. Kafka 事务音讯,然而在后果的存储形式上各有所不同,上面咱们来看一看目前业界支流的几个流计算引擎的设计考量。

四 一致性的引擎实现

目前流计算引擎的品种十分多,不是所有的引擎都能够实现端到端统一的流解决,在具备此能力的引擎中,从技术老本、引擎架构、能力范畴思考,会有不同的取舍和实现,如 Flink 中应用了轻量级的「分布式一致性快照」用于状态治理,Kafka Streams 为何没有应用呢?实现了幂等输入就肯定能实现端到端统一么?本章节会一一解答上述问题。

1 Google MillWheel

Google 在 2013 年发了一篇名为《MillWheel: Fault-Tolerant Stream Processing at. Internet Scale》的文章,阐述了在 Google 外部实现低提早数据处理的编程模型和工程实现,前面 Google 在此基础上形象出了 DataFlow 流解决模型(具体参考论文《The Dataflow Model: A Practical Approach to Balancing Correctness, Latency, and Cost in Massive-Scale,Unbounded, Out-of-Order Data Processing》),后者对流计算流域的影响堪比 20 世纪初 GFS,BigTable 以及 MapReduce 三篇论文对大数据的影响,前面 Google 又在 MillWheel 之上持续倒退,开源了 Apache Bean 这个零碎级的流批一体数据解决方案,因为 MillWheel 是更纯正的「流计算」,所以咱们重点来剖析 MillWheel。

MillWheel 应用了一种名为「Strong production」的机制将每个算子的输入在发送至上游之前都进行了长久化存储,一旦产生了故障,当须要复原时,引擎能够间接将存储后的后果收回去。回头再看端到端一致性数据处理语义的充沛必要条件,显然 MillWheel 是合乎「实时存储每一条两头和最终计算结果」这个条件的。对于存在不确定性计算的流计算场景,当 FailOver 时,引擎会从源头从新发送音讯进行重算,屡次计算可能会产生的不统一的后果,但因为「Strong Production」会对计算进行去重,因而即使进行了多次重算,但有且仅有一次重算的后果被输入给上游(上游算子或后果承受端),从整体上来看数据是满足一致性的,这也被称之为「Effective Determinism」。

MillWheel 会对每一条记录赋予一个惟一 ID,同时基于此 ID 保护一份是否解决过以后记录的目录。对于每一条流入以后算子的记录,引擎查找此 ID 目录以确定此记录是否是曾经解决过。这里会有很多技术上的挑战,这里略微举几个例子。

譬如,须要有稳固且高吞吐的存储后端用于后果存储,Google 外部的 BigTable 施展了其作用。流工作执行前后,引擎会对执行流做若干优化,如合并多个逻辑算子至单个算子(相似 Flink 中的 chain 化)、节点内先执行局部合并(count / sum)后再 shuffle 等等,种种伎俩均是为了升高算子间 IO 的数据规模。

此外,在判断「以后记录」是否已被解决时,MillWheel 应用了布隆过滤器用于前置过滤,因为在一个失常运行的流计算工作中,记录绝大多数的工夫都是不反复的,这刚好符合布隆过滤器的应用场景(如过滤器返回不存在则记录肯定不存在),引擎中的每个节点都保护了以记录 ID 为主键的布隆过滤器,计算前都会通过此过滤器进行判断,若提醒不存在则进行数据处理,如果存在,则须要二次校验。当然,MillWheel 在理论应用布隆过滤器,是做了若干革新的,这里就不具体开展了。

2 Apache Flink

MillWheel 作为一个外部零碎能够存储每一个两头后果,然而对于开源零碎的 Apache Flink 来说,毕竟不是每一个公司都有这么齐备的技术基建。Flink 会定期把后果以事务的形式进行批量存储,这里的「后果」如下面剖析,由源状态 SourceState(t)、算子状态 OperatorState(t)、输入的后果 Sink(t) 组成,其中 Flink 把源状态和算子状态进行了打包,统称为「分布式一致性快照」(基于 Chandy-Lamport 分布式快照算法来实现),数据会长久化在 RocksDB 中。

如上图所示,Flink 引擎会定时(每个周期称之为一个 epoch)以 2PC 的形式提交后果。事实上,即使不思考后果输入,Flink「分布式一致性快照」的快照的实现也是一个 2PC 的过程:算子的状态快照存储相似于 2PC 的 Prepare 阶段,但 Commit 的确认仅需 Coordinator(Flink JobManager)依据「是否收到了残缺算子的 ACK」来推出是否 Commit 或 Abort。将后果输入纳入快照生成的 2PC 后,端到端一致性数据处理语义的充沛必要条件在这里也失去了满足:在流计算过程中,定期(epoch)以事务(2PC)的形式进行批量存储后果(分布式一致性快照 + 写内部存储)。须要留神的是,因为 Flink 会以 epoch 为周期输入后果,因而基于此构建的流解决零碎会存在肯定的端到端提早。

3 Apache Kafka Streams

Kafka Streams 是 Apache Kafka 0.10.0 版本中蕴含的一个 Java 库,严格来讲并不算一个残缺的流解决引擎,利用这个库,用户能够基于 Kafka 构建有状态的实时数据处理利用,更进一步地,Kafka Streams 须要数据输出源和输入均为 Kafka 音讯队列。

Kafka Streams 中的「后果」也以事务的形式批量长久化,但和 Flink 不同的是,这些后果是被写入不同的音讯队列中:

源状态 SourceState(t):即 Kafka 源中的 Offset 信息,会被写入一个独自的 Kafaka 队列中,该队列对用户通明;

算子状态 OperatorState(t):计算中算子的 Changelog,也会写入独自的 Kafaka 队列中,该队列对用户通明;

输入后果 Sink(t):即用户配置的理论的输入队列,用于寄存计算结果。

Kafka Streams 将上述后果定期以事务的形式进行批量存储,上述事务在 Kafka 这被称之为 Transactions API,应用这个 API 构建的流解决利用,能够在一个事务中将多个主题音讯进行同时提交,如果事务终止或回滚,则上游生产不会读取到相应的后果(当然上游消费者也须要配置相应的一致性级别),其过程如下图所示:

如果略微回顾一下 Flink 一致性的实现逻辑,会发现这两者有很多类似点,因而 Kafka Streams 的输入后果也会存在肯定的端到端提早。因为在提交后果时创立了新的事务,所以均匀事务大小由提交距离确定,当流量雷同时,较短的提交距离将导致较小的事务,但太小的距离将导致吞吐降落,因而吞吐量与端到端解决提早之间须要有一个折衷。

同时,咱们须要留神到的是,Flink 和 Kafaka 中的「事务」提交,和咱们惯例的操作关系型数据库中的事务还是有所不同的,后者的事务提交对象个别就一个(e.g. MySQL Server),但在流计算中,因为后果有上游输入、生产进度、算子状态等,因而流计算引擎须要设计一个全局的事务协定用于和上游待提交的各个存储后端进行交互。举例:Kafka Streams 的输入后端须要是 Kafka,以配合在事务提交过程中,屏蔽局部已输入至上游(被 Kafka Broker 长久化),但还不满足事务隔离性的音讯(read_committed 级别),从流计算输入的角度来看,这些音讯已被胜利解决同时输入至上游,但从端到端的一致性来看,它们仍然属于不统一的数据。又如,应用 Flink 解决 CDC(Change Data Capture)的场景,如果上游是 MySQL,在 Flink 2PC 实现之前,来自不同 Flink 节点的数据输入后其实曾经被 commit,相似 Kafka Broker 中的音讯无奈撤回,MySQL 提交的事务也无奈回滚,因而输入数据中也须要有相似的字段实现隔离(isolation)语义,以屏蔽这种不统一的数据。

4 Apache Spark Streaming

这里提到的 Spark Streaming 指的是原始的基于「Micro-batch,微批」的 Spark 流解决引擎,前面 Spark 又提出了 Structured Streaming,应用 Continuous Processing mode 来代替「微批」解决提早的问题,容错机制上和 Flink 一样也应用了 Chandy-Lamport 算法,Structured Stream 目前还不成熟,临时还不能齐全反对 Exactly-Once-Processing,因而这里着重比照 Spark Streaming。

Spark Streaming 只能保障引擎外部的解决逻辑是统一的,然而对于后果输入,则并没有做特地的形象,因而如果咱们心愿实现端到端的一致性语义,则须要对自行保护和判断一些信息。同传统的批处理零碎相似,流解决中也是以 RDD 构建出整个的数据血统,当产生 FailOver 时,则从新计算整个 RDD 就能够了。如果 Spark Streaming 存在非确定性的计算,则不能实现端到端统一,起因是:1、不满足条件一「实时存储每一条后果」。如果能记录下每个 RDD 分区下的执行状况,防止反复执行(幂等),也肯定水平上能实现端到端统一,但这须要进行大量的革新工作,最终状态会和 MillWheel 比拟相似;2、不满足条件二「事务形式存储」,须要保障每个 RDD 产出环节的事务性(如最终后果写 HDFS 就不是原子的)。

思考一种比较简单的场景:不存在非确定计算的流计算利用。如果不存在非确定计算,依据端到端的一致性语义的充沛必要条件,只须要承受端实现幂等,则 Spark Streaming 就能够实现端到端的一致性。背地的起因是,当将形式化的后果定义与 Spark Streaming 进行映射,会发现当以「微批」的模式存储后果时,源状态和算子状态以 RDD 血统的形式人造地和输入后果进行了绑定,即当输入最终后果时,咱们其实也一并输入了源和算子状态,操作合乎一致性条件。

更进一步,当把仅有确定性计算(幂等输入)的 Spark Streaming 和 仅有确定性计算(幂等输入)的的 Flink 进行比照时,会发现二者十分类似。RDD 血统类比分布式一致性快照,批量输入类比一致性快照后的后果输入,微批类比 epoch。不同之处在于:1、Spark Streaming 在计算过程中的每一个 RDD 生成阶段都会有提早,而 Flink 在计算过程中能够进行实时处理;2、Spark Streaming 只有一个「epoch」,而 Flink 能够有多个「epoch」并行存在。基于上述两点起因,Flink 的数据处理的端到端提早要小得多,但这两种引擎幂等输入能实现一致性的实质是类似的。

5 各引擎一致性实现总结

下面咱们简述了目前支流的几种流计算引擎的一致性实现机制。从整体来看,如果实现端到端的一致性,则均须要满足咱们下面从形式化定义推导进去的充沛必要条件:实时存储每一条两头和最终计算结果,如果思考吞吐率不能存储每一条,则需定期以事务的形式进行批量存储,这里的后果蕴含流计算引擎中的状态。下面的充沛必要条件还能够进一步简化,即实时存储后果或定期事务,均能够视为以后解决逻辑单元(算子或最终存储)对上游的输出(引擎状态 + 输入后果)进行的幂等化解决:引擎 FailOver -> 输出源的事件会进行重发 -> 后期存储的后果会用于去重 / 事务回滚让后果(引擎状态 + 输入后果)回到上一次的一致性状态 -> 下一批后果输入 -> 后果承受端只影响一次 -> 实现了端到端的统一。

上面的图列举出各引擎实现端到端一致性的路线图:

后面剖析端到端一致性的实现中,重点在剖析引擎解决(算子)和输入端行为,没有提及对数据源的要求,数据源需具备重播(repaly)和音讯去重的性能即可,属于根底要求,这里不再开展。

五 总结与瞻望

本文从流计算的实质登程,推导出了在流解决中实现端到端一致性的通用解法,同时联合通用解法,剖析了目前几种支流流计算引擎在一致性上的实现思路。有「财大气粗」型的 Google MillWheel,背靠弱小的基础架构用于状态治理;有「心灵手巧」型的 Apache Flink,奇妙地联合了分布式一致性快照和两阶段事务实现一致性;也有「重剑无锋」型的 Apache Kafka Streams,间接将流处理过程事务化,屏蔽简单的底层逻辑,编程模型和了解老本都更简略(当然也肯定水平上限度其应用的场景);也有「蓬勃发展」中的 Apache Spark(Structured)Streaming,底层的一些实现构想和 Apache Flink 更加趋同,能够期待它未来能达到相似 Apache Spark 在批处理流域中的位置。

当然,引擎尽管这么多,但其背地是有若干条主线贯通的,心愿咱们能拨开迷雾,不被营销的噱头所影响,能洞察到一些更为实质的货色。本文阐述的端到端统一的流数据处理实现,重点聚焦在「计算和状态」治理,但实际上,还有很多因素须要咱们去思考,如工夫窗口的推导、提早数据的解决策略、底层计算节点的通信容错等,这些问题多多少少也会影响数据的一致性,思考到文中篇幅,这里就不一一开展了,感兴趣的同学能够抉择一个主题做深入研究。

上面这些论文对进一步理解流计算很有帮忙,感兴趣的同学能够参考:

《Streaming System》,T Akidau, S Chernyak, R Lax
《Transactions in Apache Kafka》,Apurva Mehta,Jason Gustafson
《A Survey of State Management in Big Data Processing Systems》,QC To, J Soto, V Markl
《MillWheel: fault-tolerant stream processing at Internet scale》,T Akidau, A Balikov, K Bekiroğlu, S Chernyak
《Discretized Streams: Fault-Tolerant Streaming Computation at Scale》,M Zaharia, T Das, H Li, T Hunter

原文链接
本文为阿里云原创内容,未经容许不得转载。

正文完
 0