Kafka流如何处理分布式数据

时间:2019-05-08 15:02:27

标签: apache-kafka apache-kafka-streams

我尝试过各种教程,但对Kafka流的两个方面尚不清楚。 让我们以下面提到的单词计数示例为例: https://docs.confluent.io/current/streams/quickstart.html

// Serializers/deserializers (serde) for String and Long types
final Serde<String> stringSerde = Serdes.String();
final Serde<Long> longSerde = Serdes.Long();

// Construct a `KStream` from the input topic "streams-plaintext-input", where message values
// represent lines of text (for the sake of this example, we ignore whatever may be stored
// in the message keys).
KStream<String, String> textLines = builder.stream("streams-plaintext-input", Consumed.with(stringSerde, stringSerde));

KTable<String, Long> wordCounts = textLines
// Split each text line, by whitespace, into words.  The text lines are the message
// values, i.e. we can ignore whatever data is in the message keys and thus invoke
// `flatMapValues` instead of the more generic `flatMap`.
.flatMapValues(value -> Arrays.asList(value.toLowerCase().split("\\W+")))
// We use `groupBy` to ensure the words are available as message keys
.groupBy((key, value) -> value)
// Count the occurrences of each word (message key).
.count();

// Convert the `KTable<String, Long>` into a `KStream<String, Long>` and write to the output topic.
wordCounts.toStream().to("streams-wordcount-output", 
Produced.with(stringSerde, longSerde));

问题在这里:
1.)由于原始流中没有键,因此两个单词可以落在两个不同的节点上,因为它们可能落在不同的分区中,因此真实计数将是两个单词的总和。看来这里不行吗?在同一主题的分区中服务的不同节点是否在此处进行汇总以汇总计数?
2.)由于每个操作都会生成新的流(例如flatMapValues,groupBy等),因此会为这些子流中的消息重新计算分区,以使它们降落在不同的节点上?

在这里感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

  

1。)由于原始流中没有键,因此两个单词可以落在两个不同的节点上,因为它们可能落在不同的分区中,因此,真实计数将是两个单词的总和。看来这里不行吗?

在这里完成。这是相关代码:

// We use `groupBy` to ensure the words are available as message keys
.groupBy((key, value) -> value)

在这里,“单词”成为新的消息密钥,这意味着单词将被重新分区,从而每个单词只能放入一个分区。

  

在这里,服务于同一主题分区的不同节点是否进行协调以汇总计数?

不,他们没有。分区仅由一个节点处理(更准确地说:仅由一个流任务处理,请参见下文)。

  

2。)随着每个操作(例如flatMapValues,groupBy等)生成新的流,是否在这些子流中为消息重新计算了分区,以便它们落在不同的节点上?

不确定我是否理解您的问题,尤其是“重新计算”的评论。操作(如聚合)始终在每个分区上执行,Kafka Streams将分区映射到流任务(略有简化:一个分区始终由一个且仅一个流任务处理)。 Stream任务由您的Kafka Streams应用程序的各种实例执行,这些实例通常在不同的容器/ VM /机器上运行。如果需要,将需要对数据进行重新分区(请参阅问题1和上面的答案),以进行操作以产生预期的结果-也许这就是您说“重新计算”时的意思。

我建议阅读Kafka的文档,例如https://kafka.apache.org/documentation/streams/architecture#streams_architecture_tasks