Use Kafka Streams para de janelas de dados e processamento de cada janela de uma só vez

simo:

O objetivo que eu quero alcançar é agrupar pelo usuário algumas mensagens que recebo de um tópico Kafka e janela-los, a fim de agregar as mensagens que recebo na janela (5 minutos). Então eu gostaria de recolher todos os agregados em cada janela, a fim de processá-los de uma só vez de adicioná-los a um relatório de todas as mensagens que recebi nos 5 minutos de intervalo.

O último ponto parece ser a parte mais difícil como Kafka Streams não parecem fornecer (pelo menos eu não posso encontrá-lo!) Tudo o que pode coletar todo o material relacionado a janela em um "finito" fluxo a ser processado em um só lugar .

Este é o código que eu implementado

StreamsBuilder builder = new StreamsBuilder();
KStream<UserId, Message> messages = builder.stream("KAFKA_TOPIC");

TimeWindowedKStream<UserId, Message> windowedMessages =
        messages.
                groupByKey().windowedBy(TimeWindows.of(SIZE_MS));

KTable<Windowed<UserId>, List<Message>> messagesAggregatedByWindow =
        windowedMessages.
                aggregate(
                        () -> new LinkedList<>(), new MyAggregator<>(),
                        Materialized.with(new MessageKeySerde(), new MessageListSerde())
                );

messagesAggregatedByWindow.toStream().foreach((key, value) -> log.info("({}), KEY {} MESSAGE {}",  value.size(), key, value.toString()));

KafkaStreams streams = new KafkaStreams(builder.build(), config);
streams.start();

O resultado é algo como

KEY [UserId(82770583)@1531502760000/1531502770000] Message [Message(userId=UserId(82770583),message="a"),Message(userId=UserId(82770583),message="b"),Message(userId=UserId(82770583),message="d")]
KEY [UserId(77082590)@1531502760000/1531502770000] Message [Message(userId=UserId(77082590),message="g")]
KEY [UserId(85077691)@1531502750000/1531502760000] Message [Message(userId=UserId(85077691),message="h")]
KEY [UserId(79117307)@1531502780000/1531502790000] Message [Message(userId=UserId(79117307),message="e")]
KEY [UserId(73176289)@1531502760000/1531502770000] Message [Message(userId=UserId(73176289),message="r"),Message(userId=UserId(73176289),message="q")]
KEY [UserId(92077080)@1531502760000/1531502770000] Message [Message(userId=UserId(92077080),message="w")]
KEY [UserId(78530050)@1531502760000/1531502770000] Message [Message(userId=UserId(78530050),message="t")]
KEY [UserId(64640536)@1531502760000/1531502770000] Message [Message(userId=UserId(64640536),message="y")]

Para cada janela há muitas linhas de registo e eles são misturados com as outras janelas.

O que eu gostaria de ter é algo como:

// Hypothetical implementation
windowedMessages.streamWindows((interval, window) -> process(interval, window));

onde o processo método seria algo como:

// Hypothetical implementation

void process(Interval interval, WindowStream<UserId, List<Message>> windowStream) {
// Create report for the whole window   
Report report = new Report(nameFromInterval());
    // Loop on the finite iterable that represents the window content
    for (WindowStreamEntry<UserId, List<Message>> entry: windowStream) {
        report.addLine(entry.getKey(), entry.getValue());
    }
    report.close();
}

O resultado seriam agrupados como este (cada relatório é uma chamada para o meu retorno de chamada: processo void (...)) e o commit de cada janela seria cometido quando toda a janela é processado:

Report 1:
    KEY [UserId(85077691)@1531502750000/1531502760000] Message [Message(userId=UserId(85077691),message="h")]

Report 2:
    KEY [UserId(82770583)@1531502760000/1531502770000] Message [Message(userId=UserId(82770583),message="a"),Message(userId=UserId(82770583),message="b"),Message(userId=UserId(82770583),message="d")]
    KEY [UserId(77082590)@1531502760000/1531502770000] Message [Message(userId=UserId(77082590),message="g")]
    KEY [UserId(73176289)@1531502760000/1531502770000] Message [Message(userId=UserId(73176289),message="r"),Message(userId=UserId(73176289),message="q")]
    KEY [UserId(92077080)@1531502760000/1531502770000] Message [Message(userId=UserId(92077080),message="w")]
    KEY [UserId(78530050)@1531502760000/1531502770000] Message [Message(userId=UserId(78530050),message="t")]
    KEY [UserId(64640536)@1531502760000/1531502770000] Message [Message(userId=UserId(64640536),message="y")]

Report 3
    KEY [UserId(79117307)@1531502780000/1531502790000] Message [Message(userId=UserId(79117307),message="e")]
Bruno:

Eu tive a mesma dúvida. Eu já falei com os desenvolvedores da biblioteca e eles disseram que este é um pedido muito comum ainda não foi implementado. Ele será lançado em breve.

Você pode encontrar mais informações aqui: https://cwiki.apache.org/confluence/display/KAFKA/KIP-328%3A+Ability+to+suppress+updates+for+KTables

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=176635&siteId=1
Recomendado
Clasificación