151

Flink与 Spark 进行了比较,在我看来,这是错误的比较,因为它将窗口事件处理系统与微批处理进行了比较;同样,将 Flink 与 Samza 进行比较对我来说没有多大意义。在这两种情况下,它都会比较实时和批处理事件处理策略,即使在 Samza 的情况下“规模”较小。但我想知道 Flink 与 Storm 相比如何,后者在概念上似乎更相似。

我发现这个(幻灯片#4)记录了 Flink 的“可调节延迟”的主要区别。另一个提示似乎是Slicon Angle的一篇文章,该文章建议 Flink 更好地集成到 Spark 或 HadoopMR 世界中,但没有提及或引用实际细节。最后,Fabian Hueske 本人在接受采访时指出,“与 Apache Storm 相比,Flink 的流分析功能提供了高级 API,并使用更轻量级的容错策略来提供恰好一次处理的保证。”

所有这些对我来说有点稀疏,我不太明白这一点。有人能解释一下 Flink 完全解决了 Storm 中流处理的哪些问题吗?Hueske 所指的 API 问题及其“更轻量级的容错策略”指的是什么?

4

4 回答 4

229

免责声明:我是 Apache Flink 提交者和 PMC 成员,只熟悉 Storm 的高级设计,而不熟悉它的内部结构。

Apache Flink 是一个统一流和批处理的框架。由于并行任务之间的流水线数据传输(包括流水线洗牌),Flink 的运行时本机支持这两个域。记录立即从生产任务传送到接收任务(在收集到缓冲区以进行网络传输之后)。可以选择使用阻塞数据传输来执行批处理作业。

Apache Spark 是一个还支持批处理和流处理的框架。Flink 的批处理 API 看起来非常相似,并且解决了与 Spark 相似的用例,但内部结构不同。对于流式传输,两个系统都遵循非常不同的方法(小批量与流式传输),这使得它们适用于不同类型的应用程序。我想说比较 Spark 和 Flink 是有效且有用的,但是,Spark 并不是与 Flink 最相似的流处理引擎。

回到最初的问题,Apache Storm 是一个没有批处理功能的数据流处理器。事实上,Flink 的流水线引擎在内部看起来有点像 Storm,即 Flink 的并行任务的接口类似于 Storm 的 bolts。Storm 和 Flink 的共同点是,它们的目标是通过流水线数据传输实现低延迟流处理。但是,与 Storm 相比,Flink 提供了更高级别的 API。Flink 的 DataStream API 提供了 Map、GroupBy、Window 和 Join 等功能,而不是使用一个或多个读取器和收集器来实现螺栓的功能。使用 Storm 时,必须手动实现许多此功能。另一个区别是处理语义。Storm 保证 at-least-once 处理,而 Flink 提供exactly-once。提供这些处理保证的实现有很大不同。Storm 使用记录级别的确认,而 Flink 使用 Chandy-Lamport 算法的变体。简而言之,数据源会定期将标记注入数据流。每当操作员收到这样的标记时,它就会检查其内部状态。当所有数据接收器都接收到标记时,将提交标记(以及之前已处理的所有记录)。在失败的情况下,所有源操作员在看到最后提交的标记时都会重置到他们的状态并继续处理。这种标记检查点方法比 Storm 的记录级确认更轻量级。这个 数据源定期将标记注入数据流。每当操作员收到这样的标记时,它就会检查其内部状态。当所有数据接收器都接收到标记时,将提交标记(以及之前已处理的所有记录)。在失败的情况下,所有源操作员在看到最后提交的标记时都会重置到他们的状态并继续处理。这种标记检查点方法比 Storm 的记录级确认更轻量级。这个 数据源定期将标记注入数据流。每当操作员收到这样的标记时,它就会检查其内部状态。当所有数据接收器都接收到标记时,将提交标记(以及之前已处理的所有记录)。在失败的情况下,所有源操作员在看到最后提交的标记时都会重置到他们的状态并继续处理。这种标记检查点方法比 Storm 的记录级确认更轻量级。这个 当所有源操作员看到最后提交的标记并继续处理时,他们将重置为其状态。这种标记检查点方法比 Storm 的记录级确认更轻量级。这个 当所有源操作员看到最后提交的标记并继续处理时,他们将重置为其状态。这种标记检查点方法比 Storm 的记录级确认更轻量级。这个幻灯片集和相应的演讲讨论了 Flink 的流处理方法,包括容错、检查点和状态处理。

Storm 还提供了一个一次性的高级 API,称为 Trident。然而,Trident 是基于 mini-batch 的,因此更类似于 Spark 而不是 Flink。

Flink 的可调延迟是指 Flink 将记录从一个任务发送到另一个任务的方式。我之前说过,Flink 使用管道数据传输,并在记录产生后立即转发。为了提高效率,这些记录被收集在一个缓冲区中,一旦缓冲区满或达到某个时间阈值,该缓冲区就会通过网络发送。此阈值控制记录的延迟,因为它指定记录将保留在缓冲区中而不被发送到下一个任务的最长时间。但是,它不能用于硬保证记录从进入程序到离开程序所需的时间,因为这还取决于任务内的处理时间和网络传输的数量等。

于 2015-06-08T21:08:56.900 回答
52

添加到 Fabian Hueske 的答案:

Flink 还对 Storm 进行了以下改进:

  • 背压:当不同的算子以不同的速度运行时,Flink 的流式运行时表现良好,因为尽管网络层管理缓冲池,但下游算子对上游算子的背压非常好。

  • 用户自定义状态:Flink 允许程序在您的操作符中维护自定义状态。该状态实际上可以参与检查点以实现容错,为自定义的用户定义状态提供一次性保证。请参阅操作员内部用户定义状态机的示例,该状态机始终与数据流一起设置检查点。

  • 流窗口:流窗口和窗口聚合是分析数据流的重要组成部分。Flink 带有一个非常强大的窗口系统,支持多种类型的窗口。

于 2015-06-23T10:15:40.987 回答
7

免责声明:我是 Cloudera 的员工,是 Storm 和(很快)Flink 的主要支持者。

功能性

已经提出了很多好的技术点。一个非常简短的亮点摘要:

  • Flink 和 Storm 都可以按事件处理
  • Storm 似乎不支持开箱即用的事件时间
  • Storm 尚未将 SQL 支持退出实验阶段

非功能性

  • 许多客户发现 Storm(太)难以使用
  • Storm 采用速度放缓,Flink 社区现在似乎比 Storm 更活跃
  • Flink 仍有一些工作要做(例如记录的示例),但总体而言,它几乎在您可能想到的每个领域都赶上了

结论

Cloudera 最近宣布弃用 Storm(在 HDP 中)。同时 Flink 被宣布为其继任者。

因此,如果您在 Storm 上有用例,它们当然会继续工作。但是对于新的用例,我会研究 Flink 或其他流引擎。

于 2019-12-15T19:43:39.137 回答
4

根据我对 Storm 和 Flink 的经验。我觉得这些工具可以用不同的方法解决同样的问题。@Stephan Ewen 提到的 Flink 的每个特性现在都可以被 Storm 与内部 API(即spoltsbolts)和Trident API 匹配。有人声称Trident是 mini-batch 风格,而我认为大多数具有状态相关或聚合的复杂应用程序只能依赖于具有窗口风格的批处理。所以我在这里只列出一些主要区别,而不说哪个更好。

  • 发展风格。Flink 中面向计算(例如,可链接操作符)与addSpolt()/addBolt()Storm 中面向数据流(例如,)。
  • 高级 API。Flink 中的函数(例如 Map、Window、Join 在 Streaming 级别) vs. Native Window 和 Storm 中的 Trident。
  • 保证消息处理(GMP。即,at-exactly-once。Flink 中带有两阶段提交连接器(例如 KafkaConsumer)的检查点与带有外部状态机的元组树或 Storm 中的 Trident。
  • 容错。Flink 中的标记检查点与 Storm 中的记录级 ACK。
  • 内部架构。Flink 中的简单抽象和相对并行性(例如,考虑 CPU 内核的每个线程的插槽)与 Storm 中的多层抽象(例如,每个 JVM 的插槽作为主管中的工作人员,每个主管可以有许多工作人员)。
于 2019-01-14T04:00:51.630 回答