为什么我必须使用Kafka Streams配置状态存储

时间:2019-12-07 16:53:39

标签: apache-kafka apache-kafka-streams rocksdb

当前,我有以下设置:

StoreBuilder storeBuilder = Stores.keyValueStoreBuilder(
    Stores.persistentKeyValueStore("kafka.topics.table"),
    new SomeKeySerde(),
    new SomeValueSerde());

streamsBuilder.addStateStore(storeBuilder);

final KStream<byte[], SomeClass> requestsStream = streamsBuilder
            .stream("myTopic", Consumed.with(Serdes.ByteArray(), theSerde));
    requestsStream
            .filter((key, request) -> Objects.nonNull(request))
            .process(() -> new SomeClassUpdater("kafka.topics.table", maxNumMatches), "kafka.topics.table");

Properties streamsConfiguration = loadConfiguration();
KafkaStreams streams = new KafkaStreams(streamsBuilder.build(), streamsConfiguration);

streams.start()

为什么我不需要本地状态存储,因为我不使用它进行任何其他计算,并且数据也存储在kafka更新日志中?另外,它什么时候存储在本地存储中,是否存储并提交到变更日志?

我面临的问题是我存储本地语言,并且及时遇到内存问题,尤其是当它经常重新分区时。因为旧的分区仍然围着内存。 所以我的问题是,为什么我们需要用rocksdb持久化:

  1. 数据保留在kafka更新日志中
  2. 容器消失后,ramdisk也消失了。

1 个答案:

答案 0 :(得分:1)

在一个线程上,我们可以有多个等于no的任务。主题分区。每个分区都有自己的状态存储区,这些状态存储区将数据保存到 Changelog(这是Kafka的内部主题)。分区的每个状态存储区还维护其他分区的状态存储区的副本,为了恢复其任务可能失败的分区的数据。

如果您不使用状态存储,而您的任务之一失败,它将转到内部主题,即Changelog,然后将获取分区的数据,这对CPU来说是一项耗时的工作。因此,维护状态存储可减少任务可能失败的时间,并立即从另一个任务状态存储中获取数据。