InvalidStateStoreException при присоединении к KStream с использованием GlobalKtables

У меня есть приложение Kafka Streams, в котором я присоединяюсь к KStream, который читает из topic1 с GlobalKTable, который читает из topic2, а затем с другим GlobalKTable, который читает из topic3.

Когда я пытаюсь отправить сообщения во все 3 темы одновременно, я получаю следующее исключение -

org.apache.kafka.streams.errors.InvalidStateStoreException

Если я отправляю сообщения одно за другим в этих темах, то есть отправляю сообщения в тему2, затем в тему3, а затем в тему1, я не получаю этого исключения.

Я также добавил StateListener перед запуском KafkaStreams

KafkaStreams.StateListener stateListener = new KafkaStreams.StateListener() {
            @Override
            public void onChange (KafkaStreams.State newState, KafkaStreams.State oldState) {
                if(newState == KafkaStreams.State.REBALANCING) {
                    try {
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
streams.setStateListener(stateListener);
streams.start();

Также я жду, пока хранилище не станет доступным для запроса после запуска потока, вызвав следующий метод

public static  <T> T waitUntilStoreIsQueryable(final String storeName,
                                                   final QueryableStoreType<T> queryableStoreType,
                                                   final KafkaStreams streams) throws InterruptedException {
        while (true) {
            try {
                return streams.store(storeName, queryableStoreType);
            } catch (final InvalidStateStoreException ignored) {
                // store not yet ready for querying
                Thread.sleep(100);
            }
        }
    }

Ниже приведен код соединения Kafka Streams и GlobalKTable:

KStream<String, GenericRecord> topic1KStream =
           builder.stream(
               "topic1",
               Consumed.with(Serdes.String(), genericRecordSerde)
           );
GlobalKTable<String, GenericRecord> topic2KTable =
           builder.globalTable(
               "topic2",
               Consumed.with(Serdes.String(), genericRecordSerde),
               Materialized.<String, GenericRecord, KeyValueStore<Bytes, byte[]>>as("topic2-global-store")
                   .withKeySerde(Serdes.String())
                   .withValueSerde(genericRecordSerde)
           );
  GlobalKTable<String, GenericRecord> topic3KTable =
           builder.globalTable(
               "topic3",
               Consumed.with(Serdes.String(), genericRecordSerde),
               Materialized.<String, GenericRecord, KeyValueStore<Bytes, byte[]>>as("topic3-global-store")
                   .withKeySerde(Serdes.String())
                   .withValueSerde(genericRecordSerde)
           );

KStream<String, MergedObj> stream_topic1_topic2 = topic1KStream.join(
           topic2KTable,
           (topic2Id, topic1Obj) -> topic1.get("id").toString(),
           (topic1Obj, topic2Obj) -> new MergedObj(topic1Obj, topic2Obj)
       );
       final KStream<String, GenericRecord> enrichedStream =
        stream_topic1_topic2.join(
           topic3KTable,
           (topic2Id, mergedObj) -> mergedObj.topic3Id(),
           (mergedObj, topic3Obj) -> new Enriched(
               mergedObj.topic1Obj,
               mergedObj.topic2Obj,
               topic3Obj
           ).enrich()
       );
enrichedStream.to("enrichedStreamTopic", Produced.with(Serdes.String(),getGenericRecordSerde()));

Приведенный выше код очень похож на this.

Когда я пытаюсь отправить сообщения во все 3 темы одновременно, я получаю следующее исключение:

org.apache.kafka.streams.errors.StreamsException: Exception caught in process. taskId=0_1, processor=KSTREAM-SOURCE-0000000000, topic=topic1,
partition=1, offset=61465,
stacktrace=org.apache.kafka.streams.errors.InvalidStateStoreException:
Store topic2-global-store is currently closed.
    at
org.apache.kafka.streams.state.internals.WrappedStateStore.validateStoreOpen(WrappedStateStore.java:66)
    at
org.apache.kafka.streams.state.internals.CachingKeyValueStore.get(CachingKeyValueStore.java:150)
    at
org.apache.kafka.streams.state.internals.CachingKeyValueStore.get(CachingKeyValueStore.java:37)
    at
org.apache.kafka.streams.state.internals.MeteredKeyValueStore.get(MeteredKeyValueStore.java:135)
    at
org.apache.kafka.streams.processor.internals.ProcessorContextImpl$KeyValueStoreReadOnlyDecorator.get(ProcessorContextImpl.java:245)
    at
org.apache.kafka.streams.kstream.internals.KTableSourceValueGetterSupplier$KTableSourceValueGetter.get(KTableSourceValueGetterSupplier.java:49)
    at
org.apache.kafka.streams.kstream.internals.KStreamKTableJoinProcessor.process(KStreamKTableJoinProcessor.java:71)
    at
org.apache.kafka.streams.processor.internals.ProcessorNode.process(ProcessorNode.java:117)
    at
org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:183)
    at
org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:162)
    at
org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:122)
    at
org.apache.kafka.streams.processor.internals.SourceNode.process(SourceNode.java:87)
    at
org.apache.kafka.streams.processor.internals.StreamTask.process(StreamTask.java:364)
    at
org.apache.kafka.streams.processor.internals.AssignedStreamsTasks.process(AssignedStreamsTasks.java:199)
    at
org.apache.kafka.streams.processor.internals.TaskManager.process(TaskManager.java:420)
    at
org.apache.kafka.streams.processor.internals.StreamThread.runOnce(StreamThread.java:890)
    at
org.apache.kafka.streams.processor.internals.StreamThread.runLoop(StreamThread.java:805)
    at
org.apache.kafka.streams.processor.internals.StreamThread.run(StreamThread.java:774)

person Kavita    schedule 06.05.2019    source источник


Ответы (1)


Я исправил проблему в моем коде, который был auto.register.schemas=false, потому что я вручную зарегистрировал схемы для всех моих тем.

После того, как я установил auto.register.schemas=true и повторно запустил потоковое приложение, все заработало. Думаю, ему нужен этот флаг для своих внутренних тем.

person Kavita    schedule 08.05.2019