文章目录
-
- [Hadoop YARN Cgroups 实践](#Hadoop YARN Cgroups 实践)
-
- [什么是 cgroups](#什么是 cgroups)
- [cgroups 概念](#cgroups 概念)
- [YARN 使用 cgroups 背景](#YARN 使用 cgroups 背景)
- [cgroups 在 YARN 中的工作原理](#cgroups 在 YARN 中的工作原理)
- [cgroups 在 YARN 中的实践步骤](#cgroups 在 YARN 中的实践步骤)
- 参考
Hadoop YARN Cgroups 实践
什么是 cgroups
cgroups 的全名叫做 Control Groups, 它是 Linux 内核的一个功能,用来限制、控制与分离一个进程组的资源(如CPU、内存、网络、磁盘IO等)。
cgroups 主要提供有以下四个功能:
-
Resource Limiting: Group 可以设定 CPU、内存等使用上限;
-
Prioritization: 不同的 Group 可以拥有不同的 CPU 跟 磁盘IO 使用优先顺序
-
Accounting: 计算 Group 内的资源使用状况,例如可以拿来当作计费的依据
-
Control:冻结或是重启一整个 Group 的 Process
cgroups 概念
了解 cgroups 的一些基本核心概念,cgroups 主要由四个元素构成:
-
Task: 运行于作业系统内的 Process,在 cgroups 内被称为 Task;
-
Subsystem: 一种资源控制器,一个 Subsystem 负责管理一种资源,例如 CPU 或是 Memory,不同的作业系统所提供的 Subsystem 种类可能不尽相同,以下列出一些常见的类型:
- blkio:限制 Task 对于储存装置的读取,例如 Disk, SSD 和 USB...等
- cpu: 透过 Scheduler 安排 cgroup 内 Task 存取 CPU 资源
- cpuacct: 自动产生 cgroup 内的 Task 使用 CPU 资源的报告
- cpuset: 为 cgroup 内的 Task 分配一组单独的 CPU 核心 (多核心 的 CPU 系统) 跟 Memory
- devices: 控制 cgroup 中 Task 可以存取的装置有哪些
- freezer: 暂停跟恢复位于 cgroup 内的 Task
- memory: 限制 Task 可以使用的 Memory,并且自动产生 cgroup 内 Task 使用 Memory 资源的报告
- net_cls: 对网路封包标记上 Class ID,进而让 Linux Traffic Controller 根据这些 Class ID 得知网路封包是来自于哪一个 cgroup 中的 Task
- net_prio: 为每一个 Network Interface 提供动态设定网路流量优先权的方法
- perf_event: 用来辨别 Task 属于哪一个 cgroup
-
cgroup: cgroups 的资源控制单位,也就是 Task 与 Subsystem 的关联单位,用来定义 Task 的资源管理策略,例如把一个 Task 加入到某个 cgroup 内,那么这个 Task 使用资源时就必须遵守该 cgroup 中所定义的规范;
-
hierarchy: 一群 cgroup 所组成的树状结构,每个节点都是一个 cgroup,一个 cgroup 可以有多个子节点,子节点预设继承父节点的属性;系统中可以有多个 hierarchy;
YARN 使用 cgroups 背景
cgroups 是用于限制一组进程的资源使用(如 CPU、内存、网络、磁盘IO)。Apache YARN 利用此功能为 Hadoop 工作负载提供 CPU 隔离。目前,YARN 仅支持通过 cgroup 限制 CPU 使用率。
我们生产环境是 YARN 和 Presto 混合部署,如果 YARN 上运行并大量消耗 CPU 资源任务,就会发生与Presto 争抢 CPU 资源。Cgroups 可以限制 node manager 上的所有 YARN containers CPU 使用。
cgroups 在 YARN 中的工作原理
YARN 资源分配背后的基本概念是 container。container 是最小的资源分配单元*,*对内存和 vcore 具有固定的资源限制。这提供了限制 container 内运行的任务(进程)的内存和 vcore 资源的能力。当 node manager 无法为container 提供足够的资源时,任务将无法启动。类似地,cgroups 监控 node manager 上所有 container 的 CPU 使用情况,并在达到限制时停止向容器分配 CPU 时间。此时,任务进程进入等待状态,一直持续到有足够的资源为止。主要工作过程如下:
- 用户定义允许 node manager 使用多少 CPU 时间(以百分比表示,通过YARN 参数
yarn.nodemanager.resource.percentage-physical-cpu-limit
控制); - 当用户提交作业时,Application Master计算每个任务需要的处理器数量(container 请求的 vcore 数量),然后向 resource manager 提交请求;
- resource manager 将 container 分配给能够提供所需资源的适当节点;
- node manager 计算每个 container 的 CPU 使用限制(百分比值)并将该值写入 cgroups 配置文件;
- node manager 启动 container 来完成任务;
- Linux 内核保证每个 container 在 CPU 限制内运行。
cgroups 在 YARN 中的实践步骤
准备工作
- 重新编译container-executor
shell
# LinuxContainerExecutor通过container-executor来启动容器,但是出于安全的考虑,要求其所依赖的配置文件container-executor.cfg及其各级父路径所有者必须是root用户;编译目的是修改 container-executor.cfg 配置文件的存放路径。
cd /home/admin/hadoop-3.1.1-src/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager
cmake src -DHADOOP_CONF_DIR=/etc/hadoop
# cmake 版本需要安装 3.1版本以上的,本次使用cmake-3.27.7
- 修改container-executor.cfg
shell
yarn.nodemanager.linux-container-executor.group=admin
banned.users=
min.user.id=0
allowed.system.users=
修改 YARN 配置
shell
# 修改 yarn-site.xml
<property>
<name>yarn.nodemanager.container-executor.class</name>
<value>org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor</value>
</property>
<property>
<name>yarn.nodemanager.linux-container-executor.resources-handler.class</name>
<value>org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler</value>
</property>
<property>
<name>yarn.nodemanager.linux-container-executor.group</name>
<value>admin</value>
</property>
<property>
<name>yarn.nodemanager.linux-container-executor.cgroups.mount-path</name>
<value>/sys/fs/cgroup</value>
</property>
<property>
<name>yarn.nodemanager.linux-container-executor.cgroups.mount</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.linux-container-executor.nonsecure-mode.local-user</name>
<value>admin</value>
</property>
<property>
<name>yarn.nodemanager.resource.count-logical-processors-as-cores</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.resource.pcores-vcores-multiplier</name>
<value>2.0</value>
</property>
<property>
<name>yarn.nodemanager.resource.detect-hardware-capabilities</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.resource.percentage-physical-cpu-limit</name>
<value>85</value>
</property>
# yarn.nodemanager.resource.count-logical-processors-as-cores 默认是false,是使用物理核心数当做vcore数;修改为true表示使用逻辑核心数据
# yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage 设置为true时即为严格模式,container只能使用被需要分配的CPU资源,即使CPU有空闲也不能使用;设置为false时即为非严格模式,container除了实际被需要分配的CPU资源外,还可以利用空闲的CPU资源。
拷贝 container-executor.cfg 到 /etc/hadoop
shell
sudo mkdir -p /etc/hadoop
sudo cp /home/admin/container-executor.cfg /etc/hadoop/
创建 cgroup 目录
shell
sudo yum install -y libcgroup-tools
cd /sys/fs/cgroup/cpu
sudo cgcreate -t admin:admin -a admin:admin -g cpu:/hadoop-yarn
# sudo cgdelete cpu:/hadoop-yarn
# mount -t cgroup -o cpu,cpuacct cpu /sys/fs/cgroup/cpu
注意:无论使用 cgcreate 还是mkdir 创建 cgroup目录,都是临时的,服务器重启后都会消失。
替换 NM container-executor
shell
cp -r /home/admin/container-executor /opt/apache/hadoop/bin/
sudo chown root:admin /opt/apache/hadoop/bin/container-executor
sudo chmod 6050 /opt/apache/hadoop/bin/container-executor
优雅重启 NM
shell
# 查看 NM日志出现 "restricted to 34.0 cores",40逻辑核心数 * 85% cpu-limit = 34 cores
INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.resources.CGroupsCpuResourceHandlerImpl: YARN containers restricted to 34.0 cores
验证
第一批10台节点
未开启 YARN cgroups前,cpu-limit 为85%,cpu 使用率超过85%情况较多,甚至可以到100%;
开启 YARN cgroups 后,cpu 使用率超过85%情况较之前好转, 未出现超过100%。