Akka Stream Kafka vs Kafka Streams

Posted

技术标签:

【中文标题】Akka Stream Kafka vs Kafka Streams【英文标题】: 【发布时间】:2018-01-19 13:25:35 【问题描述】:

我目前正在与 Akka Stream Kafka 合作以与 kafka 进行交互,我想知道与 Kafka Streams 有什么区别。

我知道基于 Akka 的方法实现了响应式规范并处理了 kafka 流似乎缺乏的背压功能。

与 akka 流 kafka 相比,使用 kafka 流有什么优势?

【问题讨论】:

Confluent 在docs.confluent.io/current/streams/… 处解决了背压问题。 “Kafka Streams 不使用背压机制,因为它不需要。”在处理阶段之间,记录永远不会在内存中缓冲。 【参考方案1】:

你的问题很笼统,所以我会从我的角度给出一个笼统的答案。

首先,我有两个使用场景:

    我从 kafka 读取数据、对其进行处理并将一些输出写回 kafka 的情况,对于这些情况,我只使用 kafka 流。 数据源或接收器不是 kafka 的情况,对于我使用 akka 流的情况。

这已经让我可以回答关于背压的部分了:对于上面的第一种情况,kafka 流中有一个背压机制。

现在让我们只关注上述第一个场景。让我们看看如果我决定停止使用 Kafka 流,我会失去什么:

我的一些流处理器阶段需要一个持久(分布式)状态存储,kafka 流为我提供了它。这是 akka 流不提供的东西。 缩放,kafka 流会在流处理器的新实例启动或被杀死时自动平衡负载。这适用于同一个 JVM 以及其他节点:向上和向外扩展。这不是由 akka 流提供的。

这些是对我来说最重要的差异,我希望它对你有意义!

【讨论】:

我想你误解了我的问题,我说的是 akka-streams kafka,它是使用 akka 流构造与 kafka 交互的。 我是这么理解的。 Akka-streams kafka 只是一个包装为 akka-streams 源/接收器的 kafka 消费者/生产者。因此,我的回答似乎是有效的。你觉得哪里不合适? @FredericA。当 Kafka 是源时,关于缩放的观点也适用于 akka 流。如果你决定使用 akka 流,你不会失去它。 @DanielWojda 是正确的,这是通过为流源定义消费者组来实现的。这样每个主题分区将只有一个活动消费者。例如,当使用响应式 kafka 时,此功能由支持流源的 kafka 消费者提供。 案例 2:如果您已经拥有 Kafka 基础架构,则只需部署 Kafka connect 即可继续。【参考方案2】:

Akka Stream 相对于 Kafka Streams 的最大优势在于可以实现非常复杂的处理图,这些处理图可以通过扇入/扇出和反馈循环进行循环。如果我没记错的话,Kafka 流只允许非循环图。在Kafka流之上实现循环处理图会非常复杂

【讨论】:

这是不正确的,循环流可以使用 Kafka 流。【参考方案3】:

发现这篇文章很好地总结了Kafka Streams 提供的分布式设计问题(补充Akka Streams)。

https://www.beyondthelines.net/computing/kafka-streams/

消息排序:Kafka 维护一种仅附加日志,其中存储所有消息,每条消息都有一个序列 ID,也称为其偏移量。偏移量用于指示消息在日志中的位置。 Kafka 流使用这些消息偏移量来维持顺序。

分区:Kafka 将一个主题拆分为多个分区,每个分区在不同的代理之间复制。分区允许分散负载,复制使应用程序具有容错性(如果代理关闭,数据仍然可用)。这有利于数据分区,但我们还需要以类似的方式分配进程。 Kafka Streams 使用依赖于 Kafka 组管理的处理器拓扑。这与 Kafka 消费者用来在代理之间平均分配负载的组管理相同(这项工作主要由代理管理)。

容错:数据复制保证数据容错。组管理具有内置容错功能,因为它在剩余的活动代理实例之间重新分配工作负载。

状态管理:Kafka 流提供由 kafka 更改日志主题支持的本地存储,该主题使用日志压缩(仅保留给定键的最新值)。Kafka 日志压缩

重新处理:当启动一个新版本的应用程序时,我们可以从头开始重新处理日志以计算新状态,然后将流量重定向到新实例并关闭旧应用程序。

时间管理:“流数据永远不会完整,总是会乱序到达”,因此必须区分事件时间和处理时间并正确处理。

作者还说“使用此更改日志主题 Kafka Stream 能够维护应用程序状态的“表格视图”。”

我的看法是,这主要适用于“应用程序状态”为...小的企业应用程序。

对于使用“大数据”的数据科学应用程序,由数据处理、机器学习模型和业务逻辑组合以协调所有这些所产生的“应用程序状态”可能无法通过 Kafka Streams 得到很好的管理。

另外,我认为使用像https://github.com/notxcain/aecor 这样的“纯函数式事件溯源运行时”将有助于使突变显式化并将应用程序逻辑与用于管理持久形式的技术分离通过状态突变和 IO“效果”(函数式编程)的原则性管理来实现状态。

换句话说,业务逻辑不会与Kafka api 纠缠在一起。

【讨论】:

[我的看法是,这主要适用于“应用程序状态”很小的企业应用程序。] - 我宁愿说这是对 Kafka 流实际上是什么的非常短视的看法. Kafka 的核心是对关键值进行操作——“表视图”基本上是对 Kafka 处理的流表对偶性的非常概括的参考。 Kafka 旨在用于(并且实际上)用于真正的大型(巨大?)数据平台。 假设我有一个分析,它产生了一系列已经持久化的大型矩阵(以某种方式:spark RDD 等),我想将域事件发送到引用这些矩阵的其他组件。你会在 Kafka 中自己发送矩阵吗? 对于使用“大数据”的数据科学应用程序:数据已经持久化并且不会发生变化,为此您不需要 Kafka 或 Akka Streams,您需要一个分布式计算框架,例如例如 Spark。【参考方案4】:

Akka Streams 作为 Akka Actors 模型的以数据流为中心的抽象出现。 这些是为 JVM 构建的高性能库,专为通用微服务而设计。

就 Kafka Streams 而言,这些都是用于处理无限数据的客户端库。它们用于从 Kafka 主题读取数据,然后对其进行处理,并将结果写入新主题。

【讨论】:

以上是关于Akka Stream Kafka vs Kafka Streams的主要内容,如果未能解决你的问题,请参考以下文章

失败时优雅地重启 Reactive-Kafka Consumer Stream

Akka(25): Stream:对接外部系统-Integration

Akka(26): Stream:异常处理-Exception handling

Akka(21): Stream:实时操控:人为中断-KillSwitch

RocketMQ与Kafka对比(18项差异)

Akka(23): Stream:自定义流构件功能-Custom defined stream processing stages