您现在的位置是:首页 > 文章详情

Java 10 牵手 Docker,新特性完美解决服务器资源分配问题

日期:2018-04-03点击:486

screenshot

本文首发自“Docker公司”公众号(ID:docker-cn)
编译丨小东
每周一、三、五 与您不见不散!


许多运行在 Java 虚拟机(JVM)上的应用程序(包括像 Apache Spark 和 Kafka 这类的数据服务器和传统企业应用程序)都已经实现了在容器中运行。最近,在容器中运行 JVM 会出现内存和 CPU 用量分配有误的问题,从而导致性能下降。出现这个问题的原因是因为 Java 没有识别出它正在容器中运行。随着 Java 10 的发布,JVM 现在可以通过容器控制组(cgroups)来识别约束集。内存和 CPU 约束都可以直接在容器中管理 Java 应用程序,包含以下几点:

  • 遵守在容器中设置的内存限制;
  • 在容器中设置可用的 CPU;
  • 在容器中设置 CPU 约束;

Java 10 的改进已经在 Docker for Mac/Windows 和 Docker 企业版环境中实现。


容器内存限制

在 Java 9之前,JVM 不能通过使用容器标签来识别内存和 CPU 的限制集。但在 Java 10中,它可以自动的识别和执行内存限制。

Java 定义了一个服务器类机器,它具有2个CPU和2GB内存,它的默认堆(heap)大小为四分之一的物理内存。举个例子,Docker EE 安装有2GB内存和4个CPU。比较它在 Java 8和 Java 10中运行容器的区别,首先来看 Java 8:

docker container run -it -m512 --entrypoint bash openjdk:latest $ docker-java-home/bin/java -XX:+PrintFlagsFinal -version | grep MaxHeapSize uintx MaxHeapSize : = 524288000 {product} openjdk version "1.8.0_162" 

最大堆(heap)大小为512M或由 Docker EE安装设置的2GB的四分之一,而不是容器上限制集设置的512M。相比之下,在 Java 10上运行相同的命令显示容器中的内存限制集非常接近预期的128 M:

docker container run -it -m512M --entrypoint bash openjdk:10-jdk $ docker-java-home/bin/java -XX:+PrintFlagsFinal -version | grep MaxHeapSize size_t MaxHeapSize = 134217728 {product} {ergonomic} openjdk version "10" 2018-03-20 

设置可用 CPU

默认情况下,每个容器对主机的 CPU 周期访问是没有限制的。我们可以设置各种约束来限制容器访问主机的 CPU 周期。Java 10可以识别这些限制:

docker container run -it --cpus 2 openjdk:10-jdk jshell> Runtime.getRuntime().availableProcessors() $1 ==> 2 

分配给 Docker EE 的所有 CPU 都获得相同比例的 CPU 周期。可以通过相对于所有其它运行中容器的权重来更改容器的 CPU 份额权重从而修改这个比例。只有当 CPU 密集型进程运行时这个比例才会启用。当在容器中的任务空闲时,其它容器可以使用剩余的 CPU 时间量。实际的 CPU 时间量取决于系统上运行的容器数量。这些可以在 Java 10中设置,如下所示:

docker container run -it --cpu-shares 2048 openjdk:10-jdk jshell> Runtime.getRuntime().availableProcessors() $1 ==> 2 

“cpuset”约束集就是哪些CPU允许在 Java 10中执行,如下所示:

docker run -it --cpuset-cpus="1,2,3" openjdk:10-jdk jshell> Runtime.getRuntime().availableProcessors() $1 ==> 3

分配内存和 CPU

有了 Java 10,就可以使用容器设置来估计部署应用程序所需的内存和 CPU 的分配。我们假设已经确定了容器中运行的每个进程的内存堆(heap)和 CPU 需求,并设置好了 JAVA_OPTS。举个例子,如果您有一个跨10个节点分布的应用程序,其中有五个节点需要512Mb的内存,CPU 利用率权重为1024,另外五个节点需要256Mb的内存,CPU 利用率权重为512。请注意,1个CPU的份额比例由1024表示。

该应用程序至少需要分配5Gb大小的内存,如下所示:

512Mb x 5 = 2.56 Gb

256Mb x 5 = 1.28 Gb

该应用程序需要8个CPU才能有效运行,如下所示:

1024 x 5 = 5 CPUs

512 x 5 = 3 CPUs


最佳实践建议:之前的 Java 需要对应用程序进行性能分析来确定为每一个运行在 JVM 中的进程分配内存和 CPU。但是,Java 10 消除了这种分析猜测,通过容器设置来防止在 Java 应用程序中出现内存不足的错误以及分配足够的 CPU 来处理工作负载。

原文链接:https://yq.aliyun.com/articles/576200
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章