我有一个kafka主题和一个听它的KTable。
我想编写一个http POST请求,它将遍历ktable中的当前项,对它们执行一些操作并回写主题
基本上我有:
private val accessTokenTable: KTable[String, String] = builder.table(token_topic_name, tokenStoreString)
val stream: KafkaStreams = new KafkaStreams(builder, streamingConfig)
stream.cleanUp()
stream.start()
...
override def refreshTokens = {
accessTokenTable.mapValues {
new ValueMapper[String, String] {
override def apply(value: String) = {
value
}
}
}.print(token_topic_name)
}
当我尝试调用此方法时,没有任何内容打印/写入主题
我错过了什么?我唯一的选择是将消息从ktable写入hashmap并从那里读取它?它错过了ktables的全部意义?答案 0 :(得分:2)
正确的解决方案是使用GlobalKTable来避免"状态存储可能已迁移到另一个实例"所讨论的错误here。
既然你回答了自己的问题并且在你的后续工作中显然遇到了另一个问题,那么让我扩展一下你在答案中所说的内容,以帮助其他读者解决这个问题。
注意:通常情况下,您不能在KTable与GlobalKTable之间做出决定,因为您要阻止"州商店可能已迁移"情况,但因为这两个抽象为您的应用程序提供了不同的语义。例如,使用KTable而不是GlobalKTable有很多充分的理由 - 如果你这样做,你只需要知道我们刚才讨论过的内容(文档中也包含这些内容,但显然不是很明显/考虑到你确实碰到了这个问题,我已经足够清楚了。)
希望这有帮助!
答案 1 :(得分:0)
经过长时间的调查,解决方案是查询它后面的商店(rocksDB)而不是表格。
如此处所述:confluent
正确的解决方案是使用GlobalKTable来避免"状态存储可能已迁移到另一个实例"所讨论的错误here。
这段代码在kafka 0.10.2.1中为我工作:
private val accessTokenTable: GlobalKTable[String, String] = builder.globalTable(token_topic_name, token_store_string)
private val stream: KafkaStreams = new KafkaStreams(builder, streamingConfig)
stream.cleanUp()
stream.start()
val store: ReadOnlyKeyValueStore[String,String] = stream.store(token_store_string,QueryableStoreTypes.keyValueStore[String,String]())
...
override def refreshTokensFlow = {
store.all.asScala.map( tuple => {
// logic goes here
System.out.println(tuple.key + ": " + tuple.value)
}
}