【问题标题】:Kubernetes HPA based on JVM Heap memory基于 JVM Heap 内存的 Kubernetes HPA
【发布时间】:2021-10-26 06:44:09
【问题描述】:

我在 Kubernetes 集群上运行了一个 openjdk:8 映像。我添加了内存 HPA(Horizo​​ntal Pod Autoscaling),它可以很好地扩展,但由于 JVM 不会将内存从堆释放回操作系统,因此 Pod 不会缩小。以下是 hpa.yaml

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: image-server
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: image-server
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 60
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 60

解决此问题的一种方法是使用正确的 GC 并使其释放内存,但由于 JVM 被设计为不会出于性能原因频繁地从堆中释放,因此这样做不是一个好主意。有没有办法从 Kubernetes 处理这个问题?就像不检查操作系统的内存使用情况一样,我们可以不只检查堆中的内存使用情况并在其上进行扩展吗?

【问题讨论】:

  • 你是正确的,JVM 通常不会返回内存,但这也不完全正确。看看herehere, if you are using G1
  • @Eugene 我正在使用 openjdk 8,它默认使用 ParallelGC。出于性能原因,JVM 保留内存以避免分配释放周期,通过使用不同的 GC 或将其配置为更频繁地释放内存可能会增加该周期。而且由于我们只有一个 java 进程在这个 pod 上运行,所以操作系统不需要它来做任何其他事情,即使 Java 保留它也没关系。我正在寻找一种基于堆使用而不是操作系统报告的内存使用来执行 HPA 的方法。
  • 你不能。但是您可以使用 diff GC 更快(或根本)释放内存,从而几乎达到您想要的效果。声称由于性能影响而没有这样做的说法已成为过去的神话。每个并发 GC,例如 Shenandoah 和 ZGC(甚至是链接显示的 G1),都会释放它。

标签: kubernetes garbage-collection jvm


【解决方案1】:

在 Kubernetes 中扩展 Java 应用程序有点棘手。 HPA 仅查看系统内存,正如所指出的,JVM 通常不会释放已提交的堆空间(至少不会立即释放)。

有两种主要方法可以解决这个问题

1。调整 JVM 参数,使提交的堆更接近使用的堆

根据使用的 JVM 和 GC,调整选项可能略有不同,但最重要的是

  • MaxHeapFreeRatio - 允许未使用的已提交堆中有多少
  • GCTimeRatio - 允许运行 GC 的频率(影响性能)
  • AdaptiveSizePolicyWeight - 在计算新堆时如何权衡旧的和新的 GC 运行

为这些提供准确的值并不容易,这是快速释放内存和应用程序性能之间的折衷方案。最佳设置将取决于应用程序的负载特性。

Patrick Dillon 在 RedHat 发表了一篇名为 Scaling Java containers 的文章,深入探讨了这个主题。

2。自定义缩放逻辑

您可以创建自己的扩展逻辑并将其作为定期运行的作业部署到 Kubernetes 中,而不是使用 HPA:

  1. 检查所有 pod 中的堆使用情况(例如通过在 pod 内运行 jstat)
  2. 如果达到最大阈值,则扩展新 pod
  3. 如果达到最小阈值,则在 pod 中进行缩放

这种方法的好处是可以查看实际的堆使用情况,但需要一个自定义组件。

可以在 powercloudup 的文章Autoscaling based on CPU/Memory in Kubernetes — Part II 中找到一个示例

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2023-01-09
  • 1970-01-01
  • 2020-10-13
  • 2021-02-01
  • 1970-01-01
  • 2020-04-18
  • 2021-09-07
  • 2019-02-01
相关资源
最近更新 更多