Windows TCP Window Scaling Memukul dataran tinggi terlalu dini

50

Skenario: Kami memiliki sejumlah klien Windows yang secara teratur mengunggah file besar (FTP / SVN / HTTP PUT / SCP) ke server Linux yang ~ 100-160ms jauhnya. Kami memiliki bandwidth sinkron 1Gbit / s di kantor dan server adalah instance AWS atau di-host secara fisik di US DC.

Laporan awal adalah bahwa unggahan ke instance server baru jauh lebih lambat daripada yang seharusnya. Ini membosankan dalam pengujian dan dari berbagai lokasi; klien melihat stabil 2-5Mbit / s ke host dari sistem Windows mereka.

Saya pecah iperf -spada contoh AWS dan kemudian dari klien Windows di kantor:

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

Angka terakhir dapat bervariasi secara signifikan pada tes berikutnya, (Vagaries of AWS) tetapi biasanya antara 70 dan 130Mbit / s yang lebih dari cukup untuk kebutuhan kita. Wiresharking sesi, saya bisa melihat:

  • iperf -c Windows SYN - Window 64kb, Skala 1 - Linux SYN, ACK: Window 14kb, Skala: 9 (* 512) penskalaan jendela iperf dengan Jendela 64kb default
  • iperf -c -w1M Windows SYN - Windows 64kb, Skala 1 - Linux SYN, ACK: Jendela 14kb, Skala: 9 penskalaan jendela iperf dengan Jendela 1MB default

Jelas tautan tersebut dapat mempertahankan throughput yang tinggi ini, tetapi saya harus secara eksplisit mengatur ukuran jendela untuk memanfaatkannya, yang tidak akan membiarkan saya melakukannya oleh sebagian besar aplikasi dunia nyata. Jabat tangan TCP menggunakan titik awal yang sama dalam setiap kasus, tetapi yang dipaksakan skala

Sebaliknya, dari klien Linux pada jaringan yang sama secara langsung, iperf -c(menggunakan sistem default 85kb) memberi saya:

[  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

Tanpa paksaan, itu berskala seperti yang diharapkan. Ini tidak bisa menjadi sesuatu dalam hop intervening atau switch / router lokal kami dan tampaknya mempengaruhi klien Windows 7 dan 8 sama. Saya telah membaca banyak panduan tentang penyetelan otomatis, tetapi ini biasanya tentang menonaktifkan penskalaan untuk bekerja di sekitar perangkat jaringan rumah yang buruk.

Adakah yang bisa memberi tahu saya apa yang terjadi di sini dan memberi saya cara untuk memperbaikinya? (Lebih disukai sesuatu yang bisa saya tempel ke registri melalui GPO.)

Catatan

Contoh AWS Linux yang bersangkutan memiliki pengaturan kernel berikut diterapkan di 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

Saya telah menggunakan dd if=/dev/zero | ncpengalihan ke /dev/nulldi ujung server untuk mengesampingkan iperfdan menghapus kemungkinan hambatan lainnya, tetapi hasilnya hampir sama. Pengujian dengan ncftp(Cygwin, Native Windows, Linux) memiliki skala yang hampir sama dengan tes iperf di atas pada platform masing-masing.

Sunting

Saya telah melihat hal lain yang konsisten di sini yang mungkin relevan: masukkan deskripsi gambar di sini

Ini adalah detik pertama dari tangkapan 1MB, diperbesar. Anda dapat melihat Slow Start beraksi saat jendela naik dan buffer bertambah besar. Lalu ada dataran kecil ~ 0.2s ini tepat pada titik bahwa tes iperf jendela default rata selamanya. Yang satu ini tentu saja mencapai ketinggian yang jauh lebih tinggi, tetapi aneh bahwa ada jeda dalam penskalaan (Nilai adalah 1022bytes * 512 = 523264) sebelum melakukannya.

Pembaruan - 30 Juni.

Menindaklanjuti berbagai tanggapan:

  • Mengaktifkan CTCP - Ini tidak ada bedanya; penskalaan jendela identik. (Jika saya mengerti ini dengan benar, pengaturan ini meningkatkan kecepatan di mana jendela kemacetan diperbesar daripada ukuran maksimum yang bisa dicapai)
  • Mengaktifkan cap waktu TCP. - Tidak ada perubahan di sini juga.
  • Algoritma Nagle - Itu masuk akal dan setidaknya itu berarti saya mungkin dapat mengabaikan blip tertentu dalam grafik sebagai indikasi masalah.
  • file pcap: File zip tersedia di sini: https://www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip (Dianonimkan dengan bittwiste, ekstrak ke ~ 150MB karena ada ~ 150MB karena ada satu dari setiap klien OS untuk perbandingan)

Pembaruan 2 - 30 Juni

O, jadi ikuti op saran Kyle, saya sudah mengaktifkan ctcp dan menonaktifkan pemuatan cerobong: 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

Namun sayangnya, tidak ada perubahan dalam throughput.

Saya punya pertanyaan sebab / akibat di sini, meskipun: Grafik adalah dari nilai RWIN yang ditetapkan dalam ACK server ke klien. Dengan klien Windows, apakah saya benar berpikir bahwa Linux tidak mengubah nilai ini di luar titik rendah itu karena CWIN yang terbatas dari klien bahkan mencegah buffer untuk diisi? Mungkinkah ada beberapa alasan lain bahwa Linux secara buatan membatasi RWIN?

Catatan: Saya sudah mencoba menyalakan ECN untuk itu; tapi tidak ada perubahan, di sana.

Pembaruan 3 - 31 Juni.

Tidak ada perubahan setelah menonaktifkan heuristik dan autotuning RWIN. Telah memperbarui driver jaringan Intel ke yang terbaru (12.10.28.0) dengan perangkat lunak yang memaparkan tab tweak viadevice manajer fungsi. Kartu ini adalah chipset on-board 82579V NIC - (Saya akan melakukan beberapa pengujian lagi dari klien dengan realtek atau vendor lain)

Berfokus pada NIC sejenak, saya sudah mencoba yang berikut (Kebanyakan hanya mengesampingkan penyebab yang tidak mungkin):

  • Tingkatkan buffer yang diterima menjadi 2k dari 256 dan kirimkan buffer ke 2k dari 512 (Keduanya sekarang maksimum) - Tidak ada perubahan
  • Menonaktifkan semua pembongkaran checksum IP / TCP / UDP. - Tidak ada perubahan.
  • Dinonaktifkan Besar Kirim Offload - Nada.
  • Mematikan IPv6, penjadwalan QoS - Nowt.

Perbarui 3 - 3 Juli

Mencoba menghilangkan sisi server Linux, saya memulai contoh Server 2012R2 dan mengulangi pengujian menggunakan iperf(cygwin binary) dan NTttcp .

Dengan iperf, saya harus menentukan secara eksplisit -w1mdi kedua sisi sebelum koneksi akan melebihi ~ 5Mbit / s. (Kebetulan, saya bisa diperiksa dan BDP ~ 5Mbits pada latensi 91ms hampir persis 64kb. Cari batasnya ...)

Binari ntttcp sekarang menunjukkan batasan seperti itu. Menggunakan ntttcpr -m 1,0,1.2.3.5di server dan ntttcp -s -m 1,0,1.2.3.5 -t 10di klien, saya bisa melihat throughput yang jauh lebih baik:

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 menempatkannya di tingkat yang saya dapatkan dengan jendela besar secara eksplisit iperf. Anehnya, 80MB pada 1273 buffer = buffer 64kB lagi. Wireshark lebih lanjut menunjukkan RWIN yang baik dan variabel yang kembali dari server (Scale factor 256) yang tampaknya dipenuhi oleh klien; jadi mungkin ntttcp salah melaporkan jendela kirim.

Perbarui 4 - 3 Juli

Atas permintaan @ karyhead, saya telah melakukan beberapa pengujian lagi dan membuat beberapa tangkapan lagi, di sini: https://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip

  • Dua lagi iperf, keduanya dari Windows ke server Linux yang sama seperti sebelumnya (1.2.3.4): Satu dengan ukuran 128k Socket dan jendela 64k default (membatasi hingga ~ 5Mbit / dtk lagi) dan satu dengan jendela kirim 1MB dan soket standar 8kb ukuran. (skala lebih tinggi)
  • Satu ntttcpjejak dari klien Windows yang sama ke instance Server 2012R2 EC2 (1.2.3.5). di sini, throughputnya berskala baik. Catatan: NTttcp melakukan sesuatu yang aneh pada port 6001 sebelum membuka koneksi tes. Tidak yakin apa yang terjadi di sana.
  • Satu jejak data FTP, mengunggah 20MB /dev/urandomke host linux yang hampir identik (1.2.3.6) menggunakan Cygwin ncftp. Sekali lagi batasnya ada di sana. Polanya hampir sama menggunakan Windows Filezilla.

Mengubah iperfpanjang buffer memang membuat perbedaan yang diharapkan ke grafik urutan waktu (lebih banyak bagian vertikal), tetapi throughput aktual tidak berubah.

SmallClanger
sumber
11
Contoh langka dari masalah yang diteliti dengan baik yang tidak jelas dalam dokumentasi. Bagus - mari kita berharap seseorang menemukan solusi (karena entah bagaimana saya pikir saya dapat menggunakannya juga).
TomTom
2
Coba aktifkan RFC 1323 Stempel waktu karena dinonaktifkan secara default di Windows sementara Linux mengaktifkannya secara default). netsh int tcp set global timestamps=enabled
Brian
3
Penundaan 200 ms mungkin adalah algoritma Nagle dalam aksi. Karena data diterima oleh TCP pada koneksi tertentu, ia mengirim pemberitahuan kembali hanya jika salah satu dari kondisi berikut ini benar: Tidak ada pemberitahuan dikirim untuk segmen sebelumnya yang diterima; Segmen diterima, tetapi tidak ada segmen lain yang tiba dalam 200 milidetik untuk koneksi itu.
Greg Askew
2
Adakah peluang memasang beberapa tangkapan paket dari salah satu pengirim yang lebih lambat di suatu tempat?
Kyle Brandt
Saya telah memperbarui OP saya dengan hasil tes ini dan tautan ke file penangkapan yang representatif.
SmallClanger

Jawaban:

15

Sudahkah Anda mencoba mengaktifkan Compound TCP (CTCP) di klien Windows 7/8 Anda.

Silakan baca:

Meningkatkan Kinerja Sisi Pengirim untuk Transmisi BDP Tinggi

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

...

Algoritma ini bekerja dengan baik untuk BDP kecil dan menerima ukuran jendela yang lebih kecil. Namun, ketika Anda memiliki koneksi TCP dengan ukuran jendela penerimaan yang besar dan BDP yang besar , seperti mereplikasi data antara dua server yang terletak di tautan WAN kecepatan tinggi dengan waktu bolak- balik 100 ms , algoritme ini tidak meningkatkan jendela kirim cukup cepat untuk sepenuhnya memanfaatkan bandwidth koneksi .

Untuk memanfaatkan bandwidth koneksi TCP dengan lebih baik dalam situasi ini, Next Generation TCP / IP stack mencakup Compound TCP (CTCP). CTCP secara lebih agresif meningkatkan jendela kirim untuk koneksi dengan ukuran jendela penerimaan besar dan BDP . CTCP berupaya memaksimalkan throughput pada jenis koneksi ini dengan memonitor variasi dan kehilangan delay. Selain itu, CTCP memastikan bahwa perilakunya tidak berdampak negatif terhadap koneksi TCP lainnya.

...

CTCP diaktifkan secara default di komputer yang menjalankan Windows Server 2008 dan dinonaktifkan secara default di komputer yang menjalankan Windows Vista. Anda dapat mengaktifkan CTCP dengan netsh interface tcp set global congestionprovider=ctcpperintah. Anda dapat menonaktifkan CTCP dengan netsh interface tcp set global congestionprovider=noneperintah.

Edit 6/30/2014

untuk melihat apakah CTCP benar-benar "aktif"

> netsh int tcp show global

yaitu

masukkan deskripsi gambar di sini

PO berkata:

Jika saya mengerti ini dengan benar, pengaturan ini meningkatkan kecepatan di mana jendela kemacetan diperbesar daripada ukuran maksimum yang bisa dicapai

CTCP secara agresif meningkatkan jendela kirim

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

TCP majemuk

Algoritme yang ada yang mencegah pengiriman TCP peer melebihi jaringan dikenal sebagai start lambat dan penghindaran kemacetan. Algoritma ini meningkatkan jumlah segmen yang dapat dikirim pengirim, yang dikenal sebagai jendela kirim, saat awalnya mengirim data pada koneksi dan ketika memulihkan dari segmen yang hilang. Awal yang lambat meningkatkan jendela kirim oleh satu segmen TCP penuh untuk setiap segmen pengakuan yang diterima (untuk TCP pada Windows XP dan Windows Server 2003) atau untuk setiap segmen yang diakui (untuk TCP pada Windows Vista dan Windows Server 2008). Penghindaran kemacetan meningkatkan jendela kirim oleh satu segmen TCP penuh untuk setiap jendela penuh data yang diakui.

Algoritma ini bekerja dengan baik untuk kecepatan media LAN dan ukuran jendela TCP yang lebih kecil. Namun, ketika Anda memiliki koneksi TCP dengan ukuran jendela penerimaan yang besar dan produk penundaan bandwidth besar (bandwidth tinggi dan penundaan tinggi), seperti mereplikasi data antara dua server yang terletak di tautan WAN berkecepatan tinggi dengan perjalanan pulang pergi 100 ms waktu, algoritma ini tidak meningkatkan jendela kirim cukup cepat untuk sepenuhnya memanfaatkan bandwidth koneksi. Misalnya, pada tautan WAN 1 Gigabit per detik (Gbps) dengan round trip time (RTT) 100 ms, diperlukan waktu hingga satu jam untuk jendela kirim untuk awalnya meningkat ke ukuran jendela besar yang diiklankan oleh penerima dan untuk memulihkan ketika ada segmen yang hilang.

Untuk memanfaatkan bandwidth koneksi TCP dengan lebih baik dalam situasi ini, Next Generation TCP / IP stack mencakup Compound TCP (CTCP). CTCP secara lebih agresif meningkatkan jendela kirim untuk koneksi dengan ukuran jendela penerimaan besar dan produk penundaan bandwidth besar. CTCP berupaya memaksimalkan throughput pada jenis koneksi ini dengan memonitor variasi dan kehilangan delay . CTCP juga memastikan bahwa perilakunya tidak berdampak negatif terhadap koneksi TCP lainnya.

Dalam pengujian yang dilakukan secara internal di Microsoft, waktu cadangan file besar berkurang hampir setengahnya untuk koneksi 1 Gbps dengan 50ms RTT. Koneksi dengan produk penundaan bandwidth yang lebih besar dapat memiliki kinerja yang lebih baik. CTCP dan Receive Window Auto-Tuning bekerja bersama untuk meningkatkan pemanfaatan tautan dan dapat menghasilkan peningkatan kinerja yang substansial untuk koneksi produk penundaan bandwidth besar.

Menepuk
sumber
3
Sama seperti pelengkap jawaban ini, Powershell setara di Server 2012 / Win8.1 adalah Set-NetTCPSettingdengan -CongestionProviderparameter ... yang menerima CCTP, DCTCP, dan Default. Klien Windows dan server menggunakan penyedia kemacetan default yang berbeda. technet.microsoft.com/en-us/library/hh826132.aspx
Ryan Ries
Saya mengerti apa yang Anda maksudkan, tetapi tampaknya itu tidak berlaku. Demi itu, saya berlari 30 menit iperfdan Window masih belum pernah melebihi ~ 520kb. Sesuatu yang lain membatasi CWND sebelum algoritma agresif ini dapat menunjukkan manfaat apa pun.
SmallClanger
ada bug Vista lama (yang sudah diperbaiki) yang menyajikan masalah seperti ini ketika mengirimkan protokol non-HTML. Apakah masalah Anda terlihat persis sama saat mentransfer file yang sama dengan HTML atau katakanlah dengan FTP?
Pat
@Pat - Ya. Komitmen SVN (melalui HTTP dan HTTPS) dan transfer FTP ke sistem lain di AWS juga menunjukkan batas yang sama.
SmallClanger
bagaimana dengan Win client's firewall? dapatkah Anda menguji dengan firewall sepenuhnya? lihat di sini: ask.wireshark.org/questions/2365/tcp-window-size-and-scaling
Pat
12

Mengklarifikasi Masalah:

TCP memiliki dua jendela:

  • Jendela terima: Berapa banyak byte yang tersisa di buffer. Ini adalah kontrol aliran yang diberlakukan oleh penerima. Anda dapat melihat ukuran jendela terima di wireshark karena terdiri dari ukuran jendela dan faktor penskalaan jendela di dalam tajuk TCP. Kedua sisi koneksi TCP akan mengiklankan jendela penerimaan mereka, tetapi umumnya yang Anda pedulikan adalah yang menerima sebagian besar data. Dalam kasus Anda, ini adalah "server" karena klien mengunggah ke server
  • Jendela kemacetan. Ini adalah kontrol aliran yang dikenakan oleh Pengirim. Ini dikelola oleh sistem operasi dan tidak muncul di header TCP. Ini mengontrol tingkat seberapa cepat data akan dikirim.

Dalam file ambil yang Anda berikan. Kita dapat melihat bahwa buffer penerima tidak pernah meluap:

masukkan deskripsi gambar di sini

Analisis saya adalah bahwa pengirim tidak mengirim cukup cepat karena jendela kirim (alias jendela kontrol kemacetan) tidak cukup terbuka untuk memuaskan RWIN penerima. Singkatnya, penerima mengatakan "Beri aku Lebih Banyak", dan ketika Windows adalah pengirimnya, pengirimannya tidak cukup cepat.

Hal ini dibuktikan oleh fakta bahwa dalam grafik di atas, RWIN tetap terbuka, dan dengan waktu round trip 0,09 detik dan RWIN ~ 500.000 byte, kita dapat mengharapkan throughput maks sesuai dengan produk penundaan bandwidth menjadi (500000) /0.09) * 8 = ~ 42 Mbit / s (dan Anda hanya mendapatkan ~ 5 dalam kemenangan Anda untuk Linux capture).

Bagaimana memperbaikinya?

Saya tidak tahu interface tcp set global congestionprovider=ctcpKedengarannya seperti hal yang benar untuk dilakukan kepada saya karena itu akan meningkatkan jendela kirim (yang merupakan istilah lain untuk jendela kemacetan). Anda mengatakan itu tidak berfungsi. Jadi hanya untuk memastikan:

  1. Apakah Anda reboot setelah mengaktifkan ini?
  2. Apakah cerobong asap mati? Jika mungkin coba nonaktifkan sebagai percobaan. Saya tidak tahu persis apa yang diturunkan saat ini diaktifkan, tetapi jika mengendalikan jendela kirim adalah salah satunya, mungkin congestionprovider tidak berpengaruh ketika ini diaktifkan ... Saya hanya menebak ...
  3. Juga, saya pikir ini mungkin pra windows 7, tetapi Anda dapat mencoba menambahkan dan bermain dengan dua kunci registri yang disebut DefaultSendWindow dan DefaultReceiveWindow di HKEY_LOCAL_MACHINE-System-CurrentControlSet-Services-AFD-Parameter. Jika ini bahkan berhasil, Anda mungkin telah ctcp.
  4. Namun dugaan lain, coba periksa netsh interface tcp show heuristics. Saya pikir itu mungkin RWIN, tetapi tidak dikatakan, jadi mungkin bermain dengan penonaktifan / mengaktifkan jika itu berdampak pada jendela kirim.
  5. Selain itu, pastikan driver Anda terbaru tentang klien pengujian Anda. Mungkin ada sesuatu yang rusak.

Saya akan mencoba semua percobaan ini dengan semua yang Anda offloading fitur untuk memulai dengan menghilangkan kemungkinan bahwa driver jaringan melakukan beberapa penulisan ulang / memodifikasi hal-hal (awasi CPU saat offloading dinonaktifkan). Struktur TCP_OFFLOAD_STATE_DELEGATED tampaknya setidaknya menyiratkan bahwa pembongkaran CWnd setidaknya mungkin.

Kyle Brandt
sumber
2
Saya telah melaporkan "jawaban" Anda karena milik Anda itu bukan jawaban; Saya langsung terpilih; sekarang saya melihat bagaimana "orang" memilih "tidak ada jawaban" Anda ... benar-benar lucu
Pat
1
@Pat: Anda dapat mengklik nomor suara juga untuk melihat rincian Upvotes / Downvotes. Saat ini Anda tidak memiliki downvotes pada jawaban Anda. Jawaban saya tidak menyelesaikan masalahnya (tapi belum ada jawaban), ia menjelaskan dan melokalisasi masalah (semoga benar!) Yang merupakan langkah penting dalam pemecahan masalah.
Kyle Brandt
@ Kyle Brandt jika Anda menerima milik Anda bukanlah jawaban, saya ingin tahu mengapa itu tidak "secara otomatis" dihapus tanpa pertimbangan lebih lanjut ?? dan kamu salah; Saya mendapat suara turun (tidak didukung) "segera" setelah saya melaporkan "jawaban" Anda; yang belum dihapus. Sepertinya Anda bermain dengan aturan "khusus" di sini.
Pat
1
@Pat Jika itu membantu, jawaban non-Kyle sangat membantu. Saya sekarang memiliki ide yang lebih jelas tentang buffer yang dibatasi dan saya merasa saya sedikit lebih dekat dengan solusi yang tepat sebagai hasilnya. Terkadang pertanyaan seperti ini bisa merupakan upaya kolaboratif yang, dengan sedikit mengedit secara bijaksana dapat menjadi Q yang tepat dan A yang tepat .
SmallClanger
@SmallClanger dengan segala hormat, SF memiliki seperangkat aturan yang harus diikuti oleh semua penggunanya termasuk Kyle Brandt; jika itu bukan jawaban, itu harus dihapus atau dipindahkan sebagai komentar tidak peduli berapa banyak teman yang dia miliki di antara klub "moderator".
Pat
5

Sudah ada beberapa info hebat di sini oleh @Pat dan @Kyle. Pasti memperhatikan penjelasan @ Kyle tentang menerima dan mengirim TCP, saya pikir ada beberapa kebingungan di sekitar itu. Untuk membingungkan masalah lebih lanjut, iperf menggunakan istilah "jendela TCP" dengan -wpengaturan yang merupakan jenis istilah yang ambigu berkaitan dengan menerima, mengirim, atau keseluruhan jendela geser. Apa yang sebenarnya dilakukannya adalah mengatur buffer send socket untuk -cinstance (klien) dan socket menerima buffer pada -sinstance (server). Di 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 ));
}

Seperti yang disebutkan Kyle, masalahnya bukan pada jendela terima pada kotak Linux, tetapi pengirimnya tidak cukup membuka jendela kirim. Bukannya itu tidak membuka cukup cepat, hanya tutup di 64k.

Ukuran buffer soket default pada Windows 7 adalah 64k. Inilah yang dikatakan dokumentasi tentang ukuran buffer socket dalam kaitannya dengan throughput di MSDN

Saat mengirim data melalui koneksi TCP menggunakan soket Windows, penting untuk menjaga jumlah data yang cukup luar biasa (dikirim tetapi belum diakui) dalam TCP untuk mencapai throughput tertinggi. Nilai ideal untuk jumlah data yang beredar untuk mencapai throughput terbaik untuk koneksi TCP disebut ukuran ideal mengirim backlog (ISB). Nilai ISB adalah fungsi dari produk penundaan bandwidth dari koneksi TCP dan jendela penerima yang diiklankan (dan sebagian jumlah kemacetan di jaringan).

Ok, bla bla bla, Sekarang kita mulai:

Aplikasi yang melakukan satu permintaan pengiriman pemblokiran atau non-pemblokiran pada suatu waktu biasanya mengandalkan buffer pengiriman internal oleh Winsock untuk mencapai throughput yang layak. Batas buffer kirim untuk koneksi yang diberikan dikendalikan oleh opsi soket SO_SNDBUF. Untuk metode pengiriman pemblokiran dan non-pemblokiran, batas buffer pengiriman menentukan berapa banyak data yang disimpan dalam TCP . Jika nilai ISB untuk koneksi lebih besar dari batas buffer kirim, maka throughput yang dicapai pada koneksi tidak akan optimal.

Throughput rata-rata tes iperf terbaru Anda menggunakan jendela 64k adalah 5.8Mbps. Itu dari Statistics> Summary in Wireshark, yang menghitung semua bit. Kemungkinan, iperf menghitung throughput data TCP yang 5.7Mbps. Kami melihat kinerja yang sama dengan uji FTP, ~ 5.6Mbps.

Throughput teoritis dengan buffer pengiriman 64k dan 91ms RTT adalah .... 5.5Mbps. Cukup dekat untukku.

Jika kami melihat tes iperf window 1MB Anda, tputnya adalah 88.2Mbps (86.2Mbps hanya untuk data TCP). Tput teoritis dengan jendela 1MB adalah 87,9Mbps. Sekali lagi, cukup dekat untuk pekerjaan pemerintah.

Apa yang diperlihatkan ini adalah bahwa buffer soket kirim secara langsung mengontrol jendela kirim dan, ditambah dengan jendela penerima dari sisi lain, mengontrol throughput. Jendela penerimaan yang diiklankan memiliki ruang, jadi kami tidak dibatasi oleh penerima.

Tunggu sebentar, bagaimana dengan bisnis autotuning ini? Tidakkah Windows 7 menangani hal-hal itu secara otomatis? Seperti yang telah disebutkan, Windows memang menangani penskalaan otomatis dari jendela terima, tetapi juga dapat menangani buffer pengirim secara dinamis. Mari kita kembali ke halaman MSDN:

Buffer pengiriman dinamis untuk TCP telah ditambahkan pada Windows 7 dan Windows Server 2008 R2. Secara default, buffering pengiriman dinamis untuk TCP diaktifkan kecuali aplikasi menetapkan opsi soket SO_SNDBUF pada soket aliran.

iperf menggunakan SO_SNDBUFsaat menggunakan -wopsi, jadi buffering pengiriman dinamis akan dinonaktifkan. Namun, jika Anda tidak menggunakannya -wmaka tidak digunakan SO_SNDBUF. Buffer pengiriman dinamis harus diaktifkan secara default, tetapi Anda dapat memeriksa:

netsh winsock show autotuning

Dokumentasi mengatakan Anda dapat menonaktifkannya dengan:

netsh winsock set autotuning off

Tetapi itu tidak berhasil untuk saya. Saya harus membuat perubahan registri dan mengatur ini ke 0:

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

Saya tidak berpikir menonaktifkan ini akan membantu; itu hanya FYI.

Mengapa skala buffer pengiriman Anda di atas 64k standar saat mengirim data ke kotak Linux dengan banyak ruang di jendela terima? Pertanyaan bagus Kernel Linux juga memiliki TCP stack autotuning. Seperti T-Pain dan Kanye melakukan duet autotune bersama, itu mungkin terdengar tidak bagus. Mungkin ada beberapa masalah dengan kedua tumpukan TCP autotuning yang saling berbicara.

Orang lain memiliki masalah sama seperti Anda dan dapat memperbaikinya dengan mengedit registri untuk meningkatkan ukuran buffer pengiriman default. Sayangnya, itu tampaknya tidak berfungsi lagi, setidaknya tidak untuk saya ketika saya mencobanya.

Pada titik ini, saya pikir jelas faktor pembatasnya adalah mengirim ukuran buffer pada host Windows. Mengingat bahwa itu tampaknya tidak tumbuh secara dinamis dengan benar, apa yang harus dilakukan seorang gadis?

Kamu bisa:

  • Gunakan aplikasi yang memungkinkan Anda untuk mengatur opsi pengiriman yaitu jendela buffer
  • Gunakan proksi Linux lokal
  • Gunakan proxy Windows jarak jauh?
  • Buka kasing dengan Microsofhahahahahahaha
  • Bir

Penafian: Saya telah menghabiskan banyak waktu untuk meneliti hal ini dan itu benar menurut pengetahuan saya dan google-fu. Tapi aku tidak akan bersumpah di makam ibuku (dia masih hidup).

Karyhead
sumber
Input fantasic; Terima kasih. Saya menggunakan iperf 2.0.4, saya akan bereksperimen dengan pengaturan dan memperbarui OP saya dengan beberapa caps baru juga.
SmallClanger
Oke, saya sudah memperbarui "jawaban" saya berdasarkan penelitian lebih lanjut dan tes terakhir Anda
karyhead
Terima kasih. Setidaknya sebagian senang mengetahui bahwa saya tidak hanya menjadi gila. Saya telah membaca beberapa blog / utas dari hari-hari XP / 2003 yang merekomendasikan pengaturan registri tersebut, tetapi mereka ditulis sebelum Vista / 2008 dan saya cukup yakin mereka diabaikan di Vista dan seterusnya. Saya pikir saya benar-benar akan menaikkan tiket dengan MS tentang hal ini (doakan saya beruntung)
SmallClanger
1
Alat yang berguna yang saya temui dalam penelitian saya adalah tcpanalyzer.exe di SDK ( microsoft.com/en-us/download/details.aspx?id=8279 ). Ini adalah netstat grafis yang dapat Anda pilih koneksi individual dan mendapatkan statistik TCP seperti RTT, cwnd, transmisi ulang, dll. Saya bisa membuat cwnd membuka jauh melampaui ukuran buffer kirim, tetapi tputnya tidak bertambah dan wireshark diverifikasi bahwa itu masih mengirim buffer terbatas.
karyhead
1
Saya telah menemukan komentar di beberapa forum tentang perintah "netsh" yang tidak berfungsi seperti yang diiklankan pada 7/8, dan orang-orang dipaksa untuk secara manual memasukkan entri registri yang sesuai; Saya ingin tahu apakah sesuatu seperti itu mungkin terjadi dengan opsi CTCP.
Pat
4

Setelah Anda mengatur TCP stack, Anda mungkin masih memiliki bottleneck di lapisan Winsock. Saya telah menemukan bahwa mengonfigurasi Winsock (Ancillary Function Driver di registri) membuat perbedaan besar untuk kecepatan unggah (mendorong data ke server) di Windows 7. Microsoft telah mengakui bug dalam autotuning TCP untuk soket yang tidak menghalangi - hanya saja jenis soket yang digunakan browser ;-)

Tambahkan kunci DWORD untuk DefaultSendWindow dan atur ke BDP atau lebih tinggi. Saya menggunakan 256000.

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

Mengubah pengaturan Winsock untuk unduhan mungkin membantu - tambahkan kunci untuk DefaultReceiveWindow.

Anda dapat bereksperimen dengan berbagai pengaturan level soket dengan menggunakan Fiddler Proxy dan perintah untuk menyesuaikan ukuran buffer soket klien dan server:

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
LeslieM
sumber
Sedikit tambahan informasi. Apakah Anda memiliki tautan referensi untuk bug MS, kebetulan?
SmallClanger
3

Setelah membaca semua analisis dalam jawaban, masalah ini sangat terdengar seperti Anda mungkin menjalankan Windows7 / 2008R2 alias Windows 6.1

Tumpukan jaringan (TCP / IP & Winsock) di Windows 6.1 benar-benar cacat dan memiliki banyak bug dan masalah kinerja yang akhirnya ditangani Microsoft selama bertahun-tahun sejak perbaikan terbaru sejak rilis awal 6.1.

Cara terbaik untuk menerapkan perbaikan terbaru ini adalah dengan menyaring secara manual semua halaman yang relevan di support.microsoft.com dan secara manual meminta dan mengunduh versi LDR dari hotfix tumpukan jaringan (ada banyak lusinan di antaranya).

Untuk menemukan perbaikan terbaru yang relevan, Anda harus menggunakan www.bing.com dengan permintaan pencarian berikut site:support.microsoft.com 6.1.7601 tcpip.sys

Anda juga perlu memahami cara kerja perbaikan terbaru LDR / GDR di Windows 6.1

Saya biasanya menggunakan daftar perbaikan LDR saya sendiri (bukan hanya perbaikan tumpukan jaringan) untuk Windows 6.1 dan kemudian secara proaktif menerapkan perbaikan ini ke server / klien Windows 6.1 yang saya temui. Itu adalah tugas yang sangat memakan waktu untuk secara teratur memeriksa perbaikan terbaru LDR.

Untungnya, Microsoft telah menghentikan praktik perbaikan terbaru LDR dengan versi OS yang lebih baru dan perbaikan bug sekarang tersedia melalui layanan pembaruan otomatis dari Microsoft.

UPDATE : Hanya satu contoh dari banyak bug jaringan di Windows7SP1 - https://support.microsoft.com/en-us/kb/2675785

UPDATE 2 : Berikut ini perbaikan terbaru yang menambahkan saklar netsh untuk memaksa penskalaan Window setelah transmisi kedua paket SYN (secara default, penskalaan jendela dinonaktifkan setelah 2 paket SYN ditransmisikan ulang) https://support.microsoft.com/en- us / kb / 2780879

Christoph Wegener
sumber
Terima kasih Christoph; beberapa input baru yang sangat menarik tentang ini dan 'fitur' pengiriman ulang SYN sangat aneh; Saya tidak bisa melihat tujuan desain di balik itu sama sekali. (Semacam deteksi kemacetan kasar, mungkin?). Semua tes asli dilakukan pada Win7SP1; kami akan segera menguji coba Win10, dan saya harus menjalankan kembali sebagian besar ini untuk melihat bagaimana tarifnya.
SmallClanger
Cabang Windows 10 mana yang akan Anda uji? Saya belum memiliki pengalaman dengan tumpukan jaringan di Windows 10.
Christoph Wegener
Enterprise 1511 adalah apa yang kami targetkan.
SmallClanger
Saya melihat. Cukup sulit untuk memutuskan cabang dengan Windows 10 karena ada begitu banyak. Saya sudah mengalami satu masalah dengan Windows 10 di mana saya tidak bisa menggunakan fitur tertentu karena saya berada di cabang LTSB. Saya berharap Microsoft mengurangi jumlah cabang yang tersedia secara keseluruhan dan sebagai gantinya meningkatkan dokumentasi mereka tentang perbaikan dan fitur apa yang termasuk dalam setiap pembangunan ....
Christoph Wegener
1

Saya melihat ini posting yang sedikit lebih tua tetapi bisa membantu orang lain.

Singkatnya Anda harus mengaktifkan "Terima Tuning Jendela Otomatis":

netsh int tcp set global autotuninglevel=normal

CTCP tidak berarti apa-apa tanpa diaktifkan di atas.

Jika Anda menonaktifkan "Terima Tuning Jendela Otomatis" Anda akan terjebak pada ukuran paket 64KB yang memiliki dampak negatif terhadap RTT panjang dalam koneksi broadband tinggi. Anda juga dapat bereksperimen dengan opsi "terbatas" dan "sangat terbatas".

Referensi yang sangat bagus: https://www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html

spricer
sumber
1

Saya mengalami masalah yang sama dengan Klien Windows (Windows 7). Saya telah melalui sebagian besar debug yang telah Anda lalui, menonaktifkan algoritma Nagle, TCP Chimney Offloading, dan banyak perubahan pengaturan terkait TCP lainnya. Tidak ada dari mereka yang memiliki efek.

Yang akhirnya memperbaikinya bagi saya adalah memodifikasi jendela kirim default di registri layanan AFD. Masalah ini tampaknya terkait dengan file afd.sys. Saya menguji beberapa klien, beberapa menunjukkan unggahan lambat, dan beberapa tidak, tetapi semuanya adalah mesin Windows 7. Mesin yang memperlihatkan perilaku lambat memiliki versi AFD.sys yang sama. Solusi registri diperlukan untuk komputer dengan versi AFD.sys tertentu (maaf, jangan ingat versi #nya).

HKLM \ CurrentControlSet \ Services \ AFD \ Parameter

Tambah - DWORD - DefaultSendWindow

Nilai - Desimal - 1640960

Nilai itu adalah sesuatu yang saya temukan di sini: https://helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-

Saya pikir untuk menggunakan nilai yang tepat, Anda harus menghitungnya sendiri menggunakan:

misalnya. Upload Diiklankan: 15 Mbps = 15.000 Kbps

(15000/8) * 1024 = 1920000

Dari apa yang saya pahami, perangkat lunak klien umumnya harus menimpa pengaturan ini dalam registri, tetapi jika tidak, nilai default digunakan, dan tampaknya nilai default sangat rendah di beberapa versi file AFD.sys.

Saya perhatikan bahwa sebagian besar produk MS memiliki masalah pengunggahan yang lambat (IE, Mini-redirector (WebDAV), FTP melalui Windows Explorer, dll ...) Ketika menggunakan perangkat lunak pihak ke-3 (mis. Filezilla), saya tidak memiliki kecepatan lambat yang sama .

AFD.sys memengaruhi semua koneksi Winsock, jadi perbaikan ini harus berlaku untuk FTP, HTTP, HTTPS, dll ...

Juga, perbaikan ini juga tercantum di atas di suatu tempat, jadi saya tidak ingin mengambil kredit untuk itu jika bekerja untuk siapa pun, namun ada begitu banyak informasi di utas ini sehingga saya khawatir ini mungkin telah diperbaiki.

jjspierx
sumber
0

Yah, saya sendiri pernah mengalami situasi yang serupa (pertanyaan saya di sini ), dan pada akhirnya saya harus menonaktifkan heuristik penskalaan TCP, secara manual mengatur profil autotuning dan mengaktifkan 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. 
André Fernandes
sumber
0

Saya tidak punya cukup poin untuk berkomentar, jadi saya akan memposting "jawaban". Saya mengalami masalah yang serupa / identik (lihat pertanyaan serverfault di sini ). Masalah saya (dan mungkin Anda) adalah buffer kirim klien iperf di windows. Itu tidak tumbuh melebihi 64 KB. Windows seharusnya menumbuhkan buffer secara dinamis ketika tidak diukur secara eksplisit oleh proses. Tetapi pertumbuhan dinamis itu tidak terjadi.

Saya tidak yakin tentang grafik penskalaan jendela Anda yang menunjukkan jendela membuka hingga 500.000 byte untuk kasing Windows "lambat" Anda. Saya berharap untuk melihat grafik yang terbuka hanya ~ 64.000 byte mengingat Anda dibatasi hingga 5 Mbps.

Chris Stankevitz
sumber
0

Ini adalah utas yang menarik dan persis cocok dengan masalah yang saya miliki menggunakan Win7 / iperf untuk menguji throughput pada pipa panjang yang berlemak.

Solusi untuk Windows 7 adalah dengan menjalankan perintah berikut di kedua server iperf DAN klien.

antarmuka netsh tcp atur global autotuninglevel = eksperimental

NB: Sebelum Anda melakukan ini, pastikan untuk mencatat status autotuning saat ini:

netsh interface tcp show global

Terima Level Penalaan Otomatis Jendela: dinonaktifkan

Kemudian jalankan server iperf / klien di setiap ujung pipa.

Setel ulang nilai autotuning dengan mengikuti tes Anda:

antarmuka netsh tcp atur global autotuninglevel =

   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.
Wicksee
sumber