tcpdump는 UDP 성능을 향상시킵니다.

tcpdump는 UDP 성능을 향상시킵니다.

다음 설정의 성능을 확인하기 위해 일련의 부하 테스트를 실행하고 있습니다.

Node.js test suite (client) --> StatsD (server) --> Graphite (server)

즉, node.js 테스트 스위트는 x초마다 설정된 양의 메트릭을 다른 서버에 있는 StatsD 인스턴스로 보냅니다. 그런 다음 StatsD는 매초마다 동일한 서버에 있는 Graphite 인스턴스로 지표를 플러시합니다. 그런 다음 테스트 모음과 Graphite 간의 패킷 손실을 확인하기 위해 테스트 모음에서 실제로 보낸 메트릭 수와 Graphite에서 수신한 메트릭 수를 살펴봅니다.

그러나 나는 때때로 20-50% 범위의 매우 큰 패킷 삭제율(UDP 프로토콜을 사용하여 전송된다는 점에 유의)을 발견했습니다. 그래서 그때부터 이러한 패킷이 삭제되는 위치를 조사하기 시작했고 StatsD의 성능 문제일 수 있다고 판단했습니다. 그래서 저는 이러한 하락이 발생한 위치를 추적하기 위해 시스템의 모든 부분에서 측정항목을 기록하기 시작했습니다. 그리고 이것이 상황이 이상해지는 곳입니다.

나는 사용하고있다tcpdump테스트 실행이 완료된 후 검사할 캡처 파일을 생성합니다. 그러나 tcpdump를 실행하여 테스트를 실행할 때마다 패킷 손실은 거의 존재하지 않습니다! tcpdump가 어떻게든 내 테스트 성능을 향상시키는 것 같은데 왜 그리고 어떻게 이런 일이 일어나는지 알 수 없습니다. 서버와 클라이언트 모두에서 tcpdump 메시지를 기록하기 위해 다음 명령을 실행하고 있습니다.

tcpdump -i any -n port 8125 -w test.cap

한 특정 테스트 사례에서는 40000 메트릭/초를 보냅니다. tcpdump를 실행하는 동안의 테스트에서는 약 4%의 패킷 손실이 발생한 반면, 실행되지 않은 테스트에서는 약 20%의 패킷 손실이 있었습니다.

두 시스템 모두 다음 설정을 사용하여 Xen VM으로 실행됩니다.

  • 인텔 제온 E5-2630 v2 @ 2.60GHz
  • 2GB RAM
  • 우분투 14.04 x86_64

잠재적인 원인을 이미 확인한 사항:

  • UDP 버퍼 수신/전송 크기를 늘립니다.
  • 테스트에 영향을 미치는 CPU 부하입니다. (클라이언트 측과 서버 측 모두 최대 부하 40-50%)
  • 'any' 대신 특정 인터페이스에서 tcpdump를 실행합니다.
  • 무차별 모드를 비활성화하려면 '-p'를 사용하여 tcpdump를 실행합니다.
  • 서버에서만 tcpdump를 실행합니다. 이로 인해 20%의 패킷 손실이 발생했으며 테스트에는 영향을 미치지 않는 것으로 보입니다.
  • 클라이언트에서만 tcpdump를 실행합니다. 이로 인해 성능이 향상되었습니다.
  • netdev_max_backlog 및 netdev_budget을 2^32-1로 늘립니다. 이것은 아무런 차이가 없었습니다.
  • 모든 NIC에서 무차별 모드의 가능한 모든 설정을 시도했습니다(서버 켜짐 및 클라이언트 꺼짐, 서버 꺼짐 및 클라이언트 켜짐, 둘 다 켜짐, 둘 다 꺼짐). 이것은 아무런 차이가 없었습니다.

답변1

tcpdump가 실행 중일 때 수신 프레임을 읽을 때 상당히 프롬프트됩니다. 내 가설은 NIC의 패킷 링 버퍼 설정이 약간 작은 크기일 수 있다는 것입니다. tcpdump가 실행 중일 때 더 적시에 비워집니다.

Red Hat 구독자라면 이 지원 문서가 매우 유용합니다.패킷 수신 개요. 거기에는 당신이 아직 고려하지 않은 것 같은 것들이 있습니다.

시스템이 IRQ를 어떻게 처리하는지 고려하십시오. 네트워크 인터페이스의 'dev_weight'를 늘리는 것을 고려하십시오(NIC에서 사용자 공간으로 더 많은 패킷을 읽는다는 의미). 애플리케이션이 소켓을 얼마나 자주 읽는지 확인합니다(전용 스레드를 사용할 수 있는지, 확장성과 관련된 알려진 문제/해결 방법이 있는지).

NIC 프레임 버퍼를 늘립니다( ethtool명령 사용 - 기타 인수 확인 --set-ring).

'수신측 스케일링'을 살펴보고 최소한 그만큼의 수신 스레드를 사용하여 트래픽을 읽으십시오.

tcpdump가 커널 지원을 사용하는 등 멋진 일을 하고 있는지 궁금합니다.패킷 링 버퍼. 이는 당신이 보고 있는 행동을 설명하는 데 도움이 될 것입니다.

답변2

어떤 전력 거버너를 사용하고 있습니까? "ondemand" 또는 "보수적" 주지사에게서 비슷한 행동을 본 적이 있습니다.

"성능" 조정기를 사용하고 서버 BIOS에서 절전 기능을 비활성화해 보십시오.

뭔가 바뀌나요?

답변3

또 다른 방법은 ip_conntarck모듈입니다. 당신의 리눅스 박스가 새로운 연결을 받아들일 수 있다고 확신합니까? 테스트 방법:

root@debian:/home/mohsen# sysctl net.ipv4.netfilter.ip_conntrack_max
net.ipv4.netfilter.ip_conntrack_max = 65536
root@debian:/home/mohsen# sysctl  net.ipv4.netfilter.ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 29

당신은 테스트해야

net.ipv4.netfilter.ip_conntrack_max >  net.ipv4.netfilter.ip_conntrack_count

max == count 이면 최대 연결이 가득 차서 Linux-box가 새 연결을 허용할 수 없습니다.
ip_conntrack이 없으면 다음을 통해 쉽게 로드할 수 있습니다.modprobe ip_conntrack

답변4

나는 수신 측이 단순히 패킷 속도를 처리할 능력이 없다고 생각하며 그 이유는 다음과 같습니다.

  1. tcpdump 사용클라이언트에서삭제된 패킷을 줄입니다. tcpdump로 인해 클라이언트 속도가 느려지므로 서버는 여전히 부분적으로 처리할 수 있는 훨씬 낮은 패커 속도를 보고 있습니다. 클라이언트와 서버 모두에서 RX/TX 패킷 카운터를 확인하여 이 가설을 확인할 수 있어야 합니다.

  2. UDP 버퍼 수신/전송 크기를 늘렸다고 말씀하셨는데, 어떻게 하는지 자세히 알려주실 수 있나요? 서버에서 rmem_max를 모두 변경하는 것이 중요합니다.그리고rmem_default, 예: sysctl -w net.core.rmem_max=524287 sysctl -w net.core.wmem_max=524287 sysctl -w net.core.rmem_default=524287 sysctl -w net.core.wmem_default=524287

설정 테스트

statsd 및 노드 애플리케이션을 중지한 다음 시스템을 유휴 상태로 사용합니다.아이퍼프네트워크/커널이 처리할 수 있는 패킷 속도를 테스트합니다. iperf로 초당 40K 패킷을 스트리밍할 수 있지만 statsd로는 스트리밍할 수 없다면 statsd 조정에 노력을 집중해야 합니다.

기타 튜너블

튜닝하는 것도 잊지 마세요net.core.netdev_max_backlog: 특정 인터페이스가 커널이 처리할 수 있는 것보다 더 빠르게 패킷을 수신할 때 대기열에 허용되는 최대 패킷 수입니다.

관련 정보