在Kubernetes上对JVM微调研究 - brunoborges


在Kubernetes上对Java的三个方面的研究:

  • - ActiveProcessorCount
  • - 默认GC
  • - 默认Heap Sizing

ActiveProcessorCount 当前匹配cpu_quota: up to 1000m, 1 proc. 1001-2000m, 2 procs, 等等
这听起来很合理,但正如我们所了解的,CFS 控制器不限制 CPU 数量,只限制 CPU 时间。多个本地线程可以并行执行,直到达到 cpu_quota配额。
 
仅在 JVM 看到超过 1792 MB 的可用内存和 2 个可用处理器(k8s 中为 2000m+)时默认选择 G1GC,否则它会选择 SerialGC。
因此,这就是为什么这么多开发人员在受限制的容器中强制使用 -XX:+UseG1GC。
 
堆大小默认为可用内存的 1/4。许多开发人员使用 Xmx 将堆设置为可用 RAM 的 50% 到 80% 之间。
理想情况下,开发人员应该使用 -XX:MaxRAMPercentage,以便 JVM 与 k8s 中的容器一起扩展。
我们想了解为什么 JVM 在为更多可用处理器调整自身大小时表现不同,即使它受到 CPU 节流。也许与线程调度有关?
此外,这将如何影响 G1GC,以及更多堆内存是否可以减少 CPU 节流时间。
 
显然,开发人员在没有考虑 JVM 的工作方式以及并行、多线程工作(例如 JIT 编译器和 GC)的需要情况下,无法为 Kubernetes 正确调整 Java 工作负载的大小,
 
1000m 似乎不是一个好的最小值,但它很常见。
 
在我看来,使用更多副本解决 CPU 节流也是一种常见的解决方法,但不是理想的解决方案。
我们的假设仍然是,对于某些工作负载,减少副本并增加 cpu 限制,可能节省成本,可能会提供更好的性能。
 
但是又发现 JVM 可能在较低的 cpu 限制下表现得更好,只要它为多个处理器调整自己的大小,至少在今天是一个有趣的实验。