为什么 JVM 性能会随着负载的增加而提高?
Why does JVM performance improve with more load?
我们发现了一种行为,即当负载较轻时 JVM 的性能会下降。特别是在多次运行中,在测试环境中,我们注意到当泵入系统的订单消息速率降低时,延迟恶化了大约 100%。下面是关于这个问题的一些背景,我将不胜感激。
简单地说,正在调查的演示 Java 交易应用程序可以被认为具有 3 个重要线程:
订单接收线程,
处理器线程,
交换发射线程
订单接收线程接收订单并将其放在处理器 q 上。处理器线程从处理器 q 中获取它,进行一些基本处理并将其放在交换器 q 上。交易所发送器线程从交易所 q 中获取它并向交易所发送订单。
当输入系统的订单率从较高数字变为较低数字时,从订单接收到订单发送到交易所的延迟会恶化 100%。
尝试过的解决方案:
通过发送高消息率并在降低消息率之前启动系统来预热 JVM 中的关键代码路径:
没有解决问题
分析应用程序:
它使用探查器显示代码中的热点,通过改进实施可能会有 10 -15% 的改进。但是,仅仅通过增加消息速率获得的 100% 改善范围内没有任何改善。
有人对此有任何 insights/suggestions 吗?会不会跟线程的调度抖动有关
难道是在低消息率下,线程被从核心中切换出来了?
2 个我认为可能相关的帖子如下。但是我们的症状有点不同:
is the jvm faster under load?
low/medium 负载的一致延迟需要特定调整 Linux。
以下是我的旧检查列表中的几点,与具有毫秒延迟要求的组件相关。
- 将 CPU 内核配置为始终 运行 和最大频率(here 是 RedHat 的文档)
- 为您的关键应用程序线程配置专用 CPU 核心
- 使用
isolcpus
从调度程序中排除专用内核
- 使用
taskset
将关键线程绑定到特定核心
- 在单个 NUMA 节点(使用
numactl
)中将您的服务配置为 运行
Linux 调度程序和功率采样是 low/medium 低延迟下高延迟差异的关键因素。
默认情况下,CPU 核心在不活动时会降低频率,因此您的下一个请求在降频核心上的处理速度较慢。
CPU 缓存是关键的性能资产,如果您的关键线程被安排在不同的内核上,它将丢失其缓存数据。此外,为同一核心调度的其他线程会逐出缓存,同时增加关键代码的延迟。
在重负载下,这些因素不太重要(频率已达到最大值,线程约 100% 忙于坚持特定的核心)。
虽然在 low/medium 负载下,这些因素对平均延迟和高百分位数都有负面影响(与重负载情况相比,99 个百分位数可能更差)。
对于高吞吐量应用程序(超过 100k request/sec),高级线程间通信方法(例如 LMAX disruptor)也很有用。
我们发现了一种行为,即当负载较轻时 JVM 的性能会下降。特别是在多次运行中,在测试环境中,我们注意到当泵入系统的订单消息速率降低时,延迟恶化了大约 100%。下面是关于这个问题的一些背景,我将不胜感激。
简单地说,正在调查的演示 Java 交易应用程序可以被认为具有 3 个重要线程: 订单接收线程, 处理器线程, 交换发射线程
订单接收线程接收订单并将其放在处理器 q 上。处理器线程从处理器 q 中获取它,进行一些基本处理并将其放在交换器 q 上。交易所发送器线程从交易所 q 中获取它并向交易所发送订单。
当输入系统的订单率从较高数字变为较低数字时,从订单接收到订单发送到交易所的延迟会恶化 100%。
尝试过的解决方案:
通过发送高消息率并在降低消息率之前启动系统来预热 JVM 中的关键代码路径: 没有解决问题
分析应用程序: 它使用探查器显示代码中的热点,通过改进实施可能会有 10 -15% 的改进。但是,仅仅通过增加消息速率获得的 100% 改善范围内没有任何改善。
有人对此有任何 insights/suggestions 吗?会不会跟线程的调度抖动有关
难道是在低消息率下,线程被从核心中切换出来了?
2 个我认为可能相关的帖子如下。但是我们的症状有点不同:
is the jvm faster under load?
low/medium 负载的一致延迟需要特定调整 Linux。
以下是我的旧检查列表中的几点,与具有毫秒延迟要求的组件相关。
- 将 CPU 内核配置为始终 运行 和最大频率(here 是 RedHat 的文档)
- 为您的关键应用程序线程配置专用 CPU 核心
- 使用
isolcpus
从调度程序中排除专用内核 - 使用
taskset
将关键线程绑定到特定核心
- 使用
- 在单个 NUMA 节点(使用
numactl
)中将您的服务配置为 运行
Linux 调度程序和功率采样是 low/medium 低延迟下高延迟差异的关键因素。
默认情况下,CPU 核心在不活动时会降低频率,因此您的下一个请求在降频核心上的处理速度较慢。
CPU 缓存是关键的性能资产,如果您的关键线程被安排在不同的内核上,它将丢失其缓存数据。此外,为同一核心调度的其他线程会逐出缓存,同时增加关键代码的延迟。
在重负载下,这些因素不太重要(频率已达到最大值,线程约 100% 忙于坚持特定的核心)。
虽然在 low/medium 负载下,这些因素对平均延迟和高百分位数都有负面影响(与重负载情况相比,99 个百分位数可能更差)。
对于高吞吐量应用程序(超过 100k request/sec),高级线程间通信方法(例如 LMAX disruptor)也很有用。