【发布时间】:2018-05-11 19:24:08
【问题描述】:
我在 Kafka 中创建带有时间窗口的 KTable 时遇到了一些问题。
我想创建一个像这样计算流中 ID 数量的表。
ID (String) | Count (Long)
X | 5
Y | 6
Z | 7
等等。我希望能够使用 Kafka REST-API 获取表格,最好是 .json。
这是我现在的代码:
StreamsBuilder builder = new StreamsBuilder();
KStream<String, String> streams = builder.stream(srcTopic);
KTable<Windowed<String>, Long> numCount = streams
.flatMapValues(value -> getID(value))
.groupBy((key, value) -> value)
.windowedBy(TimeWindows.of(windowSizeMs).advanceBy(advanceMs))
.count(Materialized.<String, Long, WindowStore<Bytes, byte[]>>as("foo"));
我现在面临的问题是该表不是创建为<String, Long>,而是创建为<String, String>。这意味着我无法获得正确的计数,而是我收到了正确的密钥,但计数已损坏。我尝试使用Long.valueOf(value) 将其强制为Long,但没有成功。我不知道如何从这里开始。我需要将 KTable 写入新主题吗?由于我希望表可以使用 kafka REST-API 进行查询,所以我认为不需要它,对吗? Materialized.<String, Long, WindowStore<Bytes, byte[]>>as("foo") 应该使它可以作为“foo”查询,对吧?
KTable 创建了一个changelog-topic,这足以使其可查询吗?还是我必须为其创建一个新主题才能写入?
我现在正在使用另一个 KStream 来验证输出。
KStream<String, String> streamOut = builder.stream(srcTopic);
streamOut.foreach((key, value) -> System.out.println(key + " => " + value));
它输出:
ID COUNT
2855 => ~
2857 => �
2859 => �
2861 => V(
2863 => �
2874 => �
2877 => J
2880 => �2
2891 => �=
无论哪种方式,我都不想使用 KStream 来收集输出,我想查询 KTable。但如前所述,我不太了解查询的工作原理..
更新
设法让它工作
ReadOnlyWindowStore<String, Long> windowStore =
kafkaStreams.store("tst", QueryableStoreTypes.windowStore());
long timeFrom = 0;
long timeTo = System.currentTimeMillis(); // now (in processing-time)
WindowStoreIterator<Long> iterator = windowStore.fetch("x", timeFrom, timeTo);
while (iterator.hasNext()) {
KeyValue<Long, Long> next = iterator.next();
long windowTimestamp = next.key;
System.out.println(windowTimestamp + ":" + next.value);
}
非常感谢,
【问题讨论】:
标签: java apache-kafka apache-kafka-streams