我正在使用 Disruptor 框架对某些数据执行快速 Reed-Solomon 错误校正。这是我的设置:
RS Decoder 1
/ \
Producer- ... - Consumer
\ /
RS Decoder 8
- 生产者从磁盘读取 2064 字节的 block 到字节缓冲区。
- 8 个 RS 解码器消费者并行执行 Reed-Solomon 纠错。
- 消费者将文件写入磁盘。
在破坏者 DSL 术语中,设置如下所示:
RsFrameEventHandler[] rsWorkers = new RsFrameEventHandler[numRsWorkers];
for (int i = 0; i < numRsWorkers; i++) {
rsWorkers[i] = new RsFrameEventHandler(numRsWorkers, i);
}
disruptor.handleEventsWith(rsWorkers)
.then(writerHandler);
当我没有磁盘输出消费者(没有 .then(writerHandler)
部分)时,测量的吞吐量是 80 M/s,只要我添加一个消费者,即使它写入/dev/null
,或者根本不写入,但声明为依赖消费者,性能下降到50-65 M/s。
我已经使用 Oracle Mission Control 对其进行了概要分析,这是 CPU 使用率图表显示的内容:
没有额外的消费者:
有一个额外的消费者:
图中这个灰色部分是什么,它来自哪里?我想这与线程同步有关,但我在 Mission Control 中找不到任何其他统计数据来指示任何此类延迟或争用。
最佳答案
你的假设是正确的,是线程同步问题。
来自API Documentation for EventHandlerGroup<T>.then
(强调我的)
Set up batch handlers to consume events from the ring buffer. These handlers will only process events after every
EventProcessor
in this group has processed the event.This method is generally used as part of a chain. For example if the handler A must process events before handler B:
这必然会降低吞吐量。把它想象成一个漏斗:
消费者必须wait对于每个 EventProcessor
在它可以通过瓶颈之前完成。
关于java - 是什么导致了这种性能下降?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28630621/