我有两台运行 Ubuntu 22.04.3 LTS 的相同服务器。两个系统均配备 2 个 AMD 9654 CPU,共有 192 个内核和 512 GB RAM。每台服务器的主板上内置有两个 10G 以太网端口。这些 10G 端口配置为使用 netplan 创建单个链路聚合。
整个网络配置在正常负载下运行良好。以下是第一台服务器 (Thor) 的 $ip a 的输出:
Thor$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: Ethernet-10G-1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master Bond-10G state UP group default qlen 1000
link/ether 00:00:00:00:00:04 brd ff:ff:ff:ff:ff:ff permaddr a0:36:bc:c8:c6:9b
altname enp15s0f0
3: Ethernet-10G-2: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master Bond-10G state UP group default qlen 1000
link/ether 00:00:00:00:00:04 brd ff:ff:ff:ff:ff:ff permaddr a0:36:bc:c8:c6:9c
altname enp15s0f1
4: Bond-10G: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:00:00:00:00:04 brd ff:ff:ff:ff:ff:ff
inet 10.0.1.203/22 brd 10.0.3.255 scope global dynamic noprefixroute Bond-10G
valid_lft 31554381sec preferred_lft 31554381sec
inet6 fe80::200:ff:fe00:4/64 scope link
valid_lft forever preferred_lft forever
以下是正常情况下从第一台服务器到第二台服务器 (Loki) 的 ping 输出:
Thor$ ping loki
PING loki.elliptic.loc (10.0.1.204) 56(84) bytes of data.
64 bytes from Loki.elliptic.loc (10.0.1.204): icmp_seq=1 ttl=64 time=0.139 ms
这表明延迟很低,为 139 微秒。两台服务器都连接到同一台交换机,即 Netgear XS728T 28 端口 10 Gigabit L2+ 智能交换机。我还使用 iperf 进行了网络测试。结果(此处未显示,但如果有用则可用)确认两台主机之间的持续带宽为 10.0 GB/秒。
现在谈谈我的问题。我是应用数学专业的博士生,我使用这些服务器来运行大规模数值模拟代码。仿真程序采用MPI。我已经测试过这个程序,它一次可以在一台主机上的 192 个内核上完美运行。如果我使用少量核心(例如每个核心 8 个),我还可以在两台主机上运行该程序。但是,当我尝试使用大量内核运行它时,MPI 程序会挂起,因为它丢失了进程之间的 TCP 连接。以下是我尝试在每台主机上的 192 个核心(总共 384 个核心)上运行它但失败时的错误输出示例:
WARNING: Open MPI failed to TCP connect to a peer MPI process. This
should not happen.
Your Open MPI job may now hang or fail.
Local host: Thor
PID: 8076
Message: connect() to 10.0.1.204:1162 failed
Error: No route to host (113)
此外,即使在 MPI 程序终止后,一台或两台服务器上的 IP 网络也不再起作用。在网络出现故障后,我可以使用带外 IPMI 工具来访问服务器。一旦 TCP/IP 网络失效,对 ping 的调用将导致错误消息“目标主机无法访问”。在这种状态下,机器甚至无法 ping 通路由器或网络交换机。在这种情况下我能够恢复它的唯一方法是完全重新启动。
在这种情况下,我检查了远程服务器上 $ip a 的输出,它看起来与它开始的位置相同。如果我遗漏了什么,我会将其粘贴在下面:
Loki $ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: Ethernet-10G-1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master Bond-10G state UP group default qlen 1000
link/ether 00:00:00:00:00:05 brd ff:ff:ff:ff:ff:ff permaddr a0:36:bc:c8:c7:2b
altname enp15s0f0
3: Ethernet-10G-2: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master Bond-10G state UP group default qlen 1000
link/ether 00:00:00:00:00:05 brd ff:ff:ff:ff:ff:ff permaddr a0:36:bc:c8:c7:2c
altname enp15s0f1
4: Bond-10G: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:00:00:00:00:05 brd ff:ff:ff:ff:ff:ff
inet 10.0.1.204/22 brd 10.0.3.255 scope global dynamic noprefixroute Bond-10G
valid_lft 31555883sec preferred_lft 31555883sec
inet6 fe80::200:ff:fe00:5/64 scope link
valid_lft forever preferred_lft forevera
我已经取得了一些小进步,这让我相信问题与 TCP 网络无法跟上快速创建的许多连接的负载并发送大量流量有关。通读 OpenMPI 文档,我看到一些提示:应该调整几个 Linux 内核参数才能在 10 GB TCP/IP 网络上运行 MPI。我将这些更改输入到 /etc/sysctl.d/21-net.conf 中,如下所示:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.netdev_max_backlog = 30000
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.ipv4.tcp_mem = 16777216 16777216 16777216
net.ipv4.route.flush = 1
在进行这些更改之前,我什至无法让程序在每个节点上运行 8 个 MPI 进程。进行更改后,每个节点上可以运行 32 个 MPI 进程。我又进行了一轮更改,并进一步增加了它们,将 net.core.rmem_max 和 net.ipv4.tcp_mem 提高到最大值 2^31-1。通过此更改,该程序能够在两台主机上的每台主机上的 128 个核心上运行,但当我尝试使用所有 192 个核心时仍然挂起。
这是最后一个数据点。我使用我的博士导师提供的两台完全不同的计算机重复了这个测试。它们有点旧,每个都有 28 个 CPU,运行 Ubuntu 20.04 LTS。一切都处于完全典型的配置中:没有任何网络绑定的千兆位网络。我能够准确地复制我的机器上遇到的问题。唯一的区别是旧机器在每个节点上只有 8 个 MPI 进程的网络负载下不堪重负。
这是我的直觉。 MPI 使用共享内存在同一节点上的进程之间进行通信。它非常快并且不会给 TCP/IP 网络带来任何负载。跨不同节点的一对 MPI 进程之间的每个连接都需要一个套接字和一个 TCP 连接。当在多个内核上运行大型模拟时,这会给 TCP/IP 网络带来巨大的负载。增加缓冲区大小会有所帮助,但仍然很慢并且容易使 TCP 网络完全崩溃。我认为这是 HPC 世界中的一种边缘情况,因为大多数大型超级计算集群都使用更快的网络解决方案,例如 Infiniband。我还没有遇到任何其他人试图通过 10 GB 以太网扩展到 1000 个 CPU。
如果 Stack Exchange 上有人熟悉此类问题并有任何建议,我将非常感激。我现在是博士课程的第四年,我已经花了两周多的时间来解决这个问题。非常感谢一位长期会员。
-迈克尔