9.3. 구성 툴
Red Hat Enterprise Linux는 관리자가 시스템 구성을 지원하는 다양한 툴을 제공합니다. 이 섹션에서는 사용 가능한 툴을 간략하게 설명하고 Red Hat Enterprise Linux 7의 네트워크 관련 성능 문제를 해결하는 데 사용할 수 있는 방법에 대한 예를 제공합니다.
그러나 네트워크 성능 문제가 하드웨어 오작동 또는 잘못된 인프라의 결과인 경우가 있다는 점에 유의해야 합니다. Red Hat은 이러한 툴을 사용하여 네트워크 스택을 조정하기 전에 하드웨어 및 인프라가 예상대로 작동하는지 확인하는 것이 좋습니다.
또한 일부 네트워크 성능 문제는 네트워크 하위 시스템을 재구성하는 것보다 애플리케이션을 변경하여 해결할 수 있습니다. 일반적으로 애플리케이션 공간의 데이터를 대기열에 추가하더라도 애플리케이션을 구성하는 것이 좋습니다. 이렇게 하면 데이터를 유연하게 저장하고 필요에 따라 메모리 스와핑 또는 스와핑할 수 있기 때문입니다.
9.3.1. 네트워크 성능을 위한 튜닝된 프로필
Tuned 서비스는 다양한 특정 사용 사례에서 성능을 개선하기 위해 다양한 프로필을 제공합니다. 다음 프로필은 네트워킹 성능을 개선하는 데 유용할 수 있습니다.
- latency-performance
- network-latency
- Network-throughput
이러한 프로필에 대한 자세한 내용은 A.5절. “tuned-adm” 을 참조하십시오.
9.3.2. 하드웨어 버퍼 구성
하드웨어 버퍼에 의해 많은 수의 패킷이 삭제되는 경우 잠재적인 솔루션이 많이 있습니다.
- 입력 트래픽 속도 저하
- 들어오는 트래픽을 필터링하거나, 결합된 멀티 캐스트 그룹의 수를 줄이거나, 브로드캐스트 트래픽 양을 줄여 큐가 채우는 속도를 줄입니다. 들어오는 트래픽을 필터링하는 방법에 대한 자세한 내용은 Red Hat Enterprise Linux 7 보안 가이드를 참조하십시오. 멀티 캐스트 그룹에 대한 자세한 내용은 Red Hat Enterprise Linux 7 Cryostat 설명서를 참조하십시오. 브로드캐스트 트래픽에 대한 자세한 내용은 Red Hat Enterprise Linux 7 시스템 관리자 가이드 또는 구성하려는 장치와 관련된 설명서를 참조하십시오.
- 하드웨어 버퍼 큐 크기 조정
- 큐의 크기를 늘림으로써 삭제되는 패킷 수를 줄임으로써 오버플로우가 쉽게 발생하지 않도록 합니다. ethtool 명령을 사용하여 네트워크 장치의 rx/tx 매개변수를 수정할 수 있습니다.
# ethtool --set-ring devname value
- 큐의 드레이닝 속도 변경
- 장치 가중치는 장치가 한 번에 수신할 수 있는 패킷 수(단일 예약된 프로세서 액세스)를 나타냅니다. 장치 가중치를 늘리면 큐가 드레이닝되는 속도를 늘릴 수 있으며, 이는
dev_weight
매개변수에 의해 제어됩니다. 이 매개변수는/proc/sys/net/core/dev_weight
파일의 내용을 변경하거나 procps-ng 패키지에서 제공하는 sysctl 을 사용하여 영구적으로 변경되어 일시적으로 변경할 수 있습니다.
큐의 드레이닝 속도를 변경하는 것은 일반적으로 잘못된 네트워크 성능을 완화하는 가장 간단한 방법입니다. 그러나 한 번에 장치가 수신할 수 있는 패킷 수를 늘리면 다른 프로세스를 예약할 수 없는 추가 프로세서 시간을 사용하므로 다른 성능 문제가 발생할 수 있습니다.
9.3.3. 인터럽트 대기열 구성
분석에서 높은 대기 시간을 보이면 시스템은 인터럽트 기반 패킷 수신 대신 폴링 기반 패킷의 이점을 얻을 수 있습니다.
9.3.3.1. Busy Polling 구성
사용 중인 폴링은 소켓 계층 코드가 네트워크 장치의 수신 대기열을 폴링하고 네트워크 인터럽트를 비활성화하도록 허용하여 네트워크 수신 경로의 대기 시간을 줄일 수 있습니다. 이렇게 하면 인터럽트 및 결과 컨텍스트 스위치로 인한 지연이 제거됩니다. 그러나 CPU 사용률도 늘어납니다. 또한 사용량이 많은 폴링을 통해 CPU가 자고 있는 것을 방지하므로 추가 전력 소비가 발생할 수 있습니다.
사용 중인 폴링은 기본적으로 비활성화되어 있습니다. 특정 소켓에서 사용 중인 폴링을 활성화하려면 다음을 수행합니다.
sysctl.net.core.busy_poll
을0
이 아닌 값으로 설정합니다. 이 매개 변수는 소켓 폴링에 대해 장치 대기열의 패킷을 대기하고 선택하도록 대기하는 마이크로초의 수를 제어합니다. Red Hat은 값50
을 권장합니다.SO_BUSY_POLL
소켓 옵션을 소켓에 추가합니다.
전역적으로 사용 중인 폴링을 활성화하려면
sysctl.net.core.busy_read
를 0
이외의 값으로 설정해야 합니다. 이 매개 변수는 소켓 읽기를 위해 장치 대기열의 패킷을 대기하는 마이크로초의 수를 제어합니다. 또한 SO_BUSY_POLL
옵션의 기본값을 설정합니다. Red Hat은 적은 수의 소켓에 대해 값 50
을 권장하고 많은 소켓에 대해 값 100
을 권장합니다. 매우 많은 수의 소켓(백개 이상)의 경우 대신 epoll
를 사용합니다.
사용량이 많은 폴링 동작은 다음 드라이버에서 지원합니다. 이러한 드라이버는 Red Hat Enterprise Linux 7에서도 지원됩니다.
- bnx2x
- be2net
- ixgbe
- mlx4
- myri10ge
Red Hat Enterprise Linux 7.1부터 다음 명령을 실행하여 특정 장치가 사용 중인 폴링을 지원하는지 확인할 수도 있습니다.
# ethtool -k device | grep "busy-poll"
[fixed]에서 busy-poll: on
를 반환하는 경우 장치에서 사용 가능한 폴링을 사용할 수 있습니다.
9.3.4. 소켓 수신 대기열 구성
소켓 대기열의 드레이닝 속도가 너무 느리기 때문에 패킷이 삭제되는 것으로 분석되면 결과 성능 문제를 완화하는 몇 가지 방법이 있습니다.
- 들어오는 트래픽의 속도 감소
- 패킷이 큐에 도달하기 전에 패킷을 필터링하거나 삭제하거나 장치의 가중치를 낮추어 큐가 채우는 속도를 줄입니다.
- 애플리케이션 소켓 대기열의 깊이 증가
- 버스트에서 제한된 양의 트래픽을 수신하는 소켓 대기열의 경우 트래픽 버스트 크기와 일치하도록 소켓 대기열의 깊이를 늘리면 패킷이 삭제되지 않을 수 있습니다.
9.3.4.1. 들어오는 트래픽의 속도 감소
들어오는 트래픽을 필터링하거나 네트워크 인터페이스 카드의 장치 가중치를 낮추어 들어오는 트래픽 속도가 느려집니다. 들어오는 트래픽을 필터링하는 방법에 대한 자세한 내용은 Red Hat Enterprise Linux 7 보안 가이드를 참조하십시오.
장치 가중치는 장치가 한 번에 수신할 수 있는 패킷 수(단일 예약된 프로세서 액세스)를 나타냅니다. 장치 가중치는
dev_weight
매개변수에 의해 제어됩니다. 이 매개변수는 /proc/sys/net/core/dev_weight
파일의 내용을 변경하거나 procps-ng 패키지에서 제공하는 sysctl 을 사용하여 영구적으로 변경되어 일시적으로 변경할 수 있습니다.
9.3.4.2. 대기열 삭제 증가
애플리케이션 소켓 대기열의 깊이를 높이는 것은 일반적으로 소켓 대기열의 드레이닝 속도를 개선하는 가장 쉬운 방법이지만 장기적인 솔루션이 될 가능성은 낮습니다.
큐의 깊이를 늘리려면 다음 변경 중 하나를 수행하여 소켓 수신 버퍼의 크기를 늘립니다.
- /proc/sys/net/core/rmem_default 값을 늘립니다.
- 이 매개 변수는 소켓에서 사용하는 수신 버퍼의 기본 크기를 제어합니다. 이 값은
/proc/sys/net/core/rmem_max
값보다 작거나 같아야 합니다. - setsockopt를 사용하여 더 큰 SO_RCVBUF 값 구성
- 이 매개변수는 소켓 수신 버퍼의 최대 크기(바이트)를 제어합니다.
getsockopt
시스템 호출을 사용하여 버퍼의 현재 값을 확인합니다. 자세한 내용은 socket(7) 매뉴얼 페이지를 참조하십시오.
9.3.5. RSS(Receive-Side Scaling) 구성
다중 대기열 수신(RSS)이라고도 하는 수신-Side Scaling(RSS)은 여러 하드웨어 기반 수신 대기열에서 네트워크 수신 처리를 분배하여 여러 CPU에서 인바운드 네트워크 트래픽을 처리할 수 있도록 합니다. RSS를 사용하면 단일 CPU를 과부하하고 네트워크 대기 시간을 단축하여 수신 인터럽트 처리의 병목 현상을 완화할 수 있습니다.
네트워크 인터페이스 카드가 RSS를 지원하는지 여부를 확인하려면 여러 인터럽트 요청 대기열이
/proc/interrupts
의 인터페이스와 연결되어 있는지 확인합니다. 예를 들어 p1p1
인터페이스에 관심이 있는 경우 다음을 수행합니다.
# egrep 'CPU|p1p1' /proc/interrupts CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 89: 40187 0 0 0 0 0 IR-PCI-MSI-edge p1p1-0 90: 0 790 0 0 0 0 IR-PCI-MSI-edge p1p1-1 91: 0 0 959 0 0 0 IR-PCI-MSI-edge p1p1-2 92: 0 0 0 3310 0 0 IR-PCI-MSI-edge p1p1-3 93: 0 0 0 0 622 0 IR-PCI-MSI-edge p1p1-4 94: 0 0 0 0 0 2475 IR-PCI-MSI-edge p1p1-5
이전 출력에서는 NIC 드라이버가 6을 생성한
p1p1
인터페이스(p1p1-0
~ p1p1-5
)의 대기열을 수신함을 보여줍니다. 또한 각 대기열에서 처리된 인터럽트 수와 인터럽트를 서비스한 CPU도 보여줍니다. 이 경우 기본적으로 6개의 대기열이 있습니다. 이 특정 NIC 드라이버는 CPU당 하나의 큐를 생성하고 이 시스템에는 6개의 CPU가 있습니다. 이는 NIC 드라이버 중 상당히 일반적인 패턴입니다.
또는 네트워크 드라이버가 로드된 후 ls -1 /sys/devices/*/device_pci_address/msi_irqs의 출력을 확인할 수 있습니다. 예를 들어 PCI 주소가
0000:01:00.0
인 장치에 관심이 있는 경우 다음 명령을 사용하여 해당 장치의 인터럽트 요청 대기열을 나열할 수 있습니다.
# ls -1 /sys/devices/*/*/0000:01:00.0/msi_irqs 101 102 103 104 105 106 107 108 109
RSS는 기본적으로 활성화되어 있습니다. RSS에 대한 네트워크 활동을 처리해야 하는 대기열(또는 CPU 수)은 적절한 네트워크 장치 드라이버에 구성됩니다.
bnx2x
드라이버의 경우 num_queues
에 구성됩니다. sfc
드라이버의 경우 rss_cpus
매개변수에 구성됩니다. 상관 없이 일반적으로 /sys/class/net/장치/queues/rx-queue/
에서 구성됩니다. 여기서 장치는 네트워크 장치의 이름(예: eth1
) 및 rx-queue 는 적절한 수신 대기열의 이름입니다.
RSS를 구성할 때 Red Hat은 물리적 CPU 코어당 대기열 수를 하나로 제한하는 것이 좋습니다. Hyper-threads는 종종 분석 도구에서 별도의 코어로 표시되지만, 논리 코어를 포함하여 모든 코어의 대기열을 구성하는 것은 네트워크 성능에 도움이 되지 않았습니다.
활성화하면 RSS는 각 CPU가 대기한 처리 양에 따라 사용 가능한 CPU 간에 네트워크 처리를 동일하게 분배합니다. 그러나 ethtool
--show-rxfh-indir
및 --set-rxfh-indir
매개변수를 사용하여 네트워크 활동이 배포되는 방식을 수정하고 특정 유형의 네트워크 활동 가중치를 다른 유형보다 더 중요하게 지정할 수 있습니다.
irqbalance
데몬은 RSS와 함께 사용하여 교차 노드 메모리 전송 및 캐시 라인이 발생할 가능성을 줄일 수 있습니다. 이렇게 하면 네트워크 패킷 처리 대기 시간이 단축됩니다.
9.3.6. 수신 패킷 테더링 구성(RPS)
수신 패킷 처리(RPS)는 처리를 위해 패킷을 특정 CPU로 전달하는 데 사용되는 RSS와 유사합니다. 그러나 RPS는 소프트웨어 수준에서 구현되며 단일 네트워크 인터페이스 카드의 하드웨어 큐가 네트워크 트래픽에서 병목 현상이 되는 것을 방지하는 데 도움이 됩니다.
RPS는 하드웨어 기반 RSS보다 몇 가지 장점이 있습니다.
- RPS는 모든 네트워크 인터페이스 카드와 함께 사용할 수 있습니다.
- 새로운 프로토콜을 처리하기 위해 RPS에 소프트웨어 필터를 추가하기 쉽습니다.
- RPS는 네트워크 장치의 하드웨어 인터럽트 속도를 증가시키지 않습니다. 그러나 프로세서 간 인터럽트를 도입합니다.
RPS는 네트워크 장치별로 구성되고 대기열을 수신합니다.
/sys/class/net/장치/queues/rx-queue/rps_cpus
파일에서 여기서 장치는 네트워크 장치의 이름(예: eth0
) 및 rx-queue 는 적절한 수신 대기열의 이름입니다(예: rx-0
).
rps_cpus
파일의 기본값은 0
입니다. 이렇게 하면 RPS가 비활성화되므로 네트워크 인터럽트를 처리하는 CPU도 패킷을 처리합니다.
RPS를 활성화하려면 지정된 네트워크 장치에서 패킷을 처리하고 큐를 수신하는 CPU를 사용하여 적절한
rps_cpus
파일을 구성합니다.
rps_cpus
파일은 쉼표로 구분된 CPU 비트맵을 사용합니다. 따라서 CPU가 인터페이스에서 수신 대기열에 대한 인터럽트를 처리할 수 있도록 하려면 비트맵의 위치 값을 1로 설정합니다. 예를 들어 CPU 0, 1, 2, 3의 인터럽트를 처리하려면 rps_cpus
값을 f
로 설정합니다. 이 값은 15의 16진수 값입니다. 바이너리 표현에서 15는 00001111
(1+2+4+8)입니다.
단일 전송 대기열이 있는 네트워크 장치의 경우 동일한 메모리 도메인에서 CPU를 사용하도록 RPS를 구성하여 최상의 성능을 얻을 수 있습니다. NUMA가 아닌 시스템에서는 사용 가능한 모든 CPU를 사용할 수 있습니다. 네트워크 인터럽트 속도가 매우 높은 경우 네트워크 인터럽트를 처리하는 CPU를 제외하면 성능이 향상될 수 있습니다.
여러 대기열이 있는 네트워크 장치의 경우 기본적으로 각 수신 대기열에 CPU를 매핑하도록 RSS가 구성되어 있으므로 RPS와 RSS를 둘 다 구성하는 이점이 없습니다. 그러나 RPS는 CPU보다 하드웨어 대기열이 적고 RPS가 동일한 메모리 도메인에서 CPU를 사용하도록 구성된 경우에도 계속 유용할 수 있습니다.
9.3.7. RFS(Receive Flow Steering) 구성
RFS( Flow Steering)는 RPS 동작을 확장하여 CPU 캐시 적중률을 높임으로써 네트워크 대기 시간을 줄입니다. RPS가 대기열 길이에 따라 패킷을 전달하는 경우, RFS는 RPS 백엔드를 사용하여 가장 적절한 CPU를 계산한 다음 패킷을 사용하는 애플리케이션의 위치에 따라 패킷을 전달합니다. 이로 인해 CPU 캐시 효율성이 증가합니다.
RFS는 기본적으로 비활성화되어 있습니다. RFS를 활성화하려면 다음 두 파일을 편집해야 합니다.
/proc/sys/net/core/rps_sock_flow_entries
- 이 파일의 값을 동시에 활성 연결의 최대 예상 수로 설정합니다. 중간 서버 로드를 위해
32768
값을 사용하는 것이 좋습니다. 입력된 모든 값은 실제로 가장 가까운 2로 반올림됩니다. /sys/class/net/device/queues/rx-queue/rps_flow_cnt
- 장치를 구성하려는 네트워크 장치의 이름으로 바꾸고(예:
eth0
) rx-queue 는 구성할 수신 대기열(예:rx-0
)으로 바꿉니다.이 파일의 값을N
으로 나눈rps_sock_flow_entries
값으로 설정합니다. 여기서N
은 장치의 수신 대기열 수입니다. 예를 들어rps_flow_entries
가32768
로 설정되어 있고 16개의 수신 대기열이 구성된 경우rps_flow_cnt
를2048
로 설정해야 합니다. 단일 큐 장치의 경우rps_flow_cnt
값은rps_sock_flow_entries
값과 동일합니다.
단일 발신자에서 수신된 데이터는 두 개 이상의 CPU로 전송되지 않습니다. 단일 발신자에서 수신한 데이터의 양이 단일 CPU에서 처리할 수 있는 것보다 크면 인터럽트 수를 줄이고 CPU에 대한 처리 양을 줄이기 위해 더 큰 프레임 크기를 구성합니다. 또는 NIC 오프로드 옵션 또는 더 빠른 CPU를 고려하십시오.
RFS와 함께 numactl 또는 taskset 을 사용하여 애플리케이션을 특정 코어, 소켓 또는 NUMA 노드에 고정하는 것이 좋습니다. 이렇게 하면 패킷이 순서대로 처리되지 않도록 방지할 수 있습니다.
9.3.8. 가속 RFS 구성
RFS 가속 RFS는 하드웨어 지원을 추가하여 RFS의 속도를 향상시킵니다. RFS와 마찬가지로 패킷을 사용하는 애플리케이션의 위치에 따라 패킷이 전달됩니다. 그러나 기존 RFS와 달리 패킷은 데이터를 사용하는 스레드에 로컬인 CPU로 직접 전송됩니다(애플리케이션을 실행하는 CPU 또는 캐시 계층 구조의 해당 CPU 로컬).
가속 RFS는 다음 조건이 충족되는 경우에만 사용할 수 있습니다.
- 가속화 RFS는 네트워크 인터페이스 카드에서 지원해야 합니다. 가속화 RFS는
ndo_rx_flow_steer()
netdevice
기능을 내보내는 카드에서 지원됩니다. n튜플
필터링을 활성화해야 합니다.
이러한 조건이 충족되면 기존 RFS 구성에 따라 CPU to queue 매핑이 자동으로 추론됩니다. 즉, 각 수신 대기열에 대해 드라이버에서 구성한 IRQ를 기반으로 CPU to 큐 매핑이 추론됩니다. 기존 RFS 구성에 대한 자세한 내용은 9.3.7절. “RFS(Receive Flow Steering) 구성” 을 참조하십시오.
Red Hat은 RFS를 사용하는 것이 적합하고 네트워크 인터페이스 카드는 하드웨어 가속을 지원하는 모든 곳에서 가속 RFS를 사용할 것을 권장합니다.