Apache Samza和Apache Kafka Streams之间的区别(专注于并行和通信)

Luk*_*bst 18 apache-kafka apache-kafka-streams

在Samza和Kafka Streams中,数据流处理以序列/图形(在Samza中称为"数据流图"和在Kafka Streams中称为"拓扑")的处理步骤(在Samza中称为"作业"和在Kafka Streams中称为"处理器")执行我将在这个问题的其余部分中将这两个术语称为工作流程工作者.

让我们假设我们有一个非常简单的工作流程,包括一个消耗传感器测量值的工人A,并过滤掉低于50的所有值,然后是工人B接收剩余的测量值并过滤80以上的所有值.

输入(Kakfa主题X) - >(工人A) - >(工人B) - >输出(Kafka主题Y)

如果我明白了

正确地说,Samza和Kafka Streams都使用主题分区概念来复制工作流/工作人员,从而并行处理以实现可伸缩性.

但:

  • Samza将每个工作者(即作业)分别复制到多个任务(输入流中的每个分区一个).也就是说,任务是工作流的工作者的副本.

  • Kafka Streams一次将整个工作流程(即拓扑)复制到多个任务(输入流中的每个分区一个).也就是说,任务是整个工作流程的复制品.

这让我想到了我的问题:

  1. 假设只有一个分区:它是否正确,是不可能在Kafka Streams中的两台不同的机器上部署worker(A)和(B),而在Samza中这是可能的?(换句话说:无论是否有多个分区,Kafka Streams都无法将单个任务(即拓扑副本)拆分为两台机器.)

  2. Kafka Streams拓扑中的两个后续处理器(在同一任务中)如何通信?(我知道在Samza中,两个后续工作人员(即工作)之间的所有通信都是用Kafka主题完成的,但是由于必须在代码中明确地在Kafka Streams中"标记"哪些流必须作为Kafka主题发布,否则这不可能在这里是这样的.)

  3. Samza是否自动发布所有中间流作为Kafka主题(并因此使其可供潜在客户使用)是正确的,而Kafka Streams仅发布明确标记的中间和最终流(addSink在低级API和/ tothroughDSL中) )?

(我知道Samza可以使用其他消息队列而不是Kafka,但这与我的问题无关.)

小智 9

首先,在Samza和Kafka Streams中,您可以选择是否在这两个任务(处理器)之间设置中间主题,即拓扑可以是:

输入(Kakfa主题X) - >(工人A) - >(工人B) - >输出(Kafka主题Y)

要么:

输入(Kakfa主题X) - >(工人A) - >中级(Kafka主题Z) - >(工人B) - >输出(Kafka主题Y)

在Samza或Kafka Streams中,在前一种情况下,您必须将Worker A和B部署在一起,而在后一种情况下,您不能将Worker A或B部署在一起,因为在任一框架任务中只通过中间主题进行通信,并且没有基于TCP的通信渠道.

在Samza中,对于前一种情况,您需要将两个过滤器编码为一个任务,对于后一种情况,您需要为每个任务指定输入和输出主题,例如,对于Worker A输入为X且输出为Z ,对于工件B输入为Z且输出为Y,您可以独立启动/停止已部署的工作人员.

在Kafka Streams中,对于前一种情况,您可以"连接"这些处理器

stream1.filter(..).filter(..)
Run Code Online (Sandbox Code Playgroud)

因此像Lucas提到的那样,第一个过滤器的每个结果都会立即传递给第二个过滤器(你可以想到主题X中的每个输入记录都以深度优先顺序遍历拓扑,并且任何直接之间都没有缓冲连接处理器);

对于后一种情况,您可以指示中间流在另一个主题中"物化",即:

stream1.filter(..).through("topicZ").filter(..)
Run Code Online (Sandbox Code Playgroud)

并且第一个过滤器的每个结果将被发送到主题Z,然后将其流水线化到第二个过滤器处理器.在这种情况下,这两个过滤器可能部署在同一主机中的不同主机或不同线程上.