is/are Flink 和 Storm 之间的主要区别是什么?

What is/are the main difference(s) between Flink and Storm?

Flink 已经 compared to Spark,在我看来,这是错误的比较,因为它将窗口事件处理系统与微批处理进行了比较;同样,将 Flink 与 Samza 进行比较对我来说意义不大。在这两种情况下,它都比较了实时事件处理策略与批处理事件处理策略,即使在 Samza 的情况下 "scale" 更小。但我想知道 Flink 与 Storm 相比如何,Storm 在概念上似乎更相似。

我发现 this (Slide #4) documenting the main difference as "adjustable latency" for Flink. Another hint seems to be an article by Slicon Angle that suggest that Flink better integrates into a Spark or HadoopMR world, but no actual details are mentioned or referenced. Finally, Fabian Hueske himself notes in an interview "Compared to Apache Storm, the stream analysis functionality of Flink offers a high-level API and uses a more light-weight fault tolerance strategy to provide exactly-once processing guarantees."

所有这些对我来说有点稀疏,我不太明白这一点。 有人可以解释 Flink 完全解决了 Storm 中的流处理问题吗? API 问题及其 "more light-weight fault tolerance strategy" 中的 Hueske 指的是什么?

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

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

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

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

Storm 还提供了一个名为 Trident 的 exactly-once 高级 API。然而,Trident 基于 mini-batches,因此更类似于 Spark 而不是 Flink。

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

添加到 Fabian Hueske 的回答中:

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

  • 背压:当不同的算子运行以不同的速度运行时,Flink 的流 运行time 表现良好,因为尽管网络层管理缓冲池,但下游算子可以很好地背压上游算子.

  • 用户自定义状态:Flink 允许程序在你的操作符中维护自定义状态。该状态实际上可以参与容错检查点,为自定义用户定义状态提供精确一次保证。请参阅运算符中用户定义的状态机的 this example,它始终与数据流一起设置检查点。

  • Streaming Windows:Stream windowing 和 window 聚合是分析数据流的重要组成部分。 Flink 自带了一个相当强大的 windowing 系统,支持多种类型的 windows.

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

  • 开发风格。 Flink 中的面向计算(例如,可链式运算符)与 Storm 中的面向数据流(例如,addSpolt()/addBolt())。
  • 高级API。 Flink 与 Native Window 和 Storm 中的 Trident Window 和 Trident
  • 保证消息处理(GMP。即,恰好一次。在 Flink 中使用两阶段提交连接器(例如 KafkaConsumer)的检查点与在 Storm 中使用外部状态机或 Trident 的元组树。
  • 容错。 Flink 中的标记检查点与 Storm 中的记录级 ACK。
  • 内部架构。 Flink 中的简单抽象和相对并行性(例如,考虑CPU 核的每个线程的插槽)与 Storm 中的多层抽象(例如,每个 JVM 的插槽作为主管中的工作人员,每个主管可以有很多工作人员) .

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

功能正常

已经介绍了很多好的技术点。非常简短的亮点摘要:

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

无法正常工作

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

结论

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

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