7.5. 스레드 NAPI 사용 중인 폴링을 사용하여 수신 대기 시간 일관성 개선
스레드된 New API(NAPI)의 폴링을 활성화하면 전용 커널 스레드를 사용하여 패킷을 지속적으로 폴링하여 네트워크 대기 시간을 줄일 수 있습니다. AF_XDP 와 같은 고성능 워크로드에 대한 스레드 NAPI 사용량 폴링을 사용합니다. 여기서 예측 가능한 하위 마이크로초 응답 시간이 중요합니다.
표준 Linux 네트워킹에서 커널은 인터럽트 및 소프트웨어 인터럽트 요청(softirqs)을 사용하여 들어오는 패킷을 처리합니다. 이는 CPU가 이러한 인터럽트를 처리하기 위해 컨텍스트를 전환해야 하므로 결정적이지 않은 지연이 발생할 수 있습니다. 스레드 NAPI는 이 처리를 전용 커널 스레드로 이동합니다. 사용 중인 폴링을 활성화하면 이러한 스레드는 CPU에서 활성 상태를 유지하고 잠자기 대신 데이터를 지속적으로 확인합니다. 이렇게 하면 CPU가 잠기고 NAPI 스레드를 실행하는 코어의 100% 사용률에 대한 대기 시간이 제거됩니다.
이 절차에서는 enp1s0 인터페이스에서 구성된 첫 번째 IPv4 주소로 전송된 HTTPS 트래픽에 대한 폴링을 사용하는 스레드 NAPI를 활성화합니다.
사전 요구 사항
- 호스트는 RHEL 10.2 이상을 실행합니다.
- 호스트에는 NAPI를 지원하는 NIC(네트워크 인터페이스 컨트롤러)가 있습니다.
-
Cryo
stat및kernel-tools패키지가 설치됩니다.
프로세스
소프트웨어 중단 포화 상태가 호스트의 병목 현상인지 확인합니다.
모든 CPU 코어의 softirqs를 모니터링합니다. 예를 들면 다음과 같습니다.
# mpstat -P ALL 110:16:05 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 10:16:06 all 5,25 0,00 3,50 0,50 0,25 21,50 0,00 0,00 0,00 69,00 10:16:06 0 2,00 0,00 12,00 0,00 1,00 85,00 0,00 0,00 0,00 0,00 10:16:06 1 15,00 0,00 1,00 0,00 0,00 1,00 0,00 0,00 0,00 83,00 ...이 예에서 코어 0에 대한 사용률 메트릭은 총 CPU 포화 상태로 인해 네트워크 처리량에 심각한 병목 현상을 생성합니다.
-
%soft(85%): 코어가 커널 네트워크 스택 내에서 softirq 패킷 처리에 의해 거의 소진됨을 나타냅니다. -
%sys(12%): 과도한 컨텍스트 전환 및 인터럽트 처리로 인한 상당한 커널 로드를 재정의합니다. -
%idle(0%): 총 리소스 소진을 확인하여 피할 수 없는 패킷이 삭제되고 대기 시간이 늘어납니다.
-
-
Ctrl+C 눌러
mpstat의 연속 출력을 중지합니다.
다음 콘텐츠를 사용하여
/etc/NetworkManager/dispatcher.d/99-net-performanceNetworkManager 디스패처 스크립트를 만듭니다.#!/bin/bash INTERFACE=$1 ACTION=$2 if [ "$INTERFACE" != "enp1s0" ] || [ "$ACTION" != "up" ]; then exit 0 fi LOCAL_IP=$(ip -4 addr show "$INTERFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1) if [ -z "$LOCAL_IP" ]; then echo "No IP address set on $INTERFACE." exit 1 fi ethtool -K "$INTERFACE" ntuple-filters on IFI=$(cat /sys/class/net/"$INTERFACE"/ifindex) # Identify the first available RX queue ID TARGET_QUEUE=$(ynl --family netdev --dump queue-get --json "{\"ifindex\": $IFI}" | sed "s/'/\"/g" | jq -r '[.[] | select(.type=="rx" and ."napi-id"!=null) | .id] | sort | .[0]') if [ "$TARGET_QUEUE" != "null" ] && [ -n "$TARGET_QUEUE" ]; then NAPI_ID=$(ynl --family netdev --dump queue-get --json "{\"ifindex\": $IFI}" | sed "s/'/\"/g" | jq -r '.[] | select(.id == '$TARGET_QUEUE' and .type == "rx") | ."napi-id"') # Set the paired NAPI instance to threaded busy-poll ynl --family netdev --do napi-set --json "{\"id\": $NAPI_ID, \"threaded\": \"busy-poll\"}" # Set flow steering rule: Redirect traffic to port 443 on $LOCAL_IP into the high-performance queue ethtool -N "$INTERFACE" flow-type tcp4 dst-ip "$LOCAL_IP" dst-port 443 action "$TARGET_QUEUE" echo "Performance setup for $INTERFACE complete: Port 443 directed to queue $TARGET_QUEUE" else echo "No NAPI queue for $INTERFACE found." fi exit 0인터페이스가 활성화되면 NetworkManager는 이 스크립트를 실행합니다. 인터페이스 이름이
enp1s0과 일치하는 경우 스크립트는 인터페이스에 구성된 첫 번째 IPv4 주소로 전송된 HTTPS 트래픽에 대한 스레드 NAPI 사용량 폴링을 활성화합니다.디스패처 스크립트를 실행 가능하게 만듭니다.
# chmod 755 /etc/NetworkManager/dispatcher.d/99-net-performanceenp1s0인터페이스를 사용하는 연결 프로필을 다시 활성화합니다.# nmcli connection up <profile_name>
검증
enp1s0인터페이스의 모든 NAPI 인스턴스와 현재 폴링 상태를 나열합니다.# ynl --family netdev --dump napi-get --json "{\"ifindex\": $(cat /sys/class/net/enp1s0/ifindex)}" | sed "s/'/\"/g" | jq -r '.[] | "ID \(.id): \(.threaded)"'ID 8645: busy-poll ID 8644: busy-poll ...enp1s0인터페이스의 네트워크 흐름 규칙을 표시합니다.# ethtool -n enp1s063 RX rings available Total 1 rules Filter: 1022 Rule Type: TCP over IPv4 Src IP addr: 0.0.0.0 mask: 255.255.255.255 Dest IP addr: 192.0.2.1 mask: 0.0.0.0 TOS: 0x0 mask: 0xff Src port: 0 mask: 0xffff Dest port: 443 mask: 0x0 Action: Direct to queue 0mpstat유틸리티를 사용하여 softirqs를 모니터링합니다.# mpstat -P ALL 110:32:09 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 10:32:09 all 12,50 0,00 5,25 0,10 0,25 0,40 0,00 0,00 0,00 1,50 10:32:09 0 2,00 0,00 97,50 0,00 0,10 0,40 0,00 0,00 0,00 0,00 10:32:09 1 10,00 0,00 1,00 0,00 0,00 0,50 0,00 0,00 0,00 88,50 ...이제
%soft열에 모든 코어의 값이 낮은 것으로 표시됩니다.그러나 이 코어는 전용 NAPI 스레드를 처리하고 새 데이터를 위해 NIC를 지속적으로 폴링하기 때문에
%sys에서 값이 높습니다.-
Ctrl+C 눌러
mpstat의 연속 출력을 중지합니다.