RDG:RoCE 加速的 Apache Spark UCX 2.4/3.0 集群部署
创建于 2020 年 2 月 10 日,作者 Boris Kovalev、Peter Rudenko。本参考部署指南 (RDG) 将演示基于 NVIDIA 端到端 100 Gb/s 以太网解决方案的 RoCE/UCX 加速 Apache Spark 2.4/3.0 多节点集群部署流程。
文档目录
介绍
创建于 2020 年 2 月 10 日,作者 Boris Kovalev、Peter Rudenko
本参考部署指南 (RDG) 将演示基于 NVIDIA 端到端 100 Gb/s 以太网解决方案的 RoCE/UCX 加速 Apache Spark 2.4/3.0 多节点集群部署流程。
以下指南详细介绍了在 15 个物理节点上运行 Ubuntu 18.04.3 LTS 的预构建 Spark 2.4.4 / Spark 3.0-preview2 独立集群的安装过程,包括在主机和交换机侧使用 NVIDIA 推荐设置配置 RoCE 网络的逐步流程。
HDFS 集群包含 15 个数据节点和 1 个名称节点服务器。
参考资料
- http://spark.apache.org/
- Running Spark on YARN - Spark 2.4.x 文档
- Cluster Mode Overview - Spark 2.4.0 文档
- SparkUCX
- Unified Communication X (UCX) Framework
- SparkUCX Shuffle Plugin
- HiBench - the big data benchmark suite
- NVIDIA Onyx™ Advanced Ethernet Operating System
- NVIDIA OpenFabrics Enterprise Distribution for Linux (MLNX_OFED)
概述
什么是 Apache Spark™?
Apache Spark™ 是一个开源、快速且通用的大规模数据处理引擎。Spark 为整个集群编程提供了接口,具有隐式数据并行性和容错性。
NVIDIA SparkUCX 插件
Apache Spark™ 取代 MapReduce
Apache Spark 是一个像 MapReduce 一样的通用引擎,但设计运行速度更快,支持更多工作负载。 Spark 最有趣的特性之一是其高效的内存使用,而 MapReduce 主要处理存储在磁盘上的数据。
Hadoop 中实现的 MapReduce 是一种流行且广泛使用的引擎,但存在高延迟问题。此外,其批处理模式响应时间限制了处理和分析数据的许多应用程序的性能。
加速 Spark Shuffle
Shuffle 是在计算阶段之间重新分配数据(重新分区)的过程。Shuffle 是一个成本高昂的过程,应尽可能避免。
在 Hadoop shuffle 中,中间文件写入磁盘,由下一步/阶段拉取。使用 Spark Shuffle,RDD 保存在内存中,允许数据随时可用,但在集群环境中,需要网络资源从远程工作节点获取数据块,从而增加整体执行时间。
使用 SparkUCX 插件通过 RDMA(InfiniBand 或 RoCE)加速数据块的网络获取,可减少 CPU 使用率和整体执行时间。

SparkUCX 插件
SparkUCX 是 Apache Spark 的高性能、可扩展且高效的 Shuffle-Manager 插件。它利用 RDMA(远程直接内存访问)和其他高性能传输来减少 Shuffle 数据传输所需的 CPU 周期。它通过重用内存进行传输,而不是在传统 TCP 栈中多次复制数据,从而减少内存使用。
SparkUCX 插件旨在提供开箱即用的最佳性能,并提供多种配置选项以进一步按作业调整 SparkUCX。
SparkRDMA 与 SparkUCX 对比
| SparkRDMA | SparkUCX |
|---|---|
| 基于已废弃的 IBM DiSNi verbs 包 | 基于 UCX 高级 API 的生产级应用程序,拥有专门的研发团队和广泛的开发者社区 |
| 仅支持 IB/RoCE 的 RC 模式 | 支持 IB、RoCE 的 RC/DC/共享内存模式,以及 TCP 作为回退 |
| 不可扩展,每个连接有 CQ 和进度线程 | 可扩展,每个执行器有 CQ |
| 通信在专用线程上进行,CPU 消耗高 | 通信由应用程序线程发起,并由硬件异步推进 |
| RDMA 协议用 Java 实现 | 基于标准 UCX API 和协议,隐藏了 RDMA 的复杂性 |
| 每个数据块使用不同键注册 | 将所有数据注册为单个块 |
| 相比最差 TCP 性能有所提升 | 相比最佳 TCP 性能有所提升 |
性能
TeraSort 基准测试:整体减少 60%,总执行时间减少 30%。Pagerank 基准测试:执行时间减少 27%。

设置概述
在开始之前,请确保熟悉 Apache 集群多节点架构,更多信息请参见 Overview - Spark 2.4.0 文档。
逻辑设计

物料清单 (BoM)
在本指南描述的分布式 SparkUCX/HDFS 配置中,我们使用以下硬件设置。

注意: 本文档不涉及服务器的存储方面。您应根据用例(数据集大小)配置服务器的存储组件。
物理网络
连接性

网络配置
在我们的参考设计中,每台服务器使用一个端口。
- 对于单端口网卡,我们将连接可用端口。
- 对于双端口网卡,我们将第一个端口连接到以太网交换机,第二个端口留空。
我们将在后续的 NVIDIA OFED 安装部分介绍具体步骤。
每台服务器通过 100GbE 铜缆连接到 SN2700 交换机。
交换机端口连接如下:
- 端口 1 – 连接到 Namenode 服务器
- 端口 2 至 15 – 连接到 Worker 服务器
服务器名称及网络配置如下:
| 服务器类型 | 服务器名称 | 内部网络 - 100 GigE | 管理网络 - 1 GigE |
|---|---|---|---|
| Node 01 (master) | clx-mld-41 | enp1f0: 31.31.31.41 | eno0: 从 DHCP 获取(保留) |
| Node 02 | clx-mld-42 | enp1f0: 31.31.31.42 | eno0: 从 DHCP 获取(保留) |
| Node 03 | clx-mld-43 | enp1f0: 31.31.31.43 | eno0: 从 DHCP 获取(保留) |
| Node 04 | clx-mld-44 | enp1f0: 31.31.31.44 | eno0: 从 DHCP 获取(保留) |
| Node 05 | clx-mld-45 | enp1f0: 31.31.31.45 | eno0: 从 DHCP 获取(保留) |
| Node 06 | clx-mld-46 | enp1f0: 31.31.31.46 | eno0: 从 DHCP 获取(保留) |
| Node 07 | clx-mld-47 | enp1f0: 31.31.31.47 | eno0: 从 DHCP 获取(保留) |
| Node 08 | clx-mld-48 | enp1f0: 31.31.31.48 | eno0: 从 DHCP 获取(保留) |
| Node 09 | clx-mld-49 | enp1f0: 31.31.31.49 | eno0: 从 DHCP 获取(保留) |
| Node 10 | clx-mld-50 | enp1f0: 31.31.31.50 | eno0: 从 DHCP 获取(保留) |
| Node 11 | clx-mld-51 | enp1f0: 31.31.31.51 | eno0: 从 DHCP 获取(保留) |
| Node 12 | clx-mld-52 | enp1f0: 31.31.31.52 | eno0: 从 DHCP 获取(保留) |
| Node 13 | clx-mld-53 | enp1f0: 31.31.31.53 | eno0: 从 DHCP 获取(保留) |
| Node 14 | clx-mld-54 | enp1f0: 31.31.31.54 | eno0: 从 DHCP 获取(保留) |
| Node 15 | clx-mld-55 | enp1f0: 31.31.31.55 | eno0: 从 DHCP 获取(保留) |
网络交换机配置
如果您不熟悉 NVIDIA 交换机软件,请参考 HowTo Get Started with NVIDIA switches 指南。更多信息请参阅 NVIDIA Onyx 用户手册:https://docs.mellanox.com/category/onyx
首先,我们需要将交换机操作系统更新到最新的 ONYX 软件版本。更多详情请参考 HowTo Upgrade MLNX-OS Software on NVIDIA switch systems。
我们将使用 RoCE 传输来加速 SparkUCX。
在我们的部署中,我们将网络配置为 有损 模式。交换机上无需额外配置。
对于 无损 配置,且 NVIDIA Onyx 版本 3.8.2004 及以上,运行:
switch (config) #roce lossless
(PFC+ECN)通过 "roce" 命令配置,以在无损网络上运行 RoCE。
要查看 RoCE 配置,运行:
show roce
要监控 RoCE 计数器,运行:
show interface ethernet counters roce
Master 和 Worker 服务器的安装与配置
前提条件
更新 Master 和 Worker 服务器上的 Ubuntu 软件包
要更新/升级 Ubuntu 软件包,运行以下命令:
sudo apt-get update # 获取可用更新列表
sudo apt-get upgrade -y # 严格升级当前包
在 Master 和 Worker 服务器上安装通用依赖
要安装通用依赖,运行以下命令或逐行粘贴:
sudo apt-get install git bc
在 Master 和 Worker 服务器上安装 Java 8(推荐 Oracle Java)
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer
在 Master 和 Worker 服务器上添加主机文件条目
要编辑主机文件:
sudo vim /etc/hosts
现在添加 namenode(master)和 worker 服务器的条目。
127.0.0.1 localhost
127.0.1.1 clx-mld-42.local.domain clx-mld-42
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
#ff02::1 ip6-allnodes
#ff02::2 ip6-allrouters
31.31.31.41 namenoder
31.31.31.42 clx-mld-42-r
31.31.31.43 clx-mld-43-r
31.31.31.44 clx-mld-44-r
31.31.31.45 clx-mld-45-r
31.31.31.46 clx-mld-46-r
31.31.31.47 clx-mld-47-r
31.31.31.48 clx-mld-48-r
31.31.31.49 clx-mld-49-r
31.31.31.50 clx-mld-50-r
31.31.31.51 clx-mld-51-r
31.31.31.52 clx-mld-52-r
31.31.31.53 clx-mld-53-r
31.31.31.54 clx-mld-54-r
31.31.31.55 clx-mld-55-r
创建网络文件系统(NFS)共享
在主服务器上安装NFS服务器。创建目录 /share/sparkucx 并将其导出到所有工作服务器。 在所有工作服务器上安装NFS客户端。将主服务器的 /share/sparkucx 导出挂载到本地目录 /share/sparkucx(与主服务器路径相同)。
配置SSH
我们将配置从主节点到所有从节点的无密码SSH访问。
-
在主节点和从节点上安装OpenSSH服务器和客户端
sudo apt-get install openssh-server openssh-client -
在主节点上生成密钥对
ssh-keygen -t rsa -P "" -
将主节点上的 .ssh/id_rsa.pub 文件内容复制到所有节点(主节点和从节点)的 .ssh/authorized_keys 文件中
-
验证可以从主节点访问从节点
ssh clx-mld-41-r ssh clx-mld-42-r ssh clx-mld-43-r ... ssh clx-mld-55-r
安装Hadoop
安装Hadoop集群通常涉及在所有集群机器上解压软件。
-
下载 hadoop-2.7.7.tar.gz 到要安装的机器上
wget https://downloads.apache.org/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz -
解压压缩的tar文件
cd /share/sparkucx/ tar -zxvf hadoop-2.7.7.tar.gz
下载Apache Spark
-
访问 下载 | Apache Spark 并下载 Apache Spark™ 和 spark-2.4.4-bin-hadoop2.7.tgz 到共享文件夹 /share/sparkucx。

-
选择Spark版本:**2.4.4 (2019年8月30日) 或 ** 3.0.0-preview2 (2019年12月23日)
-
选择包类型:Pre-built for Apache Hadoop 2.7
-
下载Spark:spark-2.4.4-bin-hadoop2.7.tgz
克隆HiBench Suite 7.0仓库
要克隆最新的HiBench仓库,运行以下命令:
cd /share/sparkucx
git clone https://github.com/intel-hadoop/HiBench.git
上述git clone命令会创建一个名为“HiBench”的子目录。克隆后,您可以选择构建特定分支(例如发布分支),通过调用以下命令:
cd HiBench
git checkout master # 其中master是所需分支(默认)
cd <Path to NFS share>
在主节点和工作节点上安装适用于Ubuntu的MLNX_OFED
本章介绍如何在安装了NVIDIA ConnectX®-5网卡的单台主机上安装和测试MLNX_OFED for Linux包。 更多信息请点击 NVIDIA OFED for Linux User Manual。
下载NVIDIA OFED
-
验证系统已安装NVIDIA网络适配器(HCA/NIC):
lspci -v | grep Mellanox以下示例显示安装了NVIDIA HCA的系统:

-
根据您的操作系统下载ISO镜像到主机。 镜像名称格式为 MLNX_OFED_LINUX--.iso。 您可以从 http://www.NVIDIA.com > 产品 > Software > InfiniBand/VPI Drivers > NVIDIA OFED Linux (MLNX_OFED) > Download 下载。

-
使用MD5SUM工具确认下载文件的完整性。运行以下命令并将结果与下载页面上提供的值进行比较:
md5sum MLNX_OFED_LINUX-<ver>-<OS label>.iso
安装NVIDIA OFED
MLNX_OFED通过运行 mlnxofedinstall 脚本安装。安装脚本执行以下操作:
- 发现当前安装的内核。
- 卸载标准操作系统发行版或其他供应商商业堆栈中的任何软件堆栈。
- 安装MLNX_OFED_LINUX二进制RPM(如果当前内核可用)。
- 识别当前安装的InfiniBand和以太网网络适配器,并自动升级固件。
安装脚本会删除所有先前安装的NVIDIA OFED包并重新安装。系统会提示您确认删除旧包。
-
以root身份登录安装机器。
-
将下载的ISO复制到 /root。
-
挂载ISO镜像到您的机器:
mkdir /mnt/iso mount -o loop /root/MLNX_OFED_LINUX-4.7-3.2.9.0-ubuntu18.04-x86_64.iso /mnt/iso cd /mnt/iso -
运行安装脚本:
./mlnxofedinstall --all -
安装成功后重启:
# /etc/init.d/openibd restart # reboot
ConnectX®-5 端口可单独配置为 InfiniBand 或以太网端口。默认情况下,两个 ConnectX-5 VPI 端口均初始化为 InfiniBand 端口。
- 检查端口模式是否为以太网:
ibv_devinfo
- 如果看到以下内容,则需要将接口端口类型更改为以太网:

将接口端口类型更改为以太网模式。
使用 mlxconfig 脚本在驱动加载后更改模式。
注意:LINK_TYPE_P1=2 表示以太网模式
a. 启动 mst 并查看端口名称:
mst start
mst status
b. 将端口模式更改为以太网:
mlxconfig -d /dev/mst/mt4121_pciconf0 s LINK_TYPE_P1=2
Port 1 set to ETH mode
reboot
c. 查询以太网设备并打印用户空间可用的信息:
ibv_devinfo
d. 运行 ibdev2netdev 工具查看以太网设备与 InfiniBand 设备/端口的所有关联:
ibdev2netdev
e. 配置网络接口:
ifconfig ens13f0 31.31.31.28 netmask 255.255.255.0
f. 将以下行插入到 /etc/network/interfaces 文件中,位于以下行之后:
vim /etc/network/interfaces
auto eno1
iface eno1 inet dhcp
新行:
auto ens13f0
iface ens13f0 inet static
address 31.31.31.28
netmask 255.255.255.0
示例:
vim /etc/network/interfaces
auto eno1
iface eno1 inet dhcp
auto ens13f0
iface ens13f0 inet static
address 31.31.31.28
netmask 255.255.255.0
g. 检查网络配置是否正确:
ifconfig -a
Lossless Fabric with L3 (DSCP) Configuration
此文章提供了在基于 DSCP 的 QoS 模式下,使用 MLNX_OFED 安装的 NVIDIA 设备运行 RoCE 无损网络的配置示例。
适用于我们环境的示例:
符号说明
指父接口(例如 ens13f0)
指 mlx 设备(例如 mlx5_0)
要获取上述信息,请运行:
ibdev2netdev
指 MST 设备(例如 /dev/mst/mt4121_pciconf0),通过运行:
mst start
mst status
Configuration:
mlnx_qos -i ens13f0 --trust dscp
echo 106 > /sys/class/infiniband/mlx5_0/tc/1/traffic_class
cma_roce_tos -d mlx5_0 -t 106
sysctl -w net.ipv4.tcp_ecn=1
mlnx_qos -i ens13f0 --pfc 0,0,0,1,0,0,0,0
Validate MOFED
检查 "mofed" 版本和 "uverbs":
ofed_info -s
MLNX_OFED_LINUX-4.7-3.2.9.0
ls /dev/infiniband/uverbs1
在容器中运行 InfiniBand 带宽压力测试。
| Server | ib_write_bw -a -d mlx5_0 & |
|---|---|
| Client | ib_write_bw -a -F $server_IP -d mlx5_0 --report_gbits |
这样可以在容器之间运行 RoCE 带宽压力测试。
Configuring the Environment
注意: SparkUCX 和 HADOOP 配置步骤在 Master 节点上完成。
Installing Unified Communication X(UCX) on the Master and Worker Servers (From sources)
cd /tmp
git clone –b v1.8.x git@github.com:openucx/ucx.git
cd ucx
mkdir build
./autogen.sh
cd build
../contrib/configure-devel –with-java –prefix=$PWD
make –j `nproc`
make install
Untar the Spark and archives
cd /share/sparkucx
tar -xzvf spark-2.4.4-bin-hadoop2.7.tgz
所有脚本、jar 包和配置文件均位于新创建的目录 "spark-2.4.4-bin-hadoop2.7" 中。
Unpack the SparkUCX jar file to /tmp directory and copy to Spark directory
spark-ucx-1.0-for-spark-2.4-jar-with-dependencies.jar.zip
cp /tmp/spark-ucx-1.0-for-spark-2.4-jar-with-dependencies.jar /share/sparkucx/spark-2.4.4-bin-hadoop2.7/spark-ucx-1.0-for-spark-2.4-jar-with-dependencies.jar
Spark Configuration
-
更新 bash 文件,运行:
vim ~/.bashrc在文本编辑器底部添加以下行:
export JAVA_HOME=/usr/lib/jvm/java-8-oracle/ export SPARK_HOME=/share/sparkucx/spark-2.4.4-bin-hadoop2.7/ -
保存并关闭文件后,运行以下命令重新加载
.bashrc文件:source ~/.bashrc -
检查路径是否正确修改。
echo $JAVA_HOME
echo $SPARK_HOME
echo $LD_LIBRARY_PATH
- 编辑
spark-env.sh
现在编辑配置文件 spark-env.sh(位于 $SPARK_HOME/conf/)并设置以下参数:
创建 spark-env.sh 模板的副本并重命名。添加主节点主机名、接口和 spark_tmp 目录。
cd /share/sparkucx/spark-2.4.4-bin-hadoop2.7/conf
cp spark-env.sh.template spark-env.sh
vim spark-env.sh
# Generic options for the daemons used in the standalone deploy mode
# - SPARK_CONF_DIR Alternate conf dir. (Default: ${SPARK_HOME}/conf)
# - SPARK_LOG_DIR Where log files are stored. (Default: ${SPARK_HOME}/logs)
# - SPARK_PID_DIR Where the pid file is stored. (Default: /tmp)
# - SPARK_IDENT_STRING A string representing this instance of spark. (Default: $vuhuong)
# - SPARK_NICENESS The scheduling priority for daemons. (Default: 0)
#export SPARK_MASTER_HOST=spark1-r
export SPARK_MASTER_HOST=namenoder
export SPARK_LOCAL_IP=`/sbin/ip addr show enp1f0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1`
export SPARK_LOCAL_DIRS=/data/spark-tmp
Add slaves
Create a copy of the template of slaves configuration file, rename it to slaves (in $SPARK_HOME/conf/) and add the following entries:
$ vim /share/sparkucx/spark-2.4.4-bin-hadoop2.7/conf/slaves
clx-mld-41-r
clx-mld-42-r
clx-mld-43-r
...
clx-mld-55-r
Hadoop 配置
- 复制
conf/slaves到hadoop-2.7.4/etc/hadoop/slaves
cp /share/sparkucx/spark-2.4.4-bin-hadoop2.7/conf/slaves /share/sparkucx/hadoop-2.7.4/etc/hadoop/slaves
- 创建分布式文件系统
sbin/slaves.sh mkdir /data/hadoop_tmp # on NVMe disk
- 编辑
current_config/core-site.xml。在<configuration>标签内添加两个 property 标签。
cd /share/sparkucx/hadoop-2.7.7
vim current_config/core-site.xml
<?xml-stylesheet type="text/xsl" href="https://networking-docs.nvidia.com/sol/configuration.xsl"?>
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. See accompanying LICENSE file.
-->
<!-- Put site-specific property overrides in this file. -->
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://namenoder:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/data/hadoop_tmp</value>
</property>
</configuration>
- 更新 bash 文件,运行:
vim ~/.bashrc
这将打开你的 bash 文件,滚动到底部并添加以下行:
export HADOOP_HOME=/share/sparkucx/hadoop-2.7.7/
- 保存并关闭文本文件后,返回原始终端并输入以下命令重新加载
.bashrc文件:
source ~/.bashrc
- 检查路径是否正确修改:
echo $HADOOP_HOME
- 编辑
current_config/hadoop-env.sh
现在编辑配置文件 current_config/hadoop-env.sh(位于 $HADOOP_HOME/etc/hadoop)并设置以下参数:
添加 HADOOP_HOME 目录。
vim current_config/hadoop-env.sh
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Set Hadoop-specific environment variables here.
# The only required environment variable is JAVA_HOME. All others are
# optional. When running a distributed configuration it is best to
# set JAVA_HOME in this file, so that it is correctly defined on
# remote nodes.
# The java implementation to use.
export JAVA_HOME=${JAVA_HOME}
export HADOOP_HOME=/share/sparkucx/hadoop-2.7.7/
export HADOOP_PREFIX=$HADOOP_HOME
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop/
HDFS 配置
- 编辑
current_config/hdfs-site.xml
vim current_config/hdfs-site.xml
<!-- Put site-specific property overrides in this file. -->
<configuration>
<property>
<name>dfs.datanode.dns.interface</name>
<value>enp1f0</value>
</property>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.datanode.registration.ip-hostname-check</name>
<value>false</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/data/hadoop_tmp</value>
</property>
</configuration>
YARN 配置
注意: 本示例中未使用 YARN,但你可以在部署中使用它。
- 编辑
current_config/yarn-site.xml
vim current_config/yarn-site.xml
<?xml version="1.0"?>
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. See accompanying LICENSE file.
-->
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>namenoder:8025</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>namenoder:8030</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>namenoder:8032</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>namenoder:8034</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>namenoder:8101</value>
</property>
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>40960</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>40960</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>40960</value>
</property>
</configuration>
<value>2048</value>
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>20</value>
</property>
<property>
<name>yarn.nodemanager.disk-health-checker.enable</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.log-dirs</name>
<value>/tmp/yarn_nm/</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
</configuration>
-
编辑
current_config/yarn-env.sh。指定 hadoop 目录。vim current_config/yarn-env.sh ... export HADOOP_HOME=/share/sparkucx/hadoop-2.7.7/ RDMA_IP=`/usr/sbin/ip addr show ens13f0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1` export YARN_NODEMANAGER_OPTS="-Dyarn.nodemanager.hostname=$RDMA_IP" .... -
将
current_config/*复制到etc/hadoop/。cp current_config/* etc/hadoop/ -
在 NameNode 主机上执行以下命令以格式化 HDFS:
bin/hdfs namenode -format
启动 Spark Standalone 集群
在 Hadoop 集群之上运行 SparkUCX。

在 Master 上运行以下命令以启动 Spark 服务:
cd /share/sparkucx/spark-2.4.4-bin-hadoop2.7
sbin/start-all.sh
检查服务是否已启动
在 Master 上检查守护进程:
jps
33970 Jps
47928 ResourceManager
48121 NodeManager
47529 DataNode
47246 NameNode
在 Slave 上检查守护进程:
jps
1846 NodeManager
16491 Jps
1659 DataNode
检查 HDFS 和 YARN(可选)状态:
cd /share/sparkucx/hadoop-2.7.7
bin/hdfs dfsadmin -report | grep Name
Name: 31.31.31.43:50010 (clx-mld-43-r)
Name: 31.31.31.47:50010 (clx-mld-47-r)
Name: 31.31.31.48:50010 (clx-mld-48-r)
Name: 31.31.31.45:50010 (clx-mld-45-r)
Name: 31.31.31.42:50010 (clx-mld-42-r)
Name: 31.31.31.41:50010 (namenoder)
...
Name: 31.31.31.55:50010 (clx-mld-53-r)
bin/hdfs dfsadmin -report | grep Name -c
15
bin/yarn node -list
18/02/20 16:56:31 INFO client.RMProxy: Connecting to ResourceManager at namenoder/31.31.31.41:8101
Total Nodes:15
Node-Id Node-State Node-Http-Address Number-of-Running-Containers
clx-mld-42-r:34873 RUNNING clx-mld-42-r:8042 0
clx-mld-47-r:35045 RUNNING clx-mld-47-r:8042 0
clx-mld-48-r:44996 RUNNING clx-mld-48-r:8042 0
clx-mld-46-r:45432 RUNNING clx-mld-46-r:8042 0
clx-mld-45-r:41307 RUNNING clx-mld-45-r:8042 0
...
clx-mld-55-r:44311 RUNNING clx-mld-55-r:8042 0
namenoder:41409 RUNNING namenoder:8042 0
停止集群
在 Master 上运行以下命令以停止 Spark 服务:
cd /share/sparkucx/spark-2.4.4-bin-hadoop2.7
sbin/stop-all.sh
NVIDIA 网卡性能调优
建议运行 mlnx_tune 工具,该工具将执行多项系统检查并提供可能导致性能下降的潜在设置通知。
您可以根据发现结果采取相应措施。
有关 mlnx_tune 的更多信息,请阅读此文章:HowTo Tune Your Linux Server for Best Performance Using the mlnx_tune Tool
该命令还将显示网络驱动程序使用的 CPU 核心。此信息将用于 Spark 性能调优。
sudo mlnx_tune
2017-08-16 14:47:17,023 INFO Collecting node information
2017-08-16 14:47:17,023 INFO Collecting OS information
2017-08-16 14:47:17,026 INFO Collecting CPU information
2017-08-16 14:47:17,104 INFO Collecting IRQ Balancer information
. . .
Local CPUs list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
. . .
2018-02-16 14:47:18,777 INFO System info file: /tmp/mlnx_tune_180416_144716.log
运行 mlnx_tune 命令后,强烈建议设置 cpuList 参数。
修改 spark.conf 文件以使用与 NVIDIA 设备关联的 NUMA 核心。
Local CPUs list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
spark.shuffle.rdma.cpuList 0-15
更多深入性能资源请参阅 NVIDIA 社区文章:Performance Tuning for NVIDIA 网卡
SparkUCX 性能提示
-
压缩: Spark 默认启用压缩。使用压缩会减小节点间发送的数据包大小,但会增加 CPU 利用率以压缩数据。 由于 RDMA 网络的高性能和低 CPU 开销特性,建议在使用 SparkUCX 时禁用压缩。 在
spark.conf文件中设置:spark.shuffle.compress false spark.shuffle.spill.compress false禁用压缩后,您可以回收之前用于数据压缩/解压缩的宝贵 CPU 周期,并在 RDMA 数据传输速度上看到额外的性能提升。
-
磁盘介质: 为了获得最高且最一致的性能结果,建议使用最高性能的磁盘介质。 尽可能考虑使用 ramdrive 或 NVMe 设备作为 spark-tmp 和 hadoop tmp 文件。
恭喜,您现在拥有了一个 RDMA 加速的 Spark 集群,可以开始工作了。
接下来我们将运行 HiBench 套件基准测试,以比较 TCP 与 RoCE 的性能。
附录 A:使用 SparkUCX 运行 HiBench
HiBench 是一个大数据基准测试套件,可帮助评估不同大数据框架的速度、吞吐量和系统资源利用率。 它包含一组 Hadoop、Spark 和流处理工作负载,包括 Sort、WordCount、TeraSort、Sleep、SQL、PageRank、Nutch indexing、Bayes、Kmeans、NWeight 和增强型 DFSIO 等。
环境
- 实例类型和环境:请参阅设置概述
- 操作系统:Ubuntu 18.04.3 LTS
- Apache Hadoop:2.7.4,HDFS(1 个 NameNode,14 个 DataNode)
- Spark:2.4.4 独立模式,15 个节点
- 基准测试:设置 HiBench
- 测试日期:2020 年 2 月
基准测试运行
重现 TeraSort 结果的步骤:
-
在 HiBench 的
conf目录中配置 Hadoop 和 Spark 设置。 -
在
HiBench/conf/hibench.conf中设置:hibench.scale.profile bigdata # Mapper number in hadoop, partition number in Spark hibench.default.map.parallelism 3000 # Reducer
RDG:RoCE 加速的 Apache Spark UCX 2.4/3.0 集群部署
创建于 2020 年 2 月 10 日,作者:Boris Kovalev、Peter Rudenko
简介
本参考部署指南 (RDG) 将演示多节点集群部署流程。
基准测试结果
TeraSort 结果重现步骤
-
在
HiBench/conf/hibench.conf中设置:hibench.scale.profile bigdata # Mapper number in hadoop, partition number in Spark hibench.default.map.parallelism 3000 # Reducer number in hadoop, shuffle partition number in Spark hibench.default.shuffle.parallelism 15000 -
在
HiBench/conf/workloads/micro/terasort.conf中设置:hibench.terasort.bigdata.datasize 1890000000 -
运行
HiBench/bin/workloads/micro/terasort/prepare/prepare.sh和HiBench/bin/workloads/micro/terasort/spark/run.sh -
在
HiBench/conf/spark.conf中添加:spark.driver.extraClassPath /share/sparkucx/spark-2.4.4-bin-hadoop2.7/spark-ucx-1.0-for-spark-SPARK_VERSION-jar-with-dependencies.jar:/share/sparkucx/spark-2.4.4-bin-hadoop2.7/build/lib/spark.executor.extraClassPath spark.executor.extraClassPath /share/sparkucx/spark-2.4.4-bin-hadoop2.7/spark-ucx-1.0-for-spark-SPARK_VERSION-jar-with-dependencies.jar:/share/sparkucx/spark-2.4.4-bin-hadoop2.7/build/lib/spark.shuffle.manager org.apache.spark.shuffle.UcxShuffleManager spark.shuffle.manager org.apache.spark.shuffle.UcxShuffleManager spark.shuffle.compress false spark.shuffle.spill.compress false spark.shuffle.sort.io.plugin.class org.apache.spark.shuffle.compat.spark_3_0.UcxLocalDiskShuffleDataIO -
运行
HiBench/bin/workloads/micro/terasort/spark/run.sh
Pagerank 排序结果重现步骤
-
在
HiBench/conf/hibench.conf中设置:hibench.scale.profile bigdata # Mapper number in hadoop, partition number in Spark hibench.default.map.parallelism 3000 # Reducer number in hadoop, shuffle partition number in Spark hibench.default.shuffle.parallelism 15000 -
运行
HiBench/bin/workloads/micro/sort/prepare/prepare.sh和HiBench/bin/workloads/micro/sort/spark/run.sh
基准测试结果

完成!
关于作者
关于 Boris Kovalev

过去几年,Boris Kovalev 在 NVIDIA 技术部门担任解决方案架构师,负责复杂的机器学习和基于 VMware 的高级云研究与设计。此前,他在多家公司担任高级顾问和解决方案架构师超过 15 年,最近在 VMware 工作。他撰写了多份参考设计,涵盖 VMware、机器学习、Kubernetes 和容器解决方案,这些文档可在 NVIDIA 文档网站上获取。
关于 Peter Rudenko

Peter Rudenko 是高性能计算团队的软件工程师,专注于加速数据密集型应用,开发 UCX 通信库和各种大数据解决方案。

