MPI 프로그램이 네트워크에 과부하를 걸면 Ubuntu 22.04의 TCP/IP 네트워크가 응답하지 않게 됩니다.

MPI 프로그램이 네트워크에 과부하를 걸면 Ubuntu 22.04의 TCP/IP 네트워크가 응답하지 않게 됩니다.

Ubuntu 22.04.3 LTS를 실행하는 두 개의 동일한 서버가 있습니다. 두 시스템 모두 총 192개의 코어와 512GB RAM을 갖춘 2개의 AMD 9654 CPU를 갖추고 있습니다. 각 서버에는 마더보드에 2개의 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기가비트 L2+ 스마트 스위치에 연결되어 있습니다. iperf를 사용하여 네트워크 테스트도 수행했습니다. 결과(여기에는 표시되지 않았지만 유용한 경우 사용 가능)는 두 호스트 간의 지속 대역폭이 10.0GB/초임을 확인합니다.

이제 내 질문입니다. 저는 응용 수학 박사 과정 학생이고 이 서버를 사용하여 대규모 수치 시뮬레이션 코드를 실행합니다. 시뮬레이션 프로그램은 MPI를 사용합니다. 나는 이 프로그램을 테스트했으며 한 번에 한 호스트의 192개 코어에서 완벽하게 실행됩니다. 적은 수의 코어(예: 코어당 8개)를 사용하는 경우 두 개의 호스트에서 프로그램을 실행할 수도 있습니다. 그런데 많은 수의 코어로 실행하려고 하면 프로세스 간의 TCP 연결이 끊어져서 MPI 프로그램이 중단됩니다. 다음은 호스트당 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 문서를 읽으면서 10GB TCP/IP 네트워크에서 MPI를 실행하려면 여러 Linux 커널 매개변수를 조정해야 한다는 힌트를 보았습니다. 이러한 변경 사항을 /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를 실행합니다. 모든 것이 완전히 일반적인 구성으로 되어 있습니다. 네트워크 본딩이 없는 기가비트 네트워크입니다. 나는 내 컴퓨터에서 겪었던 문제를 정확하게 재현할 수 있었습니다. 유일한 차이점은 이전 시스템이 노드당 MPI 프로세스가 8개에 불과하여 네트워크 부하로 인해 압도당했다는 것입니다.

이것이 내 직감입니다. MPI는 공유 메모리를 사용하여 동일한 노드의 프로세스 간에 통신합니다. 매우 빠르며 TCP/IP 네트워크에 부하를 주지 않습니다. 서로 다른 노드에 걸쳐 있는 MPI 프로세스 쌍 간의 각 연결에는 소켓과 TCP 연결이 필요합니다. 이로 인해 여러 코어에서 대규모 시뮬레이션을 실행할 때 TCP/IP 네트워크에 막대한 부하가 발생합니다. 버퍼 크기를 늘리면 도움이 되지만 여전히 속도가 느리고 TCP 네트워크가 완전히 중단되기 쉽습니다. 대부분의 대규모 슈퍼컴퓨팅 클러스터는 Infiniband와 같은 더 빠른 네트워킹 솔루션을 사용하기 때문에 이것이 HPC 세계의 엣지 케이스라고 생각합니다. 10GB 이더넷을 통해 1000개의 CPU로 확장하려는 다른 사람을 본 적이 없습니다.

Stack Exchange의 누군가가 이러한 유형의 문제에 대해 잘 알고 있고 제안 사항이 있다면 매우 감사하겠습니다. 저는 이제 박사과정 4년차에 접어들었고 이 문제를 해결하기 위해 2주 이상을 보냈습니다. 오랜 회원님의 노고에 진심으로 감사드립니다.

-남자 이름

관련 정보