Windows TCP Window Scaling 고원을 너무 일찍 치다


50

시나리오 : 다수의 Windows 클라이언트가 정기적으로 대용량 파일 (FTP / SVN / HTTP PUT / SCP)을 ~ 100-160ms 떨어진 Linux 서버에 업로드합니다. 사무실에는 1Gbit / s 동기 대역폭이 있으며 서버는 AWS 인스턴스이거나 미국 DC에서 물리적으로 호스팅됩니다.

초기 보고서는 새 서버 인스턴스에 업로드 할 때보 다 훨씬 느리다는 것이 었습니다. 이것은 테스트와 여러 위치에서 나왔습니다. 클라이언트는 Windows 시스템에서 호스트에 대해 2-5Mbit / s의 안정성을 보였습니다.

나는 발발 iperf -sAWS 인스턴스에서 다음에서 윈도우 사무실에서 클라이언트 :

iperf -c 1.2.3.4

[  5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55185
[  5]  0.0-10.0 sec  6.55 MBytes  5.48 Mbits/sec

iperf -w1M -c 1.2.3.4

[  4] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55239
[  4]  0.0-18.3 sec   196 MBytes  89.6 Mbits/sec

후자의 수치는 후속 테스트 (AWS의 편차)에 따라 크게 다를 수 있지만 일반적으로 70 ~ 130Mbit / s이며 이는 우리의 요구에 충분합니다. 세션을 Wiresharking하면 다음을 볼 수 있습니다.

  • iperf -c Windows SYN-Window 64kb, 스케일 1-Linux SYN, ACK : Window 14kb, 스케일 : 9 (* 512) 기본 64kb 창으로 iperf 창 크기 조정
  • iperf -c -w1M Windows SYN-Windows 64kb, 스케일 1-Linux SYN, ACK : 창 14kb, 스케일 : 9 기본 1MB 창으로 iperf 창 크기 조정

분명히 링크는 이러한 높은 처리량을 유지할 수 있지만, 실제로 사용하려면 창 크기를 명시 적으로 설정해야합니다. TCP 핸드 셰이크는 각 경우에 동일한 시작점을 사용하지만 강제 확장은

반대로, 동일한 네트워크의 Linux 클라이언트에서 iperf -c(시스템 기본값 85kb를 사용하여) 직선을 제공합니다.

[  5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 33263
[  5]  0.0-10.8 sec   142 MBytes   110 Mbits/sec

강제하지 않으면 예상대로 확장됩니다. 이것은 개입하는 홉이나 로컬 스위치 / 라우터에있을 수 없으며 Windows 7 및 8 클라이언트에 모두 영향을 미치는 것으로 보입니다. 자동 조정에 대한 많은 가이드를 읽었지만 일반적으로 나쁜 끔찍한 홈 네트워킹 키트를 해결하기 위해 확장을 비활성화하는 방법에 관한 것입니다.

아무도 여기서 무슨 일이 일어나고 있는지 말해 줄 수 있습니까? (GPO를 통해 레지스트리에 붙일 수있는 것이 바람직합니다.)

노트

문제의 AWS Linux 인스턴스에는 다음과 같은 커널 설정이 적용됩니다 sysctl.conf.

net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
net.ipv4.tcp_rmem = 4096 1048576 16777216
net.ipv4.tcp_wmem = 4096 1048576 16777216

서버 끝에서 dd if=/dev/zero | nc리디렉션을 사용 하여 가능한 다른 병목 현상 /dev/null을 배제 iperf하고 제거했지만 결과는 거의 동일합니다. 와 테스트 ncftp(Cygwin에서 네이티브 윈도우, 리눅스)는 각각의 플랫폼에서 위의 iperf 테스트만큼 같은 방식으로 확장 할 수 있습니다.

편집하다

여기에서 관련성이있는 또 다른 일관된 것을 발견했습니다. 여기에 이미지 설명을 입력하십시오

확대 된 1MB 캡처의 첫 번째 초입니다. 창이 확대되고 버퍼가 커짐에 따라 Slow Start 가 작동하는 것을 볼 수 있습니다 . ~ 0.2 초의이 작은 고원 다음있다 정확히 기본 창 iperf 테스트 영원히 평평 시점에서이. 이것은 물론 더 어지러운 높이로 확장되지만 스케일링 에서이 일시 중지 (값은 1022 바이트 * 512 = 523264)가 있기 전에 궁금합니다.

업데이트-6 월 30 일

다양한 응답에 대한 후속 조치 :

  • CTCP 활성화-차이가 없습니다. 창 스케일링이 동일합니다. (이 내용을 올바르게 이해하면이 설정으로 인해 정체 창이 확대 될 수있는 최대 크기가 아닌 확대 비율이 증가합니다)
  • TCP 타임 스탬프 활성화 -여기도 바뀌지 않았습니다.
  • Nagle의 알고리즘-이것은 의미가 있으며 적어도 문제의 표시로 그래프의 특정 얼룩을 무시할 수 있음을 의미합니다.
  • pcap 파일 : 여기에서 사용할 수있는 Zip 파일 : https://www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip (bittwiste와 익명으로, ~ 150MB로 추출) 비교를 위해 각 OS 클라이언트에서 하나씩)

업데이트 2-6 월 30 일

Kyle의 제안에 따라 ctcp를 활성화하고 굴뚝 오프로드를 비활성화했습니다 : TCP Global Parameters

----------------------------------------------
Receive-Side Scaling State          : enabled
Chimney Offload State               : disabled
NetDMA State                        : enabled
Direct Cache Acess (DCA)            : disabled
Receive Window Auto-Tuning Level    : normal
Add-On Congestion Control Provider  : ctcp
ECN Capability                      : disabled
RFC 1323 Timestamps                 : enabled
Initial RTO                         : 3000
Non Sack Rtt Resiliency             : disabled

그러나 슬프게도 처리량에는 변화가 없습니다.

그래도 여기에 원인 / 결과 질문이 있습니다. 그래프는 클라이언트의 서버 ACK에 설정된 RWIN 값입니다. Windows 클라이언트의 경우 클라이언트의 제한된 CWIN으로 인해 버퍼가 채워지지 않기 때문에 Linux 가이 값을 저점 이상으로 확장하지 않는다고 생각하고 있습니까? 리눅스가 인위적으로 RWIN을 제한하는 다른 이유가있을 수 있습니까?

참고 : 나는 그것을 위해 ECN을 켜려고 노력했다. 그러나 변화는 없습니다.

업데이트 3-6 월 31 일

휴리스틱 및 RWIN 자동 튜닝 비활성화 후 변경 사항이 없습니다. 장치 관리자 탭을 통해 기능 왜곡을 일으키는 소프트웨어를 사용하여 인텔 네트워크 드라이버를 최신 (12.10.28.0)으로 업데이트했습니다. 이 카드는 82579V 칩셋 온보드 NIC입니다. (realtek 또는 다른 공급 업체의 클라이언트에서 더 많은 테스트를 수행 할 것입니다)

잠시 NIC에 집중하면서 다음을 시도했습니다 (거의 범인을 배제 할 것입니다).

  • 수신 버퍼를 256에서 2k로, 전송 버퍼를 512에서 2k로 증가 (모두 최대)-변경 없음
  • 모든 IP / TCP / UDP 체크섬 오프로드를 비활성화했습니다. - 변경 없음.
  • 비활성화 된 대용량 전송 오프로드-Nada.
  • IPv6, QoS 스케줄링 끄기-Nowt.

업데이트 3-7 월 3 일

Linux 서버 측을 제거하기 위해 Server 2012R2 인스턴스를 시작하고 iperf(cygwin binary) 및 NTttcp를 사용하여 테스트를 반복했습니다 .

으로 iperf, 나는 명시 적으로 지정했습니다 -w1m모두 연결이 ~ 5Mbit / s의 이상으로 확장 할 전에 측면. (실수로, 91ms의 대기 시간에서 ~ 5Mbits의 BDP는 거의 정확히 64kb입니다. 한계를 발견하십시오 ...)

ntttcp 바이너리는 이제 그러한 제한을 보여주었습니다. ntttcpr -m 1,0,1.2.3.5서버와 ntttcp -s -m 1,0,1.2.3.5 -t 10클라이언트에서 사용하면 처리량이 훨씬 더 좋습니다.

Copyright Version 5.28
Network activity progressing...


Thread  Time(s) Throughput(KB/s) Avg B / Compl
======  ======= ================ =============
     0    9.990         8155.355     65536.000

#####  Totals:  #####

   Bytes(MEG)    realtime(s) Avg Frame Size Throughput(MB/s)
================ =========== ============== ================
       79.562500      10.001       1442.556            7.955

Throughput(Buffers/s) Cycles/Byte       Buffers
===================== =========== =============
              127.287     308.256      1273.000

DPCs(count/s) Pkts(num/DPC)   Intr(count/s) Pkts(num/intr)
============= ============= =============== ==============
     1868.713         0.785        9336.366          0.157

Packets Sent Packets Received Retransmits Errors Avg. CPU %
============ ================ =========== ====== ==========
       57833            14664           0      0      9.476

8MB / s는 명시 적으로 큰 창을 사용하여 얻은 수준으로 설정 iperf합니다. 이상하게도 1273 버퍼의 80MB = 64kB 버퍼입니다. 추가 wireshark는 클라이언트가 충족하는 것처럼 보이는 가변 가변 RWIN이 서버에서 나오는 것을 보여줍니다 (Scale factor 256). 아마도 ntttcp가 전송 창을 잘못보고 있습니다.

업데이트 4-7 월 3 일

@ karyhead의 요청에 따라, 좀 더 많은 테스트를 수행하고 여기에 몇 가지 더 캡처를 생성했습니다 https://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip

  • iperfWindows에서 이전과 동일한 Linux 서버 (1.2.3.4)까지 두 개 더 : 하나는 128k 소켓 크기 및 기본 64k 창 (다시 ~ 5Mbit / s로 제한)과 1MB 전송 창 및 기본 8kb 소켓 크기. (더 큰 스케일)
  • ntttcp동일한 Windows 클라이언트에서 Server 2012R2 EC2 인스턴스 (1.2.3.5)까지 하나의 추적. 여기서 처리량은 잘 확장됩니다. 참고 : NTttcp는 포트 6001에서 테스트 연결을 열기 전에 이상한 일을합니다. 무슨 일이 일어나고 있는지 잘 모르겠습니다.
  • 하나의 FTP 데이터 추적으로 /dev/urandomCygwin을 사용하여 거의 동일한 Linux 호스트 (1.2.3.6)에 20MB를 업로드 ncftp합니다. 다시 한계가 있습니다. 패턴은 Windows Filezilla를 사용하는 것과 거의 동일합니다.

iperf버퍼 길이를 변경하면 시간 시퀀스 그래프 (훨씬 더 많은 수직 섹션)와 예상되는 차이가 발생하지만 실제 처리량은 변경되지 않습니다.


11
문서에 분명하지 않은 잘 연구 된 문제의 드문 예입니다. 니스-누군가 해결책을 찾길 바랍니다 (어쨌든 저도 그것을 사용할 수 있다고 생각하기 때문에).
TomTom

2
RFC 1323 타임 스탬프는 Windows에서 기본적으로 비활성화되어 있고 Linux에서는 기본적으로 활성화되어 있으므로 RFC 1323 타임 스탬프를 켜보십시오. netsh int tcp set global timestamps=enabled
Brian

3
200ms 지연은 아마도 Nagle 알고리즘 일 것입니다. 특정 연결에서 TCP가 데이터를 수신하면 다음 조건 중 하나에 해당하는 경우에만 승인을 다시 보냅니다. 수신 한 이전 세그먼트에 대한 승인이 전송되지 않았습니다. 세그먼트가 수신되었지만 해당 연결에 대해 200 밀리 초 내에 다른 세그먼트가 도착하지 않습니다.
Greg Askew

2
느린 발신자 중 한 곳에서 패킷 캡처를 수행 할 수 있습니까?
Kyle Brandt

이 테스트 결과와 대표 캡처 파일에 대한 링크로 OP를 업데이트했습니다.
SmallClanger

답변:


15

Windows 7/8 클라이언트에서 CTCP (Composite TCP) 를 사용하려고 했습니까?

읽어주세요:

높은 BDP 전송을위한 발신자 측 성능 향상

http://technet.microsoft.com/en-us/magazine/2007.01.cableguy.aspx

...

이 알고리즘은 소규모 BDP 및 소규모 수신 창 크기에 적합합니다. 그러나 100ms 왕복 시간 으로 고속 WAN 링크를 통해 위치한 두 서버 간의 데이터 복제와 같이 수신 창 크기가 크고 BDP 가 큰 TCP 연결이있는 경우 이러한 알고리즘 은 송신 창을 늘리지 않습니다. 연결 대역폭을 충분히 활용할 수있을만큼 빠릅니다 .

이러한 상황에서 TCP 연결의 대역폭을 더 잘 활용하기 위해 차세대 TCP / IP 스택에는 복합 TCP (CTCP)가 포함됩니다. CTCP는 수신 창 크기가 크고 BDP가 큰 연결의 경우 송신 창을보다 적극적으로 증가시킵니다 . CTCP는 지연 변동 및 손실을 모니터링하여 이러한 유형의 연결에서 처리량을 최대화하려고합니다. 또한 CTCP는 해당 동작이 다른 TCP 연결에 부정적인 영향을 미치지 않도록합니다.

...

CTCP는 Windows Server 2008을 실행하는 컴퓨터에서 기본적으로 사용되며 Windows Vista를 실행하는 컴퓨터에서는 기본적으로 사용되지 않습니다. netsh interface tcp set global congestionprovider=ctcp명령을 사용하여 CTCP를 활성화 할 수 있습니다 . netsh interface tcp set global congestionprovider=none명령을 사용하여 CTCP를 비활성화 할 수 있습니다 .

2014 년 6 월 30 일 편집

CTCP가 실제로 "켜져 있는지"확인

> netsh int tcp show global

여기에 이미지 설명을 입력하십시오

PO는 말했다 :

이것을 올바르게 이해하면이 설정으로 인해 정체 창이 확대 될 수 있는 최대 크기가 아닌 확대 비율이 증가합니다.

CTCP는 적극적으로 전송 창을 증가시킵니다

http://technet.microsoft.com/en-us/library/bb878127.aspx

복합 TCP

송신 TCP 피어가 네트워크를 압도하는 것을 방지하는 기존 알고리즘을 느린 시작 및 혼잡 방지라고합니다. 이 알고리즘은 연결에서 데이터를 처음 전송할 때와 손실 된 세그먼트에서 복구 할 때 발신자가 전송할 수있는 세그먼트의 양을 전송 창이라고합니다. 느리게 시작하면 수신 된 각 승인 세그먼트 (Windows XP 및 Windows Server 2003의 TCP의 경우) 또는 승인 된 각 세그먼트 (Windows Vista 및 Windows Server 2008의 TCP의 경우)마다 하나의 전체 TCP 세그먼트만큼 전송 창이 증가합니다. 정체 방지는 승인 된 각 데이터 창마다 하나의 전체 TCP 세그먼트만큼 전송 창을 증가시킵니다.

이 알고리즘은 LAN 미디어 속도 및 더 작은 TCP 창 크기에 적합합니다. 그러나 100ms 왕복으로 고속 WAN 링크를 통해 위치한 두 서버간에 데이터 복제와 같이 수신 창 크기가 크고 대역폭 지연 제품 (고 대역폭 및 고지연)이 큰 TCP 연결이있는 경우 시간이 지나면 이러한 알고리즘은 연결 대역폭을 완전히 활용할 수있을 정도로 전송 창을 빠르게 늘리지 않습니다. 예를 들어, 100ms RTT (round trip time)의 1Gbps WAN 링크 에서, 송신 창이 처음 에 수신자가 알리는 큰 창 크기로 증가하는 데 최대 1 시간이 소요될 있습니다. 손실 된 세그먼트가 있을 때 복구 합니다.

이러한 상황에서 TCP 연결 의 대역폭을 더 잘 활용하기 위해 차세대 TCP / IP 스택에는 복합 TCP (CTCP)가 포함됩니다. CTCP는 수신 창 크기가 크고 대역폭 지연 제품이 큰 연결의 경우 송신 창을보다 적극적으로 증가시킵니다. CTCP는 지연 변동 및 손실모니터링 하여 이러한 유형의 연결에서 처리량을 최대화하려고합니다 . 또한 CTCP는 해당 동작이 다른 TCP 연결에 부정적인 영향을 미치지 않도록합니다.

Microsoft 내부에서 수행 한 테스트에서 50ms RTT를 사용하는 1Gbps 연결의 경우 큰 파일 백업 시간이 거의 절반으로 줄었습니다. 더 큰 대역폭 지연 제품과의 연결은 더 나은 성능을 가질 수 있습니다. CTCP와 수신 창 자동 조정은 링크 사용률을 높이기 위해 함께 작동하며 큰 대역폭 지연 제품 연결에서 상당한 성능 향상을 가져올 수 있습니다.


3
이 답변을 보완하는 것처럼 Server 2012 / Win8.1의 Powershell Set-NetTCPSetting에는 -CongestionProviderCCTP, DCTCP 및 Default를 허용 하는 매개 변수가 있습니다. Windows 클라이언트와 서버는 서로 다른 기본 정체 공급자를 사용합니다. technet.microsoft.com/ko-kr/library/hh826132.aspx
Ryan은

당신이 무엇을 얻고 있는지 알지만 적용되지 않는 것 같습니다. 이를 위해 30 분 동안 실행 iperf했지만 창은 여전히 ​​~ 520kb를 초과하지 않았습니다. 이 공격적인 알고리즘이 이점을 보여주기 전에 CWND를 제한하는 것이 있습니다.
SmallClanger

HTML이 아닌 프로토콜을 전송할 때 이런 종류의 문제를 나타내는 오래된 (이미 수정 된) Vista 버그가 있습니다. HTML로 동일한 파일을 전송하거나 FTP로 말할 때 문제가 정확히 동일합니까?
Pat

@Pat-그렇습니다. HTTP 및 HTTPS를 통한 SVN 커밋 및 AWS의 다른 시스템으로의 FTP 전송도 동일한 제한을 나타냅니다.
SmallClanger

윈 클라이언트의 방화벽은 어떻습니까? 방화벽을 완전히 끈 상태에서 테스트 할 수 있습니까? 여기를보십시오 : ask.wireshark.org/questions/2365/tcp-window-size-and-scaling
Pat

12

문제를 명확하게 :

TCP에는 두 개의 창이 있습니다.

  • 수신 창 : 버퍼에 남은 바이트 수. 이것은 수신기에 의해 부과 된 흐름 제어입니다. TCP 헤더 내부의 창 크기와 창 크기 조정 요소로 구성되어 있기 때문에 wireshark에서 수신 창의 크기를 볼 수 있습니다. TCP 연결의 양쪽은 수신 창을 알리지 만 일반적으로 중요한 것은 대량의 데이터를 수신하는 것입니다. 귀하의 경우 클라이언트가 서버에 업로드하고 있기 때문에 "서버"입니다
  • 혼잡 창 이것은 발신자가 부과 한 흐름 제어입니다. 이것은 운영 체제에서 유지 보수되며 TCP 헤더에 표시되지 않습니다. 데이터 전송 속도를 제어합니다.

제공 한 캡처 파일에서. 수신 버퍼가 넘치지 않는 것을 볼 수 있습니다.

여기에 이미지 설명을 입력하십시오

내 분석은 송신 윈도우 (혼잡 제어 윈도우라고도 함)가 수신기의 RWIN을 만족시키기에 충분히 열리지 않기 때문에 발신자가 충분히 빨리 송신하지 않는 것입니다. 간단히 말해 수신자는 "Give me More"라고 말하고 Windows가 발신자 인 경우 충분히 빨리 보내지 않습니다.

이것은 위의 그래프에서 RWIN이 열린 상태로 유지되며 왕복 시간이 .09 초이고 RWIN이 ~ 500,000 바이트 인 경우 대역폭 지연 제품에 따라 최대 처리량은 (500000) /0.09) * 8 = ~ 42 Mbit / s (리눅스 캡처에서 승리 할 때 ~ 5 정도 밖에되지 않습니다).

수정하는 방법?

모르겠어요 interface tcp set global congestionprovider=ctcp전송 창 (정체 창에 대한 또 다른 용어)을 늘리기 때문에 나에게해야 할 일처럼 들립니다. 당신은 그것이 작동하지 않는다고 말했다. 따라서 확인하십시오.

  1. 이 기능을 활성화 한 후 재부팅 했습니까?
  2. 굴뚝 오프로드가 켜져 있습니까? 테스트중인 경우 사용 중지 해보십시오. 이것이 활성화 될 때 정확히 오프로드되는 것이 무엇인지 모르겠지만, 보내기 창을 제어하는 ​​것이 그 중 하나라면, 이것이 활성화 될 때 혼잡 공급자가 아무런 영향을 미치지 않을 수도 있습니다 ... 추측하고 있습니다 ...
  3. 또한 이것이 Windows 7 이전이라고 생각하지만 HKEY_LOCAL_MACHINE-System-CurrentControlSet-Services-AFD-Parameters에서 DefaultSendWindow 및 DefaultReceiveWindow라는 두 레지스트리 키를 추가하여 재생 해 볼 수 있습니다. 이것들조차도 효과가 있다면 아마도 ctcp가 꺼져있을 것입니다.
  4. 또 다른 추측은를 확인하십시오 netsh interface tcp show heuristics. 나는 그것이 RWIN 일 수 있다고 생각하지만, 그렇지 않다. 그래서 보내기 창에 영향을 줄 수있는 경우 비활성화 / 활성화로 재생할 수 있습니다.
  5. 또한 테스트 클라이언트에서 드라이버가 최신인지 확인하십시오. 어쩌면 뭔가가 깨졌을 수도 있습니다.

네트워크 드라이버가 일을 다시 작성 / 수정 할 가능성을 제거하기 위해 오프로드 기능을 모두 사용하지 않고 이러한 모든 실험을 시도합니다 (오프로드가 비활성화 된 상태에서 CPU를 유지하십시오). TCP_OFFLOAD_STATE_DELEGATED 구조체는 적어도하여 CWnd 오프 로딩이 적어도 가능하다는 것을 암시하는 것 같다.


2
답변이 아니기 때문에 "답변"을보고했습니다. 나는 즉시 투표권을 얻었습니다. 지금 나는 "사람들"이 당신의 "답변없는"투표를하는 방법을 본다 ... 정말 재밌다
Pat

1
@Pat : 투표 번호를 클릭해도 공감 / 비공식의 내역을 볼 수 있습니다. 현재 귀하는 귀하의 답변에 대한 투표를하지 않았습니다. 내 대답은 그의 문제를 해결하지 못했지만 (아직 대답은 없습니다) 문제를 설명하고 현지화합니다 (정확하게 올바르게!). 이는 문제 해결의 중요한 단계입니다.
Kyle Brandt

@ Kyle Brandt 당신이 당신을 받아들이면 대답이 아닙니다. 왜 그것이 추가 고려없이 "자동적으로"제거되지 않는지 궁금합니다 ?? 그리고 당신은 틀 렸습니다. 귀하의 "답변"을보고 한대로 "투표권"(비 공감)을 받았습니다. 아직 제거되지 않았습니다. 여기에서 "특별한"규칙에 따라 연주하는 것 같습니다.
Pat

1
@Pat 도움이된다면 Kyle의 답변이 매우 도움이되었습니다. 이제 어떤 버퍼가 제한되는지에 대한 명확한 아이디어를 얻었으며 결과적으로 적절한 솔루션에 조금 더 가깝습니다. 때때로 이와 같은 질문은 약간의 신중한 편집으로 적절한 Q 및 적절한 A 가 될 수있는 공동 노력이 될 수 있습니다 .
SmallClanger

@SmallClanger는 모든 것을 존중하며 Kyle Brandt를 포함한 모든 사용자가 따라야하는 일련의 규칙을 가지고 있습니다. 그의 답변이 아닌 경우 "편집자"클럽에 친구가 몇 명 있더라도 삭제하거나 댓글로 이동해야합니다.
Pat

5

@Pat과 @Kyle의 훌륭한 정보가 있습니다. TCP 수신 및 전송 창에 대한 @Kyle의 설명 에 확실히주의를 기울이십시오 . 나는 그 주위에 혼란이 있다고 생각합니다. 문제를 더 혼동하기 위해 iperf는 "TCP 창" -w이라는 용어를 수신, 전송 또는 전체 슬라이딩 창과 관련하여 모호한 용어 인 설정과 함께 사용합니다. 실제로 수행하는 것은 -c(클라이언트) 인스턴스 의 소켓 송신 버퍼 와 -s(서버) 인스턴스 의 소켓 수신 버퍼를 설정하는 것 입니다. 에서 src/tcp_window_size.c:

if ( !inSend ) {
    /* receive buffer -- set
     * note: results are verified after connect() or listen(),
     * since some OS's don't show the corrected value until then. */
    newTCPWin = inTCPWin;
    rc = setsockopt( inSock, SOL_SOCKET, SO_RCVBUF,
                     (char*) &newTCPWin, sizeof( newTCPWin ));
} else {
    /* send buffer -- set
     * note: results are verified after connect() or listen(),
     * since some OS's don't show the corrected value until then. */
    newTCPWin = inTCPWin;
    rc = setsockopt( inSock, SOL_SOCKET, SO_SNDBUF,
                     (char*) &newTCPWin, sizeof( newTCPWin ));
}

Kyle이 언급했듯이 Linux 상자의 수신 창에 문제가 없지만 발신자가 전송 창을 충분히 열지 못합니다. 그것은 충분히 빨리 열리지 않는 것이 아니라 단지 64k로 제한됩니다.

Windows 7의 기본 소켓 버퍼 크기는 64k입니다. MSDN의 처리량과 관련된 소켓 버퍼 크기에 대한 설명서는 다음과 같습니다.

Windows 소켓을 사용하여 TCP 연결을 통해 데이터를 전송할 때 최고의 처리량을 달성하려면 TCP에서 충분한 양의 데이터를 처리해야합니다 (전송되었지만 아직 확인되지 않은 상태). TCP 연결을위한 최상의 처리량을 달성하기 위해 뛰어난 데이터 양에 대한 이상적인 값을 이상적인 전송 백 로그 (ISB) 크기라고합니다. ISB 값은 TCP 연결의 대역폭 지연 곱과 수신자의 보급 된 수신 창 (및 일부 네트워크 혼잡 량)의 기능입니다.

좋아, blah blah blah, 이제 우리는 간다 :

한 번에 하나의 차단 또는 비 차단 전송 요청을 수행하는 응용 프로그램은 일반적으로 적절한 처리량을 달성하기 위해 Winsock의 내부 전송 버퍼링에 의존합니다. 주어진 연결에 대한 전송 버퍼 한계는 SO_SNDBUF 소켓 옵션에 의해 제어됩니다. 블로킹 및 비 블로킹 전송 방법의 경우 전송 버퍼 제한은 TCP에서 미해결 상태로 유지되는 데이터의 양을 결정합니다 . 연결의 ISB 값이 전송 버퍼 제한보다 크면 연결에서 처리량이 최적이 아닙니다.

64k 창을 사용한 최신 iperf 테스트의 평균 처리량은 5.8Mbps입니다. Wireshark의 통계> 요약 에서 가져온 것으로 모든 비트를 계산합니다. 아마도 iperf는 TCP 데이터 처리량을 5.7Mbps로 계산하고 있습니다. FTP 테스트에서도 동일한 성능 (5.6Mbps)을 볼 수 있습니다.

64k 전송 버퍼와 91ms RTT의 이론적 처리량은 ... 5.5Mbps입니다. 나를 위해 충분히 가까이

우리가 1MB 윈도우 iperf 테스트를 보면, 입력은 88.2Mbps (TCP 데이터의 경우 86.2Mbps)입니다. 1MB 윈도우의 이론적 입력은 87.9Mbps입니다. 다시 한 번 정부 업무를 위해 충분히 가까워 야합니다.

이것이 보여주는 것은 송신 소켓 버퍼가 송신 창을 직접 제어하고 다른 쪽의 수신 창과 결합하여 처리량을 제어한다는 것입니다. 보급 된 수신 창에는 공간이 있으므로 수신자에 의해 제한되지 않습니다.

이 자동 튜닝 사업은 어떻습니까? Windows 7에서 해당 항목을 자동으로 처리하지 않습니까? 앞에서 언급했듯이 Windows는 수신 창의 자동 확장을 처리하지만 송신 버퍼도 동적으로 처리 할 수 ​​있습니다. MSDN 페이지로 돌아갑니다.

TCP에 대한 동적 전송 버퍼링이 Windows 7 및 Windows Server 2008 R2에 추가되었습니다. 애플리케이션이 스트림 소켓에서 SO_SNDBUF 소켓 옵션을 설정하지 않으면 TCP에 대한 동적 전송 버퍼링이 기본적으로 사용됩니다.

iperf는 옵션을 사용할 SO_SNDBUF때 사용 -w하므로 동적 전송 버퍼링이 비활성화됩니다. 그러나 사용 -w하지 않으면을 사용하지 않습니다 SO_SNDBUF. 동적 전송 버퍼링은 기본적으로 켜져 있지만 다음을 확인할 수 있습니다.

netsh winsock show autotuning

설명서에 다음과 같이 비활성화 할 수 있다고 나와 있습니다.

netsh winsock set autotuning off

그러나 그것은 나를 위해 작동하지 않았습니다. 레지스트리를 변경하고 이것을 0으로 설정해야했습니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters\DynamicSendBufferDisable

이 기능을 비활성화하면 도움이 될 것이라고 생각하지 않습니다. 그것은 단지 참고 일뿐입니다.

수신 창에 충분한 공간이있는 Linux 박스로 데이터를 전송할 때 송신 버퍼가 기본 64k 이상으로 확장되지 않는 이유는 무엇입니까? 좋은 질문입니다. Linux 커널에는 자동 튜닝 TCP 스택도 있습니다. T-Pain과 Kanye가 자동 튜닝 듀엣을 함께 수행하는 것처럼 좋지 않을 수도 있습니다. 아마도 두 개의 자동 튜닝 TCP 스택이 서로 통신하는 데 약간의 문제가있을 수 있습니다.

다른 사람 이 당신과 같은 문제를 겪고 있었고 기본 송신 버퍼 크기를 늘리기 위해 레지스트리 편집으로 문제를 해결할 수있었습니다. 불행히도, 그것은 더 이상 작동하지 않는 것 같습니다. 적어도 그것을 시도했을 때 나에게는 그렇지 않았습니다.

이 시점에서 제한 요소가 Windows 호스트의 전송 버퍼 크기라는 것이 분명하다고 생각합니다. 그것이 동적으로 올바르게 성장하지 않는 것 같다면, 소녀는 무엇을해야합니까?

당신은 할 수 있습니다 :

  • 보내기 버퍼 즉, 윈도우 옵션을 설정할 수있는 응용 프로그램을 사용하십시오.
  • 로컬 Linux 프록시 사용
  • 원격 Windows 프록시를 사용 하시겠습니까?
  • Microsofhahahahahahaha로 사례 열기
  • 맥주

면책 조항 : 나는 이것을 연구하는 데 많은 시간을 보냈으며 그것은 내가 아는 한 google-fu와 정확합니다. 그러나 나는 어머니의 무덤을 맹세하지 않을 것입니다 (그녀는 여전히 살아 있습니다).


환상적인 입력; 감사합니다. iperf 2.0.4를 사용하고 있으며 설정을 실험하고 새 캡으로 OP를 업데이트합니다.
SmallClanger

더 많은 연구와 최근의 테스트를 기반으로 "응답"을 업데이트했습니다
karyhead

감사. 적어도 부분적으로 내가 화를내는 것이 아니라는 것을 아는 것이 좋습니다. XP / 2003에서 이러한 레지스트리 설정을 권장하는 블로그 / 스레드를 읽었지만 Vista / 2008 이전에 작성되었으므로 Vista 이후에는 무시됩니다. 나는 사실 (나에게 행운을 빌어) 이것에 대해 MS에 티켓을 올릴 생각
SmallClanger

1
내가 연구에서 찾은 유용한 도구는 SDK의 tcpanalyzer.exe ( microsoft.com/en-us/download/details.aspx?id=8279 )였습니다. 개별 연결을 선택하고 RTT, cwnd, retransmissions 등과 같은 TCP 통계를 얻을 수있는 그래픽 netstat입니다 .cwnd가 송신 버퍼 크기 이상으로 열릴 수는 있지만 입력이 증가하지 않고 wireshark가 확인되었습니다. 여전히 버퍼 제한 전송입니다.
karyhead

1
7/8에서 알려진대로 "netsh"명령이 작동하지 않고 사람들이 수동으로 해당 레지스트리 항목을 입력하도록 강요하는 몇몇 포럼에 대한 의견을 찾았습니다. CTCP 옵션으로 이런 일이 일어날 수 있는지 궁금합니다.
Pat

4

TCP 스택을 조정 한 후에도 Winsock 계층에 병목 현상이 발생할 수 있습니다. Winsock (레지스트리의 보조 기능 드라이버)을 구성하면 Windows 7에서 업로드 속도 (데이터를 서버에 푸시)에 큰 차이가 있음을 알았습니다. Microsoft는 비 차단 소켓에 대한 TCP 자동 조정의 버그를 인정했습니다. 브라우저가 사용하는 소켓의 종류 ;-)

DefaultSendWindow에 DWORD 키를 추가하고 BDP 이상으로 설정하십시오. 256000을 사용하고 있습니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\AFD\Parameters\DefaultSendWindow

다운로드에 대한 Winsock 설정을 변경하면 도움이 될 수 있습니다. DefaultReceiveWindow에 대한 키를 추가하십시오.

Fiddler 프록시 및 명령을 사용하여 클라이언트 및 서버 소켓 버퍼 크기를 조정 하여 다양한 소켓 레벨 설정을 실험 할 수 있습니다 .

prefs set fiddler.network.sockets.Server_SO_SNDBUF 65536 

fiddler.network.sockets.Client_SO_SNDBUF
fiddler.network.sockets.Client_SO_RCVBUF
fiddler.network.sockets.Server_SO_SNDBUF
fiddler.network.sockets.Server_SO_RCVBUF

훌륭한 추가 정보. 우연히 MS 버그에 대한 참조 링크가 있습니까?
SmallClanger

3

답변의 모든 분석을 읽은 후에이 문제는 Windows 6.1 / WindowsR 6.1을 실행하는 것처럼 들립니다.

Windows 6.1의 네트워킹 스택 (TCP / IP & Winsock)은 엄청나게 결함이 있었으며 Microsoft가 6.1의 최초 릴리스 이후 수년간의 핫픽스를 통해 해결 한 버그와 성능 문제가있었습니다.

이 핫픽스를 적용하는 가장 좋은 방법은 support.microsoft.com의 모든 관련 페이지를 수동으로 확인하고 수동으로 LDR 버전의 네트워크 스택 핫픽스를 요청하고 다운로드하는 것입니다 (수십 가지가 있음).

관련 핫픽스를 찾으려면 다음 검색 쿼리와 함께 www.bing.com을 사용해야합니다. site:support.microsoft.com 6.1.7601 tcpip.sys

또한 Windows 6.1에서 LDR / GDR 핫픽스가 작동하는 방식을 이해해야합니다.

필자는 일반적으로 Windows 6.1에 대한 자체 LDR 수정 목록 (네트워크 스택 수정뿐만 아니라)을 유지 관리 한 다음 이러한 수정 사항을 내가 접한 Windows 6.1 서버 / 클라이언트에 사전에 적용했습니다. 새로운 LDR 핫픽스를 정기적으로 확인하는 것은 시간이 많이 걸리는 작업이었습니다.

운 좋게도 Microsoft는 최신 OS 버전으로 LDR 핫픽스 실행을 중단했으며 이제 Microsoft의 자동 업데이트 서비스를 통해 버그 수정을 사용할 수 있습니다.

업데이트 : Windows7SP1의 많은 네트워크 버그 중 하나-https: //support.microsoft.com/en-us/kb/2675785

업데이트 2 : SYN 패킷의 두 번째 재전송 후 창 크기 조정을 강제하기 위해 netsh 스위치를 추가하는 또 다른 핫픽스가 있습니다 (기본적으로 2 개의 SYN 패킷이 재전송 된 후 창 크기 조정이 비활성화 됨) https://support.microsoft.com/en- us / kb / 2780879


감사합니다 Christoph; 이것에 대한 매우 흥미로운 새로운 의견과 SYN 재전송 '기능'은 매우 이상합니다. 나는 그 뒤에 디자인 목표를 전혀 볼 수 없습니다. (어쩌면 일종의 조잡한 혼잡 감지?). 모든 원래 테스트는 Win7SP1에서 수행되었습니다. 우리는 곧 Win10을 시험 사용할 것입니다.
SmallClanger 2016 년

테스트 할 Windows 10 지점은 무엇입니까? Windows 10의 네트워크 스택에 대한 경험이 없습니다.
Christoph Wegener 2016 년

Enterprise 1511은 우리가 목표로 삼고 있습니다.
SmallClanger

내가 참조. Windows 10이 많은 지점을 결정하기는 매우 어렵습니다. LTSB 지점에 있었기 때문에 특정 기능을 사용할 수없는 Windows 10의 문제가 이미 발생했습니다. 나는 마이크로 소프트가 가능한 전체 지점의 수를 감소하고 대신 각 빌드에서 수정 및 기능이 포함 된 것에 대해 자신의 문서 .... 개선했다 소원
크리스토프 베게너을

1

나는 이것이 조금 오래된 게시물이지만 다른 사람들에게 도움이 될 수 있음을 알았습니다.

요컨대 "수신 창 자동 조정"을 활성화해야합니다.

netsh int tcp set global autotuninglevel=normal

CTCP는 위에 설정되지 않은 아무것도 의미하지 않습니다.

"Receive Window Auto-Tuning"을 비활성화하면 64KB 패킷 크기로 고정되어 광대역 연결에서 긴 RTT에 부정적인 영향을 미칩니다. "제한된"및 "매우 제한된"옵션으로 실험 할 수도 있습니다.

아주 좋은 참조 : https://www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html


1

Windows 클라이언트 (Windows 7)와 비슷한 문제가 발생했습니다. 나는 Nagle 알고리즘, TCP Chimney Offloading 및 기타 TCP 관련 설정 변경을 비활성화하여 대부분의 디버깅을 거쳤습니다. 그들 중 어떤 것도 효과가 없었습니다.

마지막으로 문제를 해결 한 것은 AFD 서비스의 레지스트리에서 기본 전송 창을 수정하는 것이 었습니다. 이 문제는 afd.sys 파일과 관련이있는 것 같습니다. 여러 클라이언트를 테스트했지만 일부는 느린 업로드를 보였지만 일부는 그렇지 않았지만 모두 Windows 7 시스템이었습니다. 동작이 느린 컴퓨터는 AFD.sys 버전이 동일했습니다. 특정 버전의 AFD.sys가있는 컴퓨터에는 레지스트리 해결 방법이 필요합니다 (죄송합니다. 버전 번호를 기억하지 마십시오).

HKLM \ CurrentControlSet \ 서비스 \ AFD \ 매개 변수

추가-DWORD-DefaultSendWindow

값-10 진수-1640960

그 가치는 내가 여기에서 찾은 것입니다 : https://helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-

적절한 값을 사용한다고 생각하면 다음을 사용하여 직접 계산해야합니다.

예. 보급형 업로드 : 15Mbps = 15,000Kbps

(15000/8) * 1024 = 1920000

내가 이해 한 바에 따르면 클라이언트 소프트웨어는 일반적으로 레지스트리에서이 설정을 재정의해야하지만 그렇지 않은 경우 기본값이 사용되며 일부 버전의 AFD.sys 파일에서는 기본값이 매우 낮습니다.

대부분의 MS 제품은 업로드 속도가 느리다는 것을 알았습니다 (IE, Mini-redirector (WebDAV), Windows 탐색기를 통한 FTP 등) 타사 소프트웨어 (예 : Filezilla)를 사용할 때 같은 속도가 느려졌습니다 .

AFD.sys는 모든 Winsock 연결에 영향을 미치므로이 수정은 FTP, HTTP, HTTPS 등에 적용됩니다.

또한이 수정 프로그램은 어딘가에 위에 나열되어 있으므로 누군가에게 효과가있는 경우 크레딧을 받고 싶지 않지만이 스레드에 너무 많은 정보가있어서 광택이 날 것 같았습니다.


0

글쎄, 나는 비슷한 상황에 처해 있었고 ( 여기서 나의 질문 ) 결국 TCP 스케일링 휴리스틱 스를 비활성화하고 자동 튜닝 프로파일을 수동으로 설정하고 CTCP를 활성화해야했다.

# disable heuristics
C:\Windows\system32>netsh interface tcp set heuristics wsh=disabled
Ok.

# enable receive-side scaling
C:\Windows\system32>netsh int tcp set global rss=enabled
Ok.

# manually set autotuning profile
C:\Windows\system32>netsh interface tcp set global autotuning=experimental
Ok. 

# set congestion provider
C:\Windows\system32>netsh interface tcp set global congestionprovider=ctcp
Ok. 

0

의견이 충분하지 않으므로 대신 "답변"을 게시하겠습니다. 비슷한 / 동일한 문제인 것 같습니다 ( 여기서 serverfault 질문 참조 ). 내 (아마도 당신의) 문제는 Windows에서 iperf 클라이언트의 전송 버퍼입니다. 64KB 이상으로 커지지는 않습니다. Windows는 프로세스에 의해 명시 적으로 크기가 조정되지 않은 경우 버퍼를 동적으로 증가시킵니다. 그러나 그 역동적 인 성장은 일어나지 않습니다.

"느린"Windows의 경우 최대 50 만 바이트의 창이 열리는 창 크기 조절 그래프에 대해 잘 모르겠습니다. 5Mbps로 제한되는 경우 그래프가 ~ 64,000 바이트로만 열리는 것으로 예상됩니다.


0

이것은 매혹적인 스레드이며 긴 지방 파이프의 처리량을 테스트하기 위해 Win7 / iperf를 사용했던 문제와 정확히 일치합니다.

Windows 7 솔루션은 iperf 서버와 클라이언트 모두에서 다음 명령을 실행하는 것입니다.

netsh 인터페이스 TCP 설정 글로벌 자동 튜닝 수준 = 실험

주의 :이 작업을 수행하기 전에 자동 튜닝의 현재 상태를 기록하십시오.

netsh 인터페이스 tcp show global

수신 창 자동 조정 레벨 : 비활성화

그런 다음 파이프의 각 끝에서 iperf 서버 / 클라이언트를 실행하십시오.

테스트에 따라 자동 튜닝 값을 재설정하십시오.

netsh interface tcp set 전역 자동 튜닝 수준 =

   autotuninglevel - One of the following values:
                     disabled: Fix the receive window at its default
                         value.
                     highlyrestricted: Allow the receive window to
                         grow beyond its default value, but do so
                         very conservatively.
                     restricted: Allow the receive window to grow
                         beyond its default value, but limit such
                         growth in some scenarios.
                     normal: Allow the receive window to grow to
                         accomodate almost all scenarios.
                     experimental: Allow the receive window to grow
                         to accomodate extreme scenarios.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.