鲲鹏社区首页
中文
注册
华为云MRS的yarn调度能力调优实践

华为云MRS的yarn调度能力调优实践

大数据

发表于 2025/09/11

0

作者 | 陈兵

1 实践背景介绍

某银行业务系统使用华为云MRS服务,在资源节点达到两万个时,Yarn资源调度性能在鲲鹏服务器上为5100CPS(每秒启停容器数),在业界主流服务器上为8000CPS,鲲鹏服务器上Yarn的资源调度性能指标落后业界主流服务器约36.25%。需要将Yarn资源调度在鲲鹏环境的指标至少提升到业界主流服务器的水平。

环境信息

硬件环境信息

项目

配置信息

CPU型号

鲲鹏920 7265F处理器(64*4核)

鲲鹏920 7280Z处理器(80*4核)

内存

64G*16

操作系统和软件环境信息

名称

版本

说明

openEuler

22.03 SP2

测试环境OS

SUSE

15

测试环境OS

Hadoop

3.3.1_800

-

Hadoop superior sls

8.2.0

任务提交仿真器

测试场景

本项目中,使用Hadoop sls模拟资源节点和客户端提交任务等,以达到单机测试Yarn资源调度能力的目的。评判Yarn资源调度能力的指标为容器启动销毁的速度,指标单位为containers/s(CPS),通过influxdb采集CPS,grafana进行数据绘图。

不同处理器型号搭配不同版本的JDK达到的调优效果不同,调优效果请参见下文。

2 调优前性能数据

处理器型号

主频

Containers/s(CPS)

鲲鹏920 7265F处理器

3.0GHz

5100

鲲鹏920 7280Z处理器

2.9GHz

5600

3 性能瓶颈分析

从下图所示的火焰图(arthas抓取)上看,Arm环境上没有明显的瓶颈点。


从CPU的利用率上看,多个线程在Arm环境的CPU利用率较低,从华为云那里了解到,“Superior Scheduler”、“SchedulerEventDispatcher”、“AsyncDispatcher”是Yarn资源调度主要的工作线程。而“Superior Scheduler”是实际进行资源调度的线程,其余工作线程与该线程都有一定依赖关系,同时该线程会存在周期性的休眠唤醒,所以分析可能是由于线程频繁切换上下文导致多个工作线程CPU利用率上不去。

通过查看GC日志,发现Arm环境的GC时间较长,分析可能是GC时间上对Arm环境资源调度存在影响,可以考虑更换GC算法。


由于这里是模拟的nm节点以及任务提交,不涉及磁盘IO以及网络交互,所以不必分析。

4 性能调优实践

4.1 鲲鹏920 7265F处理器

4.1.1 绑核

使用numactl命令对任意一个node进行绑核,这里以node0为例,剩余3个核不直接用numactl绑定,示例如下。

numactl --physcpubind=+4-63 --membind=0 ./run_simulator.sh 20m-25k-sls-trace_new.json_60s_1000queues sls-nodes-20000_60vcores_GH.json logs/

此处对0-3号核进行绑定,0号核其余应用也较为常用,不适用,然后将三个主要的工作线程绑定到1-3号核上,主要思想就是使用一个node中其余较为空闲的核进行线程绑定,线程绑核脚本示例如下,这里使用了“1”、“2”、“3”号核。绑核能带来约2.5k的CPS提升。

#!/bin/bash

#获取Java应用的进程ID

JAVA_PID="$1"

#等待Java应用启动

sleep5#根据实际情况调整等待时间

AsyncDispatcher=$(ps -T -p $JAVA_PID | grep "AsyncDispatcher" | awk '{print $2}')

SuperiorScheduler=$(ps -T -p $JAVA_PID | grep "Superior Schedu" | awk '{print $2}')

SchedulerEventDispatcher=$(ps -T -p $JAVA_PID | grep "SchedulerEventD" | awk '{print $2}')

taskset -pc 1 $AsyncDispatcher

taskset -pc 2 $SuperiorScheduler

taskset -pc 3 $SchedulerEventDispatcher

4.1.2 开启内存大页

  1. 查看内存大页的Hugepagesize。

    cat /proc/meminfo

    查询结果为2048KB。

  2. 编辑“/sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages”路径中对应页大小目录下的nr_hugepages文件,需要多少个大页就把数量写在该文件中,这里系统的大页size是2048KB,计算公式为:大页数量=堆内存/2048kB,可以适当设置的多一点。


  3. Java使用内存大页时需要在JVM参数中增加LargePageSizeInBytes参数配置,LargePageSizeInBytes参数代表大页的页大小,需要与前面描述中的页大小,如:2048kB(2MB)保持一致。

    该步骤使用内存大页对于CPS提升并没有明显效果,但是可以让CPS波动更小,请自主选择是否使用。

    -XX:+UseLargePages -XX:LargePageSizeInBytes=2m

4.1.3 关闭CPU预取

开启CPU预取CPS会降低0.5k左右,因此需要关闭CPU预取。在BIOS中关闭CPU预取,操作步骤如下:


如何进入BIOS界面的具体操作请参见《TaiShan 服务器 BIOS 参数参考(鲲鹏920处理器)》中“进入BIOS界面”的相关内容。

4.1.4 开启性能模式

开启性能模式相较于不开启时,平均CPS会有100~200的提升。操作步骤如下。


4.1.5 调整GC参数

调优前JVM关于GC的参数配置为“-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=65”,经验证,使用G1等GC算法时,会降低CPS几百到一千不等。

调整CMSInitiatingOccupancyFraction参数时,也可以使CPS提升。经过多次测试,CMSInitiatingOccupancyFraction参数设置为80时,CPS提升最高,能提升约0.5~0.8k。

4.1.6 升级JDK版本(可选)

现网Yarn调度使用的JDK 8,将JDK 8升级为毕昇JDK 11后,能带来0.7~1.0k左右的CPS提升。

JVM参数JDK 8和JDK 11保持一致,参考“-Xms128G -Xmx128G -XX:NewSize=16G -XX:MaxNewSize=16G -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=128M -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80”。此处不能使用JDK 17,升级为JDK 17后效果达不到调优前的指标。

4.2 鲲鹏920 7280Z处理器

4.2.1 绑核

绑核方法与鲲鹏920 7265F处理器一样。鲲鹏920 7280Z处理器中node有80核,有需要可以修改下绑的核序号,不修改也没有多大影响。在使用JDK 8时能提升CPS 1.4k左右,使用JDK 11/17时能提升3.5k左右。

4.2.2 开启内存大页

设置方法请参见4.1.2-开启内存大页。开启内存大页并不能带来平均CPS的提升,但能很好的控制CPS的波动,尤其是在使用JDK升级后,波动抑制效果尤为明显。

4.2.3 调整内存刷新率

修改内存的刷新率,设置为1x Mode,在使用JDK 11/17版本时,能提升CPS 1.5k左右,使用JDK 8时影响不大。


4.2.4 开启性能模式

经测试,在鲲鹏920 7280Z处理器中,不开启性能模式,在使用JDK高版本时,会降低CPS约2k,因此建议开启性能模式。

4.2.5 升级JDK版本

使用JDK 8版本时,性能调优最多在7.5k左右,而更换成JDK 11或者JDK 17时,性能可以带来大幅度的提升。

  • 更换JDK 11时,还是需要使用CMS GC算法,其余算法都会带来性能的降低,CMSInitiatingOccupancyFraction可以保持原先的65,或者修改为最新的80,影响不大。JDK 11的JVM参数配置建议为:“-Xms128G -Xmx128G -XX:NewSize=16G -XX:MaxNewSize=16G -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=128M -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80”。

  • 使用JDK 17时,由于高低版本JDK存在一些包权限上的不同,需要在JVM参数中添加“--add-opens java.base/java.lang=ALL-UNNAMED”,否则应用无法启动,整体JVM参数配置建议为:“-Xms128G -XX:+UseLargePages -XX:LargePageSizeInBytes=2m -Xmx128G -XX:NewSize=16G -XX:MaxNewSize=16G -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=128M --add-opens java.base/java.lang=ALL-UNNAMED”。虽然JDK 17的性能更好,但是使用JDK 17时CPS的波动较大,需要斟酌使用。

4.2.6 使能SVE(仅限于JDK 11及以上可用)

在JDK 11及以上版本中,支持SVE,在本机型中,使用SVE能带来接近1k的CPS提升。只需要在JVM参数中添加“-XX:UseSVE=1”即可。但在实际的效果中看,JDK 11中使用SVE并没有明显提升,而在JDK 17中使用则可以带来1k左右的提升。

5 调优实践效果

  • 鲲鹏920 7265F处理器中,使用以上调优方法在JDK 8时CPS达到8.0~8.3k,提升幅度达到60%;在JDK 11时CPS达到9.0k左右,提升幅度达到76%。

  • 鲲鹏920 7280Z处理器中使用了进程绑核+线程单独绑核;内存大页;开启性能模式;调整内存刷新率;JDK版本升级;SVE使能。由于使用JDK 8时仅有绑核有明显效果,其余步骤仅在JDK 11/17上面效果明显。调优方法可能存在一定的关联性,如果单独使用可能没法带来描述那么大的收益,如内存刷新率在JDK 8就没有什么效果。且各个调优步骤之间的收益存在一定的重叠,不能单纯进行收益相加计算总收益。

    鲲鹏920 7280Z处理器中,调优前CPS可以达到5600。使用JDK 8时,CPS只能调优到7.5k左右,更换JDK 11时,使用以上调优手段,CPS达到14.3~14.5k左右。

处理器型号

JDK 8

JDK 11

JDK 17

鲲鹏920 7265F处理器

8.0~8.3k

9.0k

-

鲲鹏920 7280Z处理器

-

15k

16k

6 故障排除

6.1 taskset线程绑核无效

问题现象描述

numactl进行node0(0-63核)进程绑核后,再使用taskset对线程进行单独绑核并没有效果,线程绑定的核仍然存在漂移。

关键过程、根本原因分析

由于taskset对线程绑定的核序号在numactl绑核的序号范围内,怀疑两个程序存在一定的优先级,导致taskset绑核失败。

结论、解决方案及效果

numactl绑核时,仅使用4-63号核,剩余几个核不绑定,再使用taskset将工作线程绑定在1-3号核上,执行程序发现性能得到提升,核也绑定成功。

6.2 perf制作火焰图失败

问题现象描述

使用perf record对Java应用进行分析时,抓取的数据文件总是打开存在报错,而且看不到实际的Java工作内容,并且perf在抓取信息时,还会很大程度干扰应用的执行,进而无法制作火焰图。

关键过程、根本原因分析

查看perf抓取的信息都是底层so库之类的信息,怀疑perf本身对Java虚拟机内部的信息抓取支持不是很好,考虑更换可以抓取Java虚拟机内部信息的工具。

结论、解决方案及效果

使用Arthas工具,可以准确抓取Java进程信息,制作出火焰图。

6.3 Java应用在JDK 17环境报错

问题现象描述

Yarn调度器原先使用的是JDK 8,使用JDK 11不会报错,但是更换JDK 17后存在报错。报错信息如下:

关键过程、根本原因分析

从JDK 9开始,Java引入了模块系统,限制了对内部API的访问。而JDK 11对于API的限制还没有特别严格,JDK 17开始限制极其严格。

结论、解决方案及效果

对JVM增加参数“--add-opens java.base/java.lang=ALL-UNNAMED”,成功在JDK 17环境运行应用。

本页内容