在高性能Java应用程序中异步处理低速使用者(数据库)的最佳方法是什么

mac*_*ers 5 java asynchronous message-queue producer-consumer disruptor-pattern

一个EventHandler(DatabaseConsumer)Disruptor调用存储过程在数据库中,这是如此之慢,以至于它会阻塞Disruptor一段时间.

因为我需要Disruptor保持运行而不会阻塞.我正在考虑添加一个额外的队列,以便EventHandler可以作为Producer另一个新创建的线程可以Consumer用来处理数据库的工作,这可以是异步的,而不会影响Disruptor

这是一些约束:

  1. 该对象Disruptor传递给EventHandler周围30KB这个对象的数量约为40万.理论上,需要处理的对象的总大小约为30KBX400K = 12GB.所以额外的队列应该足够了.
  2. 由于性能很重要,因此应避免GC暂停.
  3. Java程序的堆大小只有2GB.

我认为文本文件是一个选项.EventHandler(生产者)将对象写入文件并Consumer从中读取并调用存储过程.问题是如何处理它到达文件末尾的情况以及如何知道新的即将到来的行.

有谁解决过这种情况吗?有什么建议?

小智 2

简短的答案是调整您的干扰器的大小,以应对突发的大小,而不是整个卷的大小,请记住,干扰器只能包含对 30kb 对象的引用,整个对象不需要位于环形缓冲区中。

在数据库需要内存进行缓冲之前,无论采用任何形式的缓冲,当数据库落后太多时,中断器都会为您提供对系统其余部分施加背压的选项。这就是说你可以减慢干扰器的输入速度。

假脱机到文件的另一个选项是查看Java Chronicle,它使用内存映射文件将内容保存到磁盘。

更复杂的答案是利用干扰器的批处理效应,以便您的数据库能够赶上。即使用 EventHandler 将一批事件收集在一起并将它们作为一个单元提交到数据库。这种做法允许事件处理程序在事物备份时变得更加高效,从而提高吞吐量。