Kafka Streams版本0.10.2.0的应用程序问题

时间:2017-03-05 13:33:41

标签: apache-kafka apache-kafka-streams

我有一个现有的Kafka Streams应用程序,它在0.10.1.1下工作正常。更新到新的0.10.2.0 Kafka Streams库以及新的代理(尽管新库向后兼容0.10.1.1)。快速背景

  • 我在基于交互式查询元数据的API
  • 之上构建了一个REST API
  • 搜索本地商店并查询远程商店(使用KafkaStreams.allMetadataForStore方法获取的StreamsMetadata)
  • 使用application.server配置参数以使其正常工作

应用程序可以正常使用单个应用程序实例。一旦我启动另一个实例并通过REST查询商店,我就会遇到以下问题

如果我在首先启动的节点上执行搜索,则本地商店搜索失败并显示此异常

SEVERE: Error - the state store, my-store, may have migrated to another instance.
org.apache.kafka.streams.errors.InvalidStateStoreException: the state store, in-memory-avg-store, may have migrated to another instance.
        at org.apache.kafka.streams.state.internals.StreamThreadStateStoreProvider.stores(StreamThreadStateStoreProvider.java:49)
        at org.apache.kafka.streams.state.internals.QueryableStoreProvider.getStore(QueryableStoreProvider.java:55)
        at org.apache.kafka.streams.KafkaStreams.store(KafkaStreams.java:699)
        **at mycode.getLocalMetrics(myclass.java:121)**
        **at mycode.remote(myclass.java:98)**
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)

如果我在新节点上执行搜索,本地商店搜索没问题,但我在 .forEach(new Consumer()

中看到了一个空指针
ks.allMetadataForStore(storeName)
                    .stream()
                    .filter(sm -> !(sm.host().equals(thisInstance.host()) && sm.port() == thisInstance.port())) //only query remote node stores
                    .forEach(new Consumer<StreamsMetadata>() {
                        @Override
                        public void accept(StreamsMetadata t) {
                            //some logic
                        }

                    });

我能错过什么?

3 个答案:

答案 0 :(得分:2)

也许你需要添加一点睡眠时间&#39;用于创建StreamsMetadata。当我注释掉Thread.sleep(1000L);时,我有同样的错误。

    KafkaStreams streams = new KafkaStreams(builder, props);
    streams.start();

    Thread.sleep(1000L);//If commented out,error occur 
    System.out.println(streams.allMetadataForStore("statestore").size());

答案 1 :(得分:1)

如果启动多个实例,则存储可能会从一个实例迁移到另一个实例。如果在商店迁移之前收集有关商店位置的元数据,则元数据将不再正确。因此,您需要刷新元数据(即再次收集)。

异常 private void button1_Click(object sender, RoutedEventArgs e) { ChangeRowColor(4, Brushes.Green); } 表示您的元数据停滞。

因此,您可以捕获此异常并重试从中恢复。

答案 2 :(得分:0)

基于Matthias J. Sax注释,可以在流状态下加载流存储,如下面的

streams.setStateListener((newState, oldState) -> {
   if (newState == State.RUNNING && oldState.REBALNCING) {
      System.out.println(streams.allMetadataForStore("statestore").size());
   }});