问题
StreamsBuilder builder = new StreamsBuilder();
Map<String, ?> serdeConfig = Collections.singletonMap(SCHEMA_REGISTRY_URL_CONFIG, schemaRegistryUrl);
Serde keySerde= getSerde(keyClass);
keySerde.configure(serdeConfig,true);
Serde valueSerde = getSerde(valueClass);
valueSerde.configure(serdeConfig,false);
StoreBuilder<KeyValueStore<K,V>> store =
Stores.keyValueStoreBuilder(
Stores.persistentKeyValueStore("mystore"),
keySerde,valueSerde).withCachingEnabled();
builder.addGlobalStore(store,"mytopic", Consumed.with(keySerde,valueSerde),this::processMessage);
streams=new KafkaStreams(builder.build(),properties);
registerShutdownHook();
streams.start();
readOnlyKeyValueStore = waitUntilStoreIsQueryable("mystore", QueryableStoreTypes.<Object, V>keyValueStore(), streams);
private <T> T waitUntilStoreIsQueryable(final String storeName,
final QueryableStoreType<T> queryableStoreType,
final KafkaStreams streams) {
// 25 seconds
long timeout=250;
while (timeout>0) {
try {
timeout--;
return streams.store(storeName, queryableStoreType);
} catch (InvalidStateStoreException ignored) {
// store not yet ready for querying
try {
Thread.sleep(100);
} catch (InterruptedException e) {
logger.error(e);
}
}
}
throw new StreamsException("ReadOnlyKeyValueStore is not queryable within 25 seconds");
}
The error is as follows:
19:42:35.049 [my_component.app-91fa5d9f-aba8-4419-a063-93635903ff5d-GlobalStreamThread] ERROR org.apache.kafka.streams.processor.internals.GlobalStreamThread$StateConsumer - global-stream-thread [my_component.app-91fa5d9f-aba8-4419-a063-93635903ff5d-GlobalStreamThread] Updating global state failed. You can restart KafkaStreams to recover from this error.
org.apache.kafka.clients.consumer.OffsetOutOfRangeException: Offsets out of range with no configured reset policy for partitions: {my_component-0=6}
at org.apache.kafka.clients.consumer.internals.Fetcher.parseCompletedFetch(Fetcher.java:990) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.clients.consumer.internals.Fetcher.fetchedRecords(Fetcher.java:491) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.clients.consumer.KafkaConsumer.pollForFetches(KafkaConsumer.java:1269) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1200) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1176) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.streams.processor.internals.GlobalStreamThread$StateConsumer.pollAndUpdate(GlobalStreamThread.java:239) [kafka-streams-2.3.0.jar:?]
at org.apache.kafka.streams.processor.internals.GlobalStreamThread.run(GlobalStreamThread.java:290) [kafka-streams-2.3.0.jar:?]
19:42:35.169 [my_component.app-91fa5d9f-aba8-4419-a063-93635903ff5d-GlobalStreamThread] ERROR org.apache.kafka.streams.KafkaStreams - stream-client [my_component.app-91fa5d9f-aba8-4419-a063-93635903ff5d] Global thread has died. The instance will be in error state and should be closed.
19:42:35.169 [my_component.app-91fa5d9f-aba8-4419-a063-93635903ff5d-GlobalStreamThread] ERROR org.apache.zookeeper.server.NIOServerCnxnFactory - Thread Thread[my_component.app-91fa5d9f-aba8-4419-a063-93635903ff5d-GlobalStreamThread,5,main] died
org.apache.kafka.streams.errors.StreamsException: Updating global state failed. You can restart KafkaStreams to recover from this error.
at org.apache.kafka.streams.processor.internals.GlobalStreamThread$StateConsumer.pollAndUpdate(GlobalStreamThread.java:250) ~[kafka-streams-2.3.0.jar:?]
at org.apache.kafka.streams.processor.internals.GlobalStreamThread.run(GlobalStreamThread.java:290) ~[kafka-streams-2.3.0.jar:?]
Caused by: org.apache.kafka.clients.consumer.OffsetOutOfRangeException: Offsets out of range with no configured reset policy for partitions: {my_component-0=6}
at org.apache.kafka.clients.consumer.internals.Fetcher.parseCompletedFetch(Fetcher.java:990) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.clients.consumer.internals.Fetcher.fetchedRecords(Fetcher.java:491) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.clients.consumer.KafkaConsumer.pollForFetches(KafkaConsumer.java:1269) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1200) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1176) ~[kafka-clients-2.2.1.jar:?]
at org.apache.kafka.streams.processor.internals.GlobalStreamThread$StateConsumer.pollAndUpdate(GlobalStreamThread.java:239) ~[kafka-streams-2.3.0.jar:?]
... 1 more
org.apache.kafka.streams.errors.InvalidStateStoreException: State store is not available anymore and may have been migrated to another instance; please re-discover its location from the state metadata.
at org.apache.kafka.streams.state.internals.CompositeReadOnlyKeyValueStore.get(CompositeReadOnlyKeyValueStore.java:60)
I see two different exceptions.
InvalidStateStoreException - store is not open
InvalidStateStoreException - Store is not available any more and might have migrated to another instance
I have only one instance of the stream application running on Windows with an application id.
From the above core, I am waiting until the store is queryable, but still I get store not open and store may not be available.
What are the possible reasons for the exception (and its solution)?
First of all, is the above code write-up correct?
回答1:
OffsetOutOfRangeException
means that the offsets that are stored in the state in the .checkpoint
file are out of range with those offsets of the topic in the Kafka cluster.
This happens when the topic is cleared and or re-created. It may not contain those many messages as that of the given offsets in the checkpoint.
I have found that, resetting the .checkpoint
file will help.
The .checkpoint
file will be something like this.
0
1
my_component 0 6
my_component 1 0
Here, 0 is partition and 6 is offset. Similarly, 1 is partition and 0 is offset.
The description my_component-0-6
in the exception means that 6th offset of 0th partition of my_component
topic is out of range.
Since, the topic is re-created, the 6th offset does not exist. So change 6 to 0.
It is important to note that, while unit testing Kafka, you must clean up the state directory once the test is complete, because your embedded Kafka cluster and its topics does not exist after the test is completed and therefore it does not make sense to retain the offsets in your state store (since they will become stale).
So, ensure that your state directory (typically, /tmp/kafka-streams
or in Windows C:\tmp\kafka-streams
) is cleaned up after the test.
Also, resetting the checkpoint file is only a workaround, and is not an ideal solution in production.
In production, if the state store is in-compatible with that of its corresponding topic (that is offsets are out of range), then it means that there is some corruption, possible some one might have deleted and re-created the topic.
In such a situation, I think, clean up might be the only possible solution. Because, your state store contains stale information which is therefore no longer valid (so far as new topic is concerned).
来源:https://stackoverflow.com/questions/57204267/invalidstatestoreexception-the-state-store-is-not-open-in-kafka-streams