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