无限流量和批量写入数据库

时间:2019-02-17 23:50:55

标签: java apache-kafka project-reactor flow-control

在继续进行实际的事件处理之前,我试图将事件无穷大的流量(使用反应堆-kafka从kafka中读取)。我的问题是使它在适当的背压下工作。

windowTimeoutbufferTimeout似乎是不错的选择,因为它们既可以指定最大大小,又可以限制“流量”低时的等待时间。

首先是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 -> {
      // ...
  });

a)repository.persist在内部什么都不做,只是迭代批处理以创建插入操作,然后返回Mono<Void>

b)ConsumedEnvelope.acknowledge()用于Kafka偏移,我只想在成功保留该批处理后执行此操作。全部包裹在concatMap中,每个分区一次只能处理一个批次。

如上所述,这导致溢出异常。是否有惯用的方式来实现我试图描述的内容?在我看来,这不应该是一件太不常见的任务,但是我是Reactor的新手,很想得到一些建议。

/ d

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

编辑2 ...上述原因当然是由于需求无限而引起的问题,我莫名其妙地错过了。因此,回到最初的问题,或者以某种方式使onBackpressureBuffer不请求未绑定的请求,而仅转发来自下游的请求。

0 个答案:

没有答案