从流内部调用Kafka交互式查询

时间:2019-02-21 09:39:27

标签: apache-kafka apache-kafka-streams

我特别需要从Stream内部调用交互式查询。这是因为我需要创建一个新的Stream,该Stream应该具有包含在State Store中的数据。截断的代码如下:

tempModifiedDataStream.to(topic.getTransformedTopic(), Produced.with(Serdes.String(), Serdes.String()));

GlobalKTable<String, String> myMetricsTable = builder.globalTable(
    topic.getTransformedTopic(),
    Materialized.<String, String, KeyValueStore<Bytes, byte[]>>as(
            topic.getTransformedStoreName() /* table/store name */)
        .withKeySerde(Serdes.String()) /* key serde */
        .withValueSerde(Serdes.String()) /* value serde */
);

KafkaStreams streams = new KafkaStreams(builder.build(), kStreamsConfigs());

KStream<String, String> tempAggrDataStream = tempModifiedDataStream
    .flatMap((key, value) -> {
        try {
            List<KeyValue<String, String>> result = new ArrayList<>();

            ReadOnlyKeyValueStore<String, String> keyValueStore =
                streams .store(
                    topic.getTransformedStoreName(),
                    QueryableStoreTypes.keyValueStore());

在最后一行中,要访问状态存储,我需要具有KafkaStreams对象,并且在创建KafkaStreams对象时已完成拓扑结构的确定。这种方法的问题在于,“ tempAggrDataStream”因此不属于拓扑的一部分,并且该部分代码无法执行。而且我无法在下面移动KafkaStreams定义,否则我无法调用交互式查询。

我对Kafka Streams有点陌生;从我这边这是不是很愚蠢?

1 个答案:

答案 0 :(得分:0)

如果您希望在每次修改数据后实现发送主题内容的所有内容,那么我认为您应该使用Processor API。

您可以使用状态存储创建org.apache.kafka.streams.kstream.Transformer。 对于每个处理消息,它将更新状态存储并将所有内容发送到下游。 效率不是很高,因为它将为每个处理消息转发主题/状态存储的全部内容(可以是成千上万条记录)。

如果仅需要 latest 值,就足以将主题cleanup.policy设置为compact。在其他站点上使用KTable,它可以抽象表(流的快照)

用于转发状态存储的全部内容的示例变压器代码如下。整个工作以transform(String key, String value)方法完成。

public class SampleTransformer
        implements Transformer<String, String, KeyValue<String, String>> {

    private String stateStoreName;
    private KeyValueStore<String, String> stateStore;
    private ProcessorContext context;

    public SampleTransformer(String stateStoreName) {
        this.stateStoreName = stateStoreName;
    }

    @Override
    @SuppressWarnings("unchecked")
    public void init(ProcessorContext context) {
        this.context = context;
        stateStore = (KeyValueStore) context.getStateStore(stateStoreName);
    }

    @Override
    public KeyValue<String, String> transform(String key, String value) {
        stateStore.put(key, value);
        stateStore.all().forEachRemaining(keyValue -> context.forward(keyValue.key, keyValue.value));
        return null;
    }

    @Override
    public void close() {

    }
}

可以找到有关处理器APi的更多信息:

可以找到如何将Processor API与Stream DSL结合使用: