Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用反应式api将卡夫卡主题读到最后_Java_Apache Kafka_Project Reactor - Fatal编程技术网

Java 使用反应式api将卡夫卡主题读到最后

Java 使用反应式api将卡夫卡主题读到最后,java,apache-kafka,project-reactor,Java,Apache Kafka,Project Reactor,我们使用压缩卡夫卡主题来存储状态更改,在重新启动或重新平衡期间,需要通过将主题读到最后并获取每个键的最后一个条目来恢复状态 对于非反应性消费者,我们可以 // get assigned partitions Set<TopicPartition> assignment = consumer.assignment(); // get "end" offset for every partition Map<TopicPartition, Long> endOffsets =

我们使用压缩卡夫卡主题来存储状态更改,在重新启动或重新平衡期间,需要通过将主题读到最后并获取每个键的最后一个条目来恢复状态

对于非反应性消费者,我们可以

// get assigned partitions
Set<TopicPartition> assignment = consumer.assignment();
// get "end" offset for every partition
Map<TopicPartition, Long> endOffsets = consumer.endOffsets(assignment);

// poll data until "end" is reached for every partition
...

给定一个
卡夫卡接收器
,您应该能够执行以下操作:

receiver.receive()
        .zipWith(receiver.doOnConsumer(Consumer::assignment)
                .flatMap(a -> receiver.doOnConsumer(c -> c.endOffsets(a)))
                .filter(m -> !m.isEmpty())
                .single()
                .retry()
                .cache()
                .repeat())
        .groupBy(t -> t.getT1().partition())
        .flatMap(f -> f.filter(t -> t.getT1().offset()+1 == (long) t.getT2().get(new TopicPartition(topic, f.key()))))
        .map(t -> t.getT1())
关于我为什么这样做的一些注释:

  • 这将为您提供一个
    Flux
    ,即每个分区中的最后一个
    ReceiverRecord
  • 通常我会说,不要为接收者创建单独的变量,只需将其全部内联——但使用
    doonsumer()
    是不可能做到这一点的,因为
    assignment()
    不受反应式
    KafkaReceiver
    的直接支持
  • 我通常尽量避免使用
    zipWith()
    从本质上合并
    Flux
    和重复缓存的
    Mono
    ,而倾向于使用
    flatMapMany()
    。但是,在这种情况下,我认为这是行不通的,因为您需要在
    assignment()
    返回除空集以外的任何内容之前主动轮询主题

可能值得添加一些其他相关的标签(卡夫卡、java等)-我假设您在这里使用了java,但额外的澄清不会有什么坏处:-)还发现了使用类似代码的解决方案,并进行了一些更正-我使用了
concatMap
和内偏移Mono的缓存,使用
doOnConsumer
获取消费者位置,而不是记录偏移量以检查结束,并
takeUntil
以完成发布。我将发布我的代码
receiver.receive()
        .zipWith(receiver.doOnConsumer(Consumer::assignment)
                .flatMap(a -> receiver.doOnConsumer(c -> c.endOffsets(a)))
                .filter(m -> !m.isEmpty())
                .single()
                .retry()
                .cache()
                .repeat())
        .groupBy(t -> t.getT1().partition())
        .flatMap(f -> f.filter(t -> t.getT1().offset()+1 == (long) t.getT2().get(new TopicPartition(topic, f.key()))))
        .map(t -> t.getT1())