Apache kafka 如何理解卡夫卡流?

Apache kafka 如何理解卡夫卡流?,apache-kafka,apache-kafka-streams,Apache Kafka,Apache Kafka Streams,我正在关注卡夫卡流文档,我对一些我想在这里澄清的概念感到困惑 阅读文档中提到的flatMap时,它获取一条记录并生成零条、一条或多条记录。您也可以修改记录键和值。它还标记要重新分区的数据 问题: 1) 重新分区是什么意思,它会为一个新主题重新分区数据,我将在哪里编写转换的结果,还是在同一主题中重新分区数据,从哪里开始流式处理 2) 如果旧主题数据被重新分区,这是否意味着转换后的结果也被写入该主题 例如: KStream<Long, String> stream = ...; KSt

我正在关注卡夫卡流文档,我对一些我想在这里澄清的概念感到困惑

阅读文档中提到的flatMap时,它获取一条记录并生成零条、一条或多条记录。您也可以修改记录键和值。它还标记要重新分区的数据

问题:

1) 重新分区是什么意思,它会为一个新主题重新分区数据,我将在哪里编写转换的结果,还是在同一主题中重新分区数据,从哪里开始流式处理

2) 如果旧主题数据被重新分区,这是否意味着转换后的结果也被写入该主题

例如:

KStream<Long, String> stream = ...;
KStream<String, Integer> transformed = stream.flatMap(
     // Here, we generate two output records for each input record.
     // We also change the key and value types.
     // Example: (345L, "Hello") -> ("HELLO", 1000), ("hello", 9000)
    (key, value) -> {
      List<KeyValue<String, Integer>> result = new LinkedList<>();
      result.add(KeyValue.pair(value.toUpperCase(), 1000));
      result.add(KeyValue.pair(value.toLowerCase(), 9000));
      return result;
    }
  );
KStream-stream=。。。;
KStream transformed=stream.flatMap(
//这里,我们为每个输入记录生成两个输出记录。
//我们还更改键和值类型。
//示例:(345L,“你好”)->(“你好”,1000),(“你好”,9000)
(键、值)->{
列表结果=新建LinkedList();
add(KeyValue.pair(value.toUpperCase(),1000));
add(KeyValue.pair(value.toLowerCase(),9000));
返回结果;
}
);

在本例中,它获取一条记录并生成两条记录,这是否意味着我开始流媒体的主题现在将有3条记录,一条带345L键,两条带HELLO键。若我把转换后的结果放到一个新主题或一个存储中,那个么新旧主题的状态会是什么呢。两个表都将包含所有3条记录。我是新手。

这是一个转化的结果。因此,当你阅读一个主题时,你不会改变源主题。但是,当您写入另一个主题时,输出接收器主题将有2个值

当它说它标记为重新分区时,它将标记为重新分区的结果;当您写入sink主题时,它将不得不重新分区。它不会重新分区源主题。想想为什么

如果你不断地阅读源主题,它会不断地重新划分源主题吗?所以,这不是一个切实可行的选择。
我希望这能澄清你的问题

这是一个转换的结果。因此,当你阅读一个主题时,你不会改变源主题。但是,当您写入另一个主题时,输出接收器主题将有2个值

当它说它标记为重新分区时,它将标记为重新分区的结果;当您写入sink主题时,它将不得不重新分区。它不会重新分区源主题。想想为什么

如果你不断地阅读源主题,它会不断地重新划分源主题吗?所以,这不是一个切实可行的选择。
我希望这能澄清你的问题

在Kafka Streams中,重新分区意味着将记录发送到处理器之前的中间主题,然后处理器从中间主题读取记录。通过将记录发送到中间主题,记录被重新分区

这是必需的,例如对于联接处理器。Kafka Streams中的连接处理器要求一个分区的所有密钥由同一个任务处理,以确保正确性。如果上游处理器修改了记录的键(如示例中的
flatMap()
),则情况并非如此。除了连接之外,聚合还要求一个分区的所有键由同一个任务处理。重新分区不会向streams应用程序的输入或输出主题写入任何内容,您通常不需要关心中间主题


但是,如果不更改记录的键,则可以使用
*Values()
操作符,如
flatMapValues()
,尽可能避免重新分区。例如,如果使用
flatMap()
,并且不更改记录的键,尽管不需要,但记录仍将被重新分区。如果不使用
flatMapValues()
,Kafka Streams将无法知道您没有触摸该键

在Kafka Streams中,重新分区意味着将记录发送到处理器之前的中间主题,然后处理器从中间主题读取记录。通过将记录发送到中间主题,记录被重新分区

这是必需的,例如对于联接处理器。Kafka Streams中的连接处理器要求一个分区的所有密钥由同一个任务处理,以确保正确性。如果上游处理器修改了记录的键(如示例中的
flatMap()
),则情况并非如此。除了连接之外,聚合还要求一个分区的所有键由同一个任务处理。重新分区不会向streams应用程序的输入或输出主题写入任何内容,您通常不需要关心中间主题


但是,如果不更改记录的键,则可以使用
*Values()
操作符,如
flatMapValues()
,尽可能避免重新分区。例如,如果使用
flatMap()
,并且不更改记录的键,尽管不需要,但记录仍将被重新分区。如果不使用
flatMapValues()
,Kafka Streams将无法知道您没有触摸该键

我可以将这些转换后的结果存储到任何存储区或任何类型的表中,而不是为其创建新主题。如果是的话,那么这件事的缺点是什么呢。如果没有,那么为什么它不是一个选项呢?您可以自己实现这样的处理器。看看这个问题,如果它回答了你的问题,别忘了投票。我可以将这些转换后的结果存储到任何存储区或任何类型的表中,而不是为其创建新主题吗。如果是的话,那么这件事的缺点是什么呢。如果没有,那么为什么它不是一个选项呢?您可以自己实现这样的处理器。看看