我为我关于Aeron的演示做了一些基准测试,但我发现如果我对同一传输使用不同的工具,我会得到稍微不同的结果。
例如,如果我使用HDR直方图,我得到的结果与维护人员在测试中得到的数字一致:
- 我的代码https://github.com/easy-logic/transport-benchmarks/blob/master/aeron-ping/src/main/java/io/easylogic/benchmarks/AeronPingBenchmarkHdrHistogram.java
- 结果https://github.com/easy-logic/transport-benchmarks/blob/master/results/aeron-docker-hdr.txt
此外,我尝试了另一个很酷的java基准测试库-JLBH
但结果让我有点困惑。。。
首先,我得到了两个不同版本的基准:
- 单螺纹https://github.com/easy-logic/transport-benchmarks/blob/master/aeron-ping/src/main/java/io/easylogic/benchmarks/AeronPingBenchmarkJlbhSingleThread.java
- 1个线程发布器/1个线程接收器https://github.com/easy-logic/transport-benchmarks/blob/master/aeron-ping/src/main/java/io/easylogic/benchmarks/AeronPingBenchmarkJlbhSeparateThread.java
似乎JLBH鼓励为侦听器使用另一个线程,至少在这种情况下,一些设置(如吞吐量)更有意义,并且初始预热打印一些统计数据。但我可能大错特错,如果我错了,请纠正我。
但更重要的是,这些基准测试的结果完全不同,与我在HDR:中看到的结果不一致
- 单螺纹https://github.com/easy-logic/transport-benchmarks/blob/master/results/aeron-docker-jlbh-sigle-thread.txt
- 1个线程发布器/1个线程接收器https://github.com/easy-logic/transport-benchmarks/blob/master/results/aeron-docker-jlbh-separate-threads.txt
我很有可能在某个地方搞砸了,但就目前而言,所有3个基准测试看起来或多或少都与我相似,但使用了不同的工具集。
非常感谢!
p.S.
如果有人想自己尝试,你只需要运行这个脚本https://github.com/easy-logic/transport-benchmarks/blob/master/run-aeron.sh
要选择要运行的版本,请更改此处的参数mainClassName
:https://github.com/easy-logic/transport-benchmarks/blob/master/aeron-ping/build.gradle#L6
有3种选择:
- io.easylogic.benchmarks.AeronPingBenchmarkJlbhSingleThread(默认值)
- io.easylogic.benchmarks.AeronPingBenchmarkJlbhSeparateThread
- io.easylogic.benchmarks.AeronPingBenchmarkHdr柱状图
您会看到不同的结果,因为基准测试不是在测量相同的东西。
AeronPingBenchmarkHdrHistogram仅测量理想情况,即发送一条消息,然后立即消耗。由于发送方和接收方同步运行,因此没有排队效应。当创建新消息时,它会获得此特定发送尝试的时间戳。但是,整个基准测试的运行时间没有限制,因此不能定义发送速率。想象一下,其中一个发送需要长时间的GC暂停(例如1秒),那么只有这个发送结果会很糟糕,但其余的都不会受到影响。
JLBH基准不同,因为它们增加了时间的概念。例如,在你的结果中,一次跑步的持续时间为5秒,例如:
Run time: 5.0s
Correcting for co-ordinated:true
Target throughput:10000/s = 1 message every 100us
End to End: (50,000) 50/90 99/99.9 99.99 - worst was 14 / 16 20 / 1,660 3,770 - 4,010
OS Jitter (5,853) 50/90 99/99.9 99.99 - worst was 1.8 / 7.0 30 / 181 3,770 - 3,770
这将基准测试从发送5万条消息更改为在5秒内发送50万条消息。从同一示例中,JLBH确定目标速率为10K/sec,并将使用此信息来计算消息开始时间(startTimeNS
)。在这种情况下,GC暂停1秒会影响此事件后的所有消息,因为至少有10K条消息不会按时发送,而且所有其他消息也会因此暂停而延迟。因此,JLBH正在努力避免协调遗漏问题。它似乎也有一些逻辑需要纠正CO,并且它在您的基准测试(例如Correcting for co-ordinated:true
)中是活跃的,这也可能会扭曲结果。
最后,AeronPingBenchmarkJlbhSeparateThread基准测试的结果甚至更糟,因为现在您看到了排队效应。发送方的发送速度快于接收方的消耗速度。随着队列的增加,一切都以最大容量运行,延迟也会减少。此外,您的背压处理代码也不正确,即不能对两个线程使用相同的IdleStrategy
实例。你需要两个。
看看真正的逻辑/基准测试项目,它包含Aeron、gRPC和Kafka的发送/接收风格的基准测试。它有自己的基准测试工具LoadTestRig,可以处理保养或预热、测量、直方图等。为其他系统添加基准测试是很简单的。