我有一个现有的Kafka Streams应用程序,它在0.10.1.1下工作正常。更新到新的0.10.2.0 Kafka Streams库以及新的代理(尽管新库向后兼容0.10.1.1)。快速背景
应用程序可以正常使用单个应用程序实例。一旦我启动另一个实例并通过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
}
});
我能错过什么?
答案 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());
}});