更改Kafka流拓扑(添加重新分区步骤)是否会对消息处理保证产生任何影响

时间:2018-01-04 12:33:28

标签: java apache-kafka apache-kafka-streams

假设我想进行一些'A'变换可配置。此转换使用状态存储管理某个状态,还需要重新分区,这意味着只有在配置时才会进行重新分区。现在,如果我以下列方式(或任何其他组合)运行应用程序3次(也可能是滚动升级): -

  1. 转化'A'已停用

  2. 转化'A'已启用

  3. 转化'A'已停用

  4. 鉴于所有3次运行都使用相同的Kafka经纪人群集: -

    1. 如果启用了EOS,所有3次运行中是否都会存在EOS保证?

    2. 如果未启用EOS,是否存在可能导致邮件丢失的情况(甚至无法提供至少一次)?

    3. 拓扑代码,以便更好地理解我想要做的事情: -

      KStream<String, Cab> kStream = getStreamsBuilder()
                  .stream("topic_a", Consumed.with(keySerde, valueSerde))
                  .transformValues(() -> transformer1)
                  .transformValues(() -> transformer2, "stateStore_a")
                  .flatMapValues(events -> events);
      
          mayBeEnrichAgain(kStream, keySerde, valueSerde)
                  .selectKey((ignored, event) -> event.getAnotherId())
                  .through(INTERMEDIATE_TOPIC_2, Produced.with(keySerde, valueSerde)) //this repartitioning will always be there
                  .transformValues(() -> transformer3, "stateStore_b")
                  .to(txStreamsConfig.getAlertTopic(), Produced.with(keySerde, valueSerde));
      
      
      
      
      private <E extends Cab> KStream<String, E> mayBeEnrichAgain(final KStream<String, E> kStream,
              final Serde<String> keySerde,
              final Serde<E> valueSerde) {
      
          if(enrichmentEnabled){ //repartitioning is configurable
                  return kStream.selectKey((ignored, event) -> event.id())
                          .through(INTERMEDIATE_TOPIC_1, Produced.with(keySerde, valueSerde))
                          .transformValues(enricher1)
                          .transformValues(enricher2);
          }
          else{
                  return kStream;
          }
      }
      

1 个答案:

答案 0 :(得分:1)

您不能简单地更改拓扑而不会破坏它。

一般来说,如果插入贯穿主题将首先破坏应用程序,很难说。

如果没有破坏,你可能会松散&#34;删除主题时的数据,因为某些未处理的数据可能仍在本主题中,并且在删除主题后,拓扑结构将不会读取这些数据。

通常,如果将应用程序升级到更改拓扑结构的较新版本,则应该干净地重置应用程序或使用新的application.id