Java 无限流量和对数据库的大容量写入

Java 无限流量和对数据库的大容量写入,java,apache-kafka,project-reactor,flow-control,Java,Apache Kafka,Project Reactor,Flow Control,在继续实际的事件处理之前,我有一个无限的事件流(来自使用reactor kafka的kafka),我试图将这些事件分批写入数据库。我的问题是让它在适当的背压下工作 windowTimeout和bufferTimeout似乎是很好的选择,因为它们允许我指定最大大小,但也限制了低“流量”情况下的等待时间 首先是windowTimeout,从中对数据库进行批量写入。然而,这很快就出现了问题:reactor.core.Exceptions$OverflowException:接收器被超过预期的信号溢出(

在继续实际的事件处理之前,我有一个无限的事件流(来自使用reactor kafka的kafka),我试图将这些事件分批写入数据库。我的问题是让它在适当的背压下工作

windowTimeout
bufferTimeout
似乎是很好的选择,因为它们允许我指定最大大小,但也限制了低“流量”情况下的等待时间

首先是
windowTimeout
,从中对数据库进行批量写入。然而,这很快就出现了问题:reactor.core.Exceptions$OverflowException:接收器被超过预期的信号溢出(有界队列…)

然后,我切换到
bufferTimeout
,但失败,出现错误reactor.core.Exceptions$OverflowException:由于缺少请求,无法发出缓冲区

我希望以下说明了我所追求的流程:

flux.groupBy(envelope -> envelope.partition)
  .flatMap(partitionFlux -> {
    final Flux<ConsumedEnvelope> elasticFlux = partitionFlux.publishOn(Schedulers.elastic());
    final Flux<List<ConsumedEnvelope>> batchFlux = partitionFlux.bufferTimeout(100, Duration.ofMillis(500))
      .concatMap(batch -> {
        final ConsumedEnvelope last = batch.get(batch.size() - 1);

        return repository.persist(batch) // a)
          .then(last.acknowledge()) // b)
          .thenReturn(batch);
      });

    return processing(batchFlux);
  })
  .subscribe(result -> {
      // ...
  });

flux.groupBy(信封->信封.partition)
.flatMap(分区流量->{
final Flux elasticFlux=partitionFlux.publishOn(Schedulers.elastic());
最终流量batchFlux=partitionFlux.bufferTimeout(100,持续时间单位:百万(500))
.concatMap(批处理->{
最终消费者开发最后一次=batch.get(batch.size()-1);
return repository.persist(batch)//a)
.then(last.acknowledge())//b)
.然后返回(批次);
});
返回处理(batchFlux);
})
.订阅(结果->{
// ...
});
a)
repository.persist
在内部什么也不做,只是迭代批处理以创建插入操作,然后返回一个
Mono

b) acknowledge()用于Kafka偏移,我只想在成功持久化批处理后执行此操作。它全部包装在
concatMap
中,一次只为每个分区处理一个批次

如上所述,这会导致溢出异常。有没有什么惯用的方法来达到我所描述的目的?在我看来,这不应该是一个非常不寻常的任务,但我是反应堆的新手,希望得到一些建议

/d

编辑 我意识到简单地添加
onBackpressureBuffer
实际上就可以解决这个问题。但总的来说,有没有更好的方法

编辑2
…当然,上述情况确实因需求不受约束而引发了问题,但不知何故,我忽略了这一点。所以,回到最初的问题,或者也许是某种方式,让onBackpressureBuffer不请求一个未绑定的需求,而是只转发从下游请求的内容

看起来这个问题已经公开了2年多了!这个URL还提到了一个可能的解决方法。