使用Kafka Streams中的内存状态存储替换RocksDB

时间:2017-01-23 13:33:59

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

状态存储的RocksDB实现无法处理我们的50k / msg速率,所以我想将状态存储更改为内存存储。根据文档http://docs.confluent.io/3.1.0/streams/architecture.html#state

,这应该是可能的

但是,当我实现这个时:

val stateStore = Stores.create(stateStoreName).withStringKeys().withStringKeys().inMemory().build()

val procSuppl: KStreamAggregate = ... // I'll spare the implementation details

streamBuilder.addSource(
  "mysource",
  new StringDeserializer(),
  new StringDeserializer(),
  "input_topic"
).addProcessor("proc", procSuppl,  "mysource").addStateStore(stateStore, "proc")

我在运行时结束了这个错误:

Caused by: java.lang.ClassCastException: org.apache.kafka.streams.state.internals.MeteredKeyValueStore cannot be cast to org.apache.kafka.streams.state.internals.CachedStateStore
2017-01-23T13:19:11.830674020Z  at org.apache.kafka.streams.kstream.internals.KStreamAggregate$KStreamAggregateProcessor.init(KStreamAggregate.java:62)

上述方法的实施是:

public void init(ProcessorContext context) {
        super.init(context);
        store = (KeyValueStore<K, T>) context.getStateStore(storeName);
        ((CachedStateStore) store).setFlushListener(new ForwardingCacheFlushListener<K, V>(context, sendOldValues));
    }

为什么要尝试将状态存储转换为CachedStateStore实例?如何根据文档实现一个简单的内存状态存储?

由于

1 个答案:

答案 0 :(得分:0)

这个问题有点老了,但是也许这个答案会帮助别人。

要创建内存存储,您需要创建存储供应商:

val storeSupplier = Stores.inMemoryKeyValueStore("in-mem")

然后,在实现KTable时需要使用商店供应商:

val wordCounts =  builder.stream[String, String]("streams-plaintext-input")
  .flatMapValues(textLine => textLine.toLowerCase.split("\\W+"))
  .groupBy((_, word) => word)
  .count()(Materialized.as(storeSupplier))

获取可查询的商店:

  val qStore = streams.store(wordCounts.queryableStoreName, QueryableStoreTypes.keyValueStore[String, Long])