Windows TCP Window Scaling Попадание на плато слишком рано

50

Сценарий. У нас есть ряд клиентов Windows, которые регулярно загружают большие файлы (FTP / SVN / HTTP PUT / SCP) на серверы Linux, которые находятся на расстоянии ~ 100-160 мс. У нас есть синхронная пропускная способность 1 Гбит / с в офисе, и серверы являются либо экземплярами AWS, либо физически размещены в DC США.

Первоначальный отчет состоял в том, что загрузка на новый экземпляр сервера была намного медленнее, чем могла бы быть. Это подтвердилось в тестировании и из разных мест; клиенты видели стабильные 2-5 Мбит / с на хосте из своих систем Windows.

Я iperf -sподключился к экземпляру AWS, а затем к клиенту Windows в офисе:

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 до 130 Мбит / с, что более чем достаточно для наших нужд. Перефразируя сеанс, я вижу:

  • iperf -c Windows SYN - окно 64 КБ, масштаб 1 - Linux SYN, ACK: окно 14 КБ, масштаб: 9 (* 512) Масштабирование окна iperf с окном по умолчанию 64 КБ
  • iperf -c -w1M Windows SYN - Windows 64 КБ, Масштаб 1 - Linux SYN, ACK: Окно 14 КБ, Масштаб: 9 масштабирование окна iperf с окном по умолчанию 1 МБ

Ясно, что ссылка может поддерживать эту высокую пропускную способность, но я должен подробно установить размер окна, чтобы использовать его, что большинство реальных приложений мне не позволят. TCP-рукопожатия используют одинаковые начальные точки в каждом случае, но принудительное масштабирование

И наоборот, из клиента Linux в той же сети прямой iperf -c(с использованием системного значения по умолчанию 85 КБ) дает мне:

[  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, Native Windows, Linux) масштабируются во многом так же, как и вышеупомянутые тесты iperf на соответствующих платформах.

редактировать

Здесь я обнаружил еще одну непротиворечивую вещь, которая может иметь значение: введите описание изображения здесь

Это первая секунда захвата 1 МБ, увеличенная. Вы можете увидеть медленный запуск в действии, когда окно масштабируется и буфер увеличивается. Затем появляется это крошечное плато, равное ~ 0,2 с, точно в той точке, в которой тест iperf окна по умолчанию выравнивается навсегда. Это, конечно, масштабируется до гораздо более высоких головокружительных высот, но любопытно, что есть такая пауза в масштабировании (значения составляют 1022 байта * 512 = 523264), прежде чем он это сделает.

Обновление - 30 июня.

Вслед за различными ответами:

  • Включение CTCP - это не имеет значения; масштабирование окна идентично. (Если я правильно понимаю, этот параметр увеличивает скорость, с которой увеличивается окно перегрузки, а не максимальный размер, который он может достичь)
  • Включение меток времени TCP. - Здесь тоже без изменений.
  • Алгоритм Нэгла - это имеет смысл, и, по крайней мере, это означает, что я, вероятно, могу игнорировать эти специфические всплески на графике как любое указание на проблему.
  • Файлы pcap: Zip-файл доступен здесь: https://www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip (анонимизируется с помощью bittwiste, извлекается в ~ 150 МБ, поскольку есть по одному от каждого клиента ОС для сравнения)

Обновление 2 - 30 июня

О, так что, следуя предложению Кайла, я включил 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

Но, к сожалению, без изменений в пропускной способности.

У меня действительно есть вопрос причины / следствия здесь, хотя: Графики имеют значение RWIN, установленное в ACK сервера для клиента. Что касается клиентов Windows, то правильно ли я считаю, что Linux не масштабирует это значение выше этой нижней точки, поскольку ограниченный CWIN клиента не позволяет заполнить даже этот буфер? Может ли быть какая-то другая причина, по которой Linux искусственно ограничивает RWIN?

Примечание: я пытался включить ECN, черт побери; но без изменений, там.

Обновление 3 - 31 июня.

Без изменений после отключения эвристики и автонастройки RWIN. Обновите сетевые драйверы Intel до последней версии (12.10.28.0) с помощью программного обеспечения, которое предоставляет функциональные настройки с помощью вкладок диспетчера устройств. Плата представляет собой встроенную сетевую плату с набором микросхем 82579 В (я собираюсь провести дополнительное тестирование от клиентов с Realtek или других поставщиков).

Сосредоточившись на сетевой карте, я попробовал следующее (в основном просто исключаю маловероятных преступников):

  • Увеличьте приемные буферы до 2k с 256 и передайте буферы до 2k с 512 (оба теперь максимально) - без изменений
  • Отключена вся выгрузка контрольной суммы IP / TCP / UDP. - Без изменений.
  • Отключено Большая отправка разгрузки - Nada.
  • Выключил IPv6, планирование QoS - Nowt.

Обновление 3 - 3 июля

Пытаясь устранить сторону сервера Linux, я запустил экземпляр Server 2012R2 и повторил тесты, используя iperf(бинарный файл cygwin) и NTttcp .

С iperf, я должен был явно указать -w1mна обе стороны , прежде чем соединение будет масштабироваться за ~ 5 Мбит / с. (Между прочим, я мог быть проверен, и BDP ~ 5 Мбит с задержкой 91 мс почти точно 64 КБ. Определите предел ...)

Двоичные файлы 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. Как ни странно, 80 МБ в 1273 буферах снова = буфер 64 КБ. Еще один Wireshark показывает хороший, переменный RWIN, возвращаемый с сервера (масштабный коэффициент 256), который клиент, кажется, выполняет; так что, возможно, ntttcp искажает окно отправки.

Обновление 4 - 3 июля

По запросу @ karyhead я провел еще несколько тестов и сгенерировал еще несколько снимков, здесь: https://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip

  • Еще два iperfs, оба с Windows на тот же сервер Linux, что и раньше (1.2.3.4): один с размером сокета 128 КБ и окном по умолчанию 64 КБ (снова ограничивается ~ 5 Мбит / с), а другой с окном отправки 1 МБ и сокетом по умолчанию 8 КБ размер. (весы выше)
  • Одна ntttcpтрассировка от того же клиента Windows к экземпляру Server 2012R2 EC2 (1.2.3.5). Здесь пропускная способность хорошо масштабируется. Примечание: NTttcp делает что-то странное с портом 6001 перед тем, как открыть тестовое соединение. Не уверен, что там происходит.
  • Одна трассировка данных FTP с загрузкой 20 МБ /dev/urandomна почти идентичный хост Linux (1.2.3.6) с использованием Cygwin ncftp. Опять предел есть. Пример такой же, как в Windows Filezilla.

Изменение iperfдлины буфера делает ожидаемую разницу с графиком временной последовательности (намного больше вертикальных секций), но фактическая пропускная способность остается неизменной.

SmallClanger
источник
11
Редкий случай хорошо изученной проблемы, которой явно нет в документации. Хорошо - будем надеяться, что кто-то найдет решение (потому что я думаю, что тоже могу это использовать).
TomTom
2
Попробуйте включить временные метки RFC 1323, так как они по умолчанию отключены в Windows, в то время как в Linux они включены по умолчанию). netsh int tcp set global timestamps=enabled
Брайан
3
Задержка 200 мс, вероятно, является алгоритмом Нагла в действии. Поскольку данные принимаются TCP по определенному соединению, он отправляет подтверждение обратно, только если выполняется одно из следующих условий: подтверждение для предыдущего полученного сегмента не было отправлено; Сегмент получен, но никакой другой сегмент не приходит в течение 200 миллисекунд для этого соединения.
Грег Аскью
2
Есть ли какой-нибудь шанс поднять некоторые захваты пакетов от одного из более медленных отправителей?
Кайл Брандт
Я обновил свой OP с результатами этих тестов и ссылками на репрезентативные файлы захвата.
SmallClanger

Ответы:

15

Вы пытались включить Compound TCP (CTCP) в своих клиентах Windows 7/8.

Пожалуйста, прочитайте:

Повышение производительности на стороне отправителя для передачи с высоким BDP

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

...

Эти алгоритмы хорошо работают для небольших BDP и меньших размеров окна приема. Однако, когда у вас есть TCP-соединение с большим размером окна приема и большим BDP , таким как репликация данных между двумя серверами, расположенными по высокоскоростному каналу глобальной сети с временем прохождения сигнала 100 мс , эти алгоритмы не увеличивают окно отправки достаточно быстро, чтобы полностью использовать пропускную способность соединения .

Чтобы лучше использовать пропускную способность соединений TCP в этих ситуациях, стек TCP / IP следующего поколения включает в себя составной TCP (CTCP). CTCP более агрессивно увеличивает окно отправки для соединений с большими размерами окна приема и BDP . CTCP пытается максимизировать пропускную способность для этих типов соединений, отслеживая изменения задержки и потери. Кроме того, CTCP гарантирует, что его поведение не окажет негативного влияния на другие соединения TCP.

...

CTCP включен по умолчанию на компьютерах под управлением Windows Server 2008 и отключен по умолчанию на компьютерах под управлением Windows Vista. Вы можете включить CTCP с помощью netsh interface tcp set global congestionprovider=ctcpкоманды. Вы можете отключить CTCP с помощью netsh interface tcp set global congestionprovider=noneкоманды.

Редактировать 30.06.2014

чтобы увидеть, действительно ли CTCP включен

> netsh int tcp show global

т.е.

введите описание изображения здесь

ПО сказал:

Если я правильно понимаю, этот параметр увеличивает скорость, с которой увеличивается окно перегрузки, а не максимальный размер, которого оно может достичь

CTCP агрессивно увеличивает окно отправки

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

Составной TCP

Существующие алгоритмы, которые не позволяют отправляющему TCP-узлу перегружать сеть, известны как медленный запуск и предотвращение перегрузок. Эти алгоритмы увеличивают количество сегментов, которые отправитель может отправить, известное как окно отправки, при первоначальной отправке данных по соединению и при восстановлении из потерянного сегмента. При медленном запуске окно отправки увеличивается на один полный сегмент TCP либо для каждого полученного сегмента подтверждения (для TCP в Windows XP и Windows Server 2003), либо для каждого подтвержденного сегмента (для TCP в Windows Vista и Windows Server 2008). Предотвращение перегрузок увеличивает окно отправки на один полный сегмент TCP для каждого полного окна данных, которые подтверждаются.

Эти алгоритмы хорошо работают для скорости передачи данных в локальной сети и меньших размеров окна TCP. Однако при наличии соединения TCP с большим размером окна приема и продуктом с большой задержкой полосы пропускания (высокая пропускная способность и высокая задержка), например, репликация данных между двумя серверами, расположенными по высокоскоростному каналу глобальной сети, с передачей данных в 100 мс. время эти алгоритмы не увеличивают окно отправки достаточно быстро, чтобы полностью использовать пропускную способность соединения. Например, для канала WAN со скоростью 1 Гбит / с (Гбит / с) и временем прохождения сигнала туда и обратно (RTT) 100 мсек, может потребоваться до часа, чтобы окно отправки первоначально увеличилось до большого размера окна, объявленного получателем, и восстановить, когда есть потерянные сегменты.

Чтобы лучше использовать пропускную способность соединений TCP в этих ситуациях, стек TCP / IP следующего поколения включает в себя составной TCP (CTCP). CTCP более агрессивно увеличивает окно отправки для соединений с большими размерами окна приема и продуктами с большой пропускной способностью. CTCP пытается максимизировать пропускную способность для этих типов соединений, отслеживая изменения задержки и потери . CTCP также гарантирует, что его поведение не окажет негативного влияния на другие соединения TCP.

При внутреннем тестировании в Microsoft время резервного копирования больших файлов сократилось почти вдвое для соединения со скоростью 1 Гбит / с с RTS 50 мс. Соединения с большей задержкой полосы пропускания могут иметь еще лучшую производительность. Автоматическая настройка CTCP и окна приема работает вместе для увеличения использования канала и может привести к значительному увеличению производительности при подключении продуктов с большой пропускной способностью.

похлопывание
источник
3
В дополнение к этому ответу эквивалент PowerShell в Server 2012 / Win8.1 Set-NetTCPSettingсоответствует -CongestionProviderпараметру ..., который принимает CCTP, DCTCP и Default. Клиент и серверы Windows используют разных поставщиков перегрузок по умолчанию. technet.microsoft.com/en-us/library/hh826132.aspx
Райан Райс
Я вижу, к чему вы клоните, но это не похоже на применение. Ради этого я пробежал 30 минут, iperfа окно по-прежнему никогда не масштабировалось за пределы ~ 520kb. Что-то еще ограничивает CWND, прежде чем этот агрессивный алгоритм может показать какие-либо преимущества.
SmallClanger
есть старая (уже исправленная) ошибка Vista, которая представляла такие проблемы при передаче не-HTML протоколов. Ваша проблема выглядит точно так же при передаче одного и того же файла по HTML или, скажем, по FTP?
Пэт
@Pat - Это так. SVN Commits (через HTTP и HTTPS) и FTP-передачи в другую систему на AWS также имеют те же ограничения.
SmallClanger
как насчет брандмауэра Win клиента? вы можете протестировать с полностью выключенным файерволом? смотрите здесь: ask.wireshark.org/questions/2365/tcp-window-size-and-scaling
Пэт
12

Разъяснение проблемы:

TCP имеет два окна:

  • Окно получения: сколько байтов осталось в буфере. Это управление потоком, наложенное приемником. Вы можете увидеть размер окна приема в wireshark, так как он состоит из размера окна и коэффициента масштабирования окна внутри заголовка TCP. Обе стороны TCP-соединения будут сообщать о своем окне приема, но, как правило, вам важна та, которая получает большую часть данных. В вашем случае это «сервер», так как клиент загружает на сервер
  • Окно заторов. Это контроль потока, наложенный Отправителем. Это поддерживается операционной системой и не отображается в заголовке TCP. Он контролирует скорость, с которой данные будут отправляться.

В файле захвата вы указали. Мы видим, что буфер приема никогда не переполняется:

введите описание изображения здесь

Мой анализ состоит в том, что отправитель не отправляет достаточно быстро, потому что окно отправки (также известное как окно контроля перегрузки) не открывается достаточно, чтобы удовлетворить RWIN получателя. Короче говоря, получатель говорит «Дай мне больше», а когда Windows является отправителем, он отправляет недостаточно быстро.

Об этом свидетельствует тот факт, что на приведенном выше графике RWIN остается открытым, и при времени кругового обхода 0,09 секунд и RWIN ~ 500 000 байтов мы можем ожидать, что максимальная пропускная способность в соответствии с произведением задержки полосы пропускания будет равна (500 000). /0.09) * 8 = ~ 42 Мбит / с (и вы выигрываете в захвате Linux только на ~ 5).

Как это исправить?

Я не знаю. interface tcp set global congestionprovider=ctcpзвучит как то, что мне нужно сделать, потому что это увеличило бы окно отправки (что является еще одним термином для окна перегрузки). Вы сказали, что это не работает. Так что просто чтобы убедиться:

  1. Вы перезагрузились после включения этого?
  2. Разгрузка дымохода включена? Если это возможно, попробуйте отключить его в качестве эксперимента. Я не знаю, что именно выгружается, когда это включено, но если управление окном отправки является одним из них, возможно, congestionprovider не действует, когда это включено ... Я просто догадываюсь ...
  3. Кроме того, я думаю, что это может быть до Windows 7, но вы можете попробовать добавить и поиграть с двумя ключами реестра с именами DefaultSendWindow и DefaultReceiveWindow в HKEY_LOCAL_MACHINE-System-CurrentControlSet-Services-AFD-Parameters. Если они даже работают, вы, вероятно, выключили ctcp.
  4. Еще одно предположение, попробуйте проверить netsh interface tcp show heuristics. Я думаю, что это может быть RWIN, но это не говорит, так что, возможно, поиграйте с отключением / включением, если это повлияет на окно отправки.
  5. Кроме того, убедитесь, что на вашем тестовом клиенте установлены последние версии драйверов. Может быть, что-то просто сломано.

Я бы попробовал начать все эти эксперименты со всеми вашими функциями разгрузки, чтобы исключить возможность того, что сетевые драйверы выполняют некоторые действия по переписыванию / модификации (следите за процессором, пока разгрузка отключена). Структура TCP_OFFLOAD_STATE_DELEGATED , кажется, по крайней мере , означает , что CWnd разгрузка по крайней мере , возможно.

Кайл Брандт
источник
2
Я сообщил ваш «ответ», потому что ваш не ответ; Я сразу же получил отрицательный голос; теперь я вижу, как "люди" голосуют за ваш "нет ответа" ... очень смешно
Пэт
1
@Pat: Вы можете нажать на номер голосования, чтобы увидеть разбивку Upvotes / Downvotes. В настоящее время у вас нет отрицательных ответов на ваш ответ. Мой ответ не решает его проблему (но пока нет ответа), он объясняет и локализует проблему (надеюсь, правильно!), Что является важным шагом в устранении неполадок.
Кайл Брандт
@ Кайл Брандт, если вы принимаете ваш, это не ответ. Интересно, почему он не "автоматически" удаляется без дальнейшего рассмотрения ?? а ты не прав; Я получил отрицательное голосование (unupvote) "как только", как только я сообщил о вашем "ответе"; тот еще не был удален. Кажется, вы играете по «особым» правилам здесь.
Пэт
1
@Pat Если это поможет, не ответ Кайла был невероятно полезен. Теперь у меня есть более четкое представление о том, какие буферы ограничены, и я чувствую, что в результате я немного ближе к правильному решению. Иногда такие вопросы, как это может быть результатом совместных усилий , что, с небольшим количеством разумном редактирования может стать собственно Q и собственно .
SmallClanger
@SmallClanger при всем уважении, у SF есть набор правил, которым должны следовать все его пользователи, включая Кайла Брандта; если он не является ответом, он должен быть удален или перемещен в качестве комментария, независимо от того, сколько у него друзей в клубе «модераторов».
Пэт
5

Здесь была отличная информация от @Pat и @Kyle. Обязательно обратите внимание на объяснение @ Kyle окон TCP для приема и отправки, я думаю, что в этом была некоторая путаница. Чтобы еще больше запутать ситуацию, 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 ));
}

Как упоминает Кайл, проблема заключается не в окне приема в окне Linux, но отправитель недостаточно открывает окно отправки. Дело не в том, что он не открывается достаточно быстро, он ограничен 64k.

Размер буфера сокета по умолчанию в Windows 7 составляет 64 КБ. Вот что говорится в документации о размере буфера сокета относительно пропускной способности в MSDN

При отправке данных по TCP-соединению с использованием сокетов Windows важно поддерживать достаточный объем ожидающих данных (отправленных, но еще не подтвержденных) в TCP для достижения максимальной пропускной способности. Идеальное значение для объема данных, ожидающих получения максимальной пропускной способности для соединения TCP, называется идеальным размером журнала невыполненных работ (ISB). Значение ISB является функцией произведения полосы пропускания соединения TCP и объявленного окна приема получателя (и частично количества перегрузки в сети).

Хорошо, бла-бла-бла, теперь мы идем:

Приложения, которые выполняют один блокирующий или неблокирующий запрос на отправку за раз, обычно используют внутреннюю буферизацию отправки Winsock для достижения достойной пропускной способности. Ограничение буфера отправки для данного соединения контролируется опцией сокета SO_SNDBUF. Для блокирующего и неблокирующего метода отправки ограничение на размер буфера отправки определяет объем данных, ожидающих обработки в TCP . Если значение ISB для соединения больше, чем предел буфера отправки, то пропускная способность, достигнутая для соединения, не будет оптимальной.

Средняя пропускная способность вашего последнего теста iperf с использованием окна 64 КБ составляет 5,8 Мбит / с. Это из Статистика> Сводка в Wireshark, которая считает все биты. Вероятно, iperf считает пропускную способность TCP, которая составляет 5,7 Мбит / с. Мы видим ту же производительность с тестом FTP, ~ 5,6 Мбит / с.

Теоретическая пропускная способность с буфером передачи 64 Кбит и RTT 91 мс составляет .... 5,5 Мбит / с. Достаточно близко для меня.

Если мы посмотрим на ваш тест iperf для окна размером 1 МБ, скорость передачи данных составит 88,2 Мбит / с (86,2 Мбит / с только для данных TCP). Теоретическая производительность с окном 1 МБ составляет 87,9 Мбит / с. Опять же, достаточно близко для работы правительства.

Это демонстрирует, что буфер отправляющего сокета напрямую управляет окном отправки, а вместе с окном приема с другой стороны контролирует пропускную способность. В объявленном окне приема есть место, поэтому мы не ограничены получателем.

Подожди, а как насчет этого бизнеса по автонастройке? Разве Windows 7 не обрабатывает эти вещи автоматически? Как уже упоминалось, Windows выполняет автоматическое масштабирование окна приема, но она также может динамически обрабатывать буфер отправки. Вернемся к странице MSDN:

Динамическая буферизация отправки для TCP была добавлена ​​в Windows 7 и Windows Server 2008 R2. По умолчанию динамическая буферизация отправки для TCP включена, если приложение не устанавливает параметр сокета SO_SNDBUF на сокете потока.

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

Я не думаю, что отключение этого поможет; это просто к вашему сведению.

Почему ваш буфер отправки не масштабируется выше 64 КБ по умолчанию при отправке данных в ящик Linux с достаточным пространством в окне приема? Отличный вопрос Ядра Linux также имеют стек TCP с автонастройкой. Как T-Pain и Kanye вместе делают дуэт автонастройки, это может звучать не очень хорошо. Возможно, есть какая-то проблема с этими двумя стеками TCP для автонастройки, которые разговаривают друг с другом.

У другого человека была такая же проблема, как у вас, и он мог исправить ее с помощью редактирования реестра, чтобы увеличить размер буфера отправки по умолчанию. К сожалению, это больше не работает, по крайней мере, для меня это не получилось, когда я попробовал.

На данный момент, я думаю, ясно, что ограничивающим фактором является размер буфера отправки на хосте Windows. Учитывая, что, похоже, он не растет должным образом динамически, что делать девушке?

Ты можешь:

  • Используйте приложения, которые позволяют вам установить буфер отправки, т.е. опцию окна
  • Используйте локальный Linux-прокси
  • Использовать удаленный прокси Windows?
  • Открыть дело с помощью Microsofhahahahahahaha
  • Пиво

Отказ от ответственности: я потратил много часов, исследуя это, и это, насколько мне известно, правильно и Google-фу. Но я не буду ругаться на могиле моей матери (она все еще жива).

karyhead
источник
Фантастический вклад; благодарю вас. Я использую iperf 2.0.4, я поэкспериментирую с настройками и обновлю свой OP с некоторыми новыми заглавными буквами.
SmallClanger
Хорошо, я обновил свой «ответ», основываясь на дополнительных исследованиях и ваших недавних тестах
karyhead
Благодарю. По крайней мере, отчасти приятно знать, что я не просто схожу с ума. Я читал несколько блогов / обсуждений за дни XP / 2003, которые рекомендуют эти параметры реестра, но они были написаны до Vista / 2008, и я уверен, что они игнорируются в Vista и далее. Я думаю, что на самом деле поднимет билет с MS об этом (пожелай мне удачи)
SmallClanger
1
Полезным инструментом, с которым я столкнулся в своем исследовании, был tcpanalyzer.exe в SDK ( microsoft.com/en-us/download/details.aspx?id=8279 ). Это графический netstat, в котором вы можете выбрать отдельное соединение и получить статистику TCP, такую ​​как RTT, cwnd, повторные передачи и т. Д. Я мог заставить cwnd открываться намного больше размера буфера отправки, но tput не увеличился и проверил wireshark что он все еще ограничен буфером отправки.
karyhead
1
На нескольких форумах я обнаружил комментарии о том, что команды «netsh» не работают, как было объявлено в 7/8, и что люди вынуждены вручную вводить соответствующие записи в реестре; Интересно, может ли что-то подобное происходить с опцией CTCP.
Пэт
4

После настройки стека TCP у вас может остаться узкое место в слое Winsock. Я обнаружил, что настройка Winsock (драйвера вспомогательных функций в реестре) имеет огромное значение для скорости загрузки (передачи данных на сервер) в Windows 7. Microsoft признала ошибку в автонастройке TCP для неблокирующих сокетов - только вид сокета, который используют браузеры ;-)

Добавьте ключ DWORD для DefaultSendWindow и установите его в 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
LeslieM
источник
Большой дополнительный бит информации. У вас есть ссылка на ошибку MS, случайно?
SmallClanger
3

Прочитав весь анализ ответов, эта проблема звучит так, как будто вы работаете под Windows7 / 2008R2 или Windows 6.1

Сетевой стек (TCP / IP и Winsock) в Windows 6.1 был ужасно испорчен и имел целый ряд ошибок и проблем с производительностью, которые Microsoft в конечном итоге устраняла в течение многих лет исправлений с момента первоначального выпуска 6.1.

Лучший способ применить эти исправления - это вручную просмотреть все соответствующие страницы на support.microsoft.com и вручную запросить и загрузить LDR-версии исправлений сетевого стека (их много десятков).

Чтобы найти соответствующие исправления, вы должны использовать www.bing.com со следующим поисковым запросом site:support.microsoft.com 6.1.7601 tcpip.sys

Вам также необходимо понять, как работают исправления LDR / GDR в Windows 6.1

Я обычно использовал свой собственный список исправлений LDR (не только исправлений сетевого стека) для Windows 6.1, а затем активно применял эти исправления к любому серверу / клиенту Windows 6.1, с которым я столкнулся. Регулярно проверять наличие новых исправлений LDR было очень трудоемкой задачей.

К счастью, Microsoft прекратила практику исправлений LDR с более новыми версиями ОС, и теперь исправления доступны через службы автоматического обновления от Microsoft.

ОБНОВЛЕНИЕ : только один пример многих сетевых ошибок в Windows7SP1 - https://support.microsoft.com/en-us/kb/2675785

ОБНОВЛЕНИЕ 2 : Вот еще одно исправление, которое добавляет переключатель netsh для принудительного масштабирования окна после второй повторной передачи пакета SYN (по умолчанию масштабирование окна отключено после повторной передачи 2 пакетов SYN) https://support.microsoft.com/en- нас / кб / 2780879

Кристоф Вегенер
источник
Спасибо Кристоф; некоторые очень интересные новые данные об этом и о том, что «особенность» SYN-ретрансляции очень странная; Я не вижу цели дизайна за этим вообще. (Возможно, какое-то грубое обнаружение заторов?). Все оригинальные тесты были сделаны на Win7SP1; скоро мы опробуем Win10, и я должен повторить большую часть этого, чтобы посмотреть, как он поживает.
SmallClanger
С какой веткой Windows 10 вы будете тестировать? У меня пока нет опыта работы с сетевым стеком в Windows 10.
Кристоф Вегенер
Предприятие 1511 - это то, к чему мы стремимся.
SmallClanger
Понимаю. Довольно сложно выбрать ветку с Windows 10, так как их так много. Я уже столкнулся с одной проблемой с Windows 10, где я не мог использовать определенную функцию, потому что я был на ветке LTSB. Я бы хотел, чтобы Microsoft сократила количество доступных веток в целом и вместо этого улучшила свою документацию о том, какие исправления и функции включены в каждую сборку ....
Кристоф Вегенер,
1

Я вижу, что это немного более старый пост, но он может помочь другим.

Короче говоря, вы должны включить «Автоматическую настройку окна приема»:

netsh int tcp set global autotuninglevel=normal

CTCP ничего не значит без включенного выше.

Если вы отключите «Автоматическую настройку окна приема», вы застрянете с размером пакета 64 КБ, что отрицательно скажется на длинных RTT в высокоскоростных соединениях. Вы также можете поэкспериментировать с «ограниченным» и «сильно ограниченным» вариантом.

Очень хорошая ссылка: https://www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html

spricer
источник
1

У меня была похожая проблема с клиентами Windows (Windows 7). Я прошел через большинство отладок, которые вы прошли, отключив алгоритм Nagle, разгрузку TCP Chimney и множество других изменений настроек, связанных с TCP. Ни один из них не имел никакого эффекта.

В конце концов мне это удалось исправить, изменив окно отправки по умолчанию в реестре службы AFD. Кажется, проблема связана с файлом afd.sys. Я протестировал несколько клиентов, некоторые демонстрировали медленную загрузку, а некоторые нет, но все они были компьютерами с Windows 7. Машины, которые демонстрировали медленное поведение, имели ту же версию AFD.sys. Временное решение реестра необходимо для компьютеров с определенными версиями AFD.sys (извините, не вспоминайте версии #).

HKLM \ CurrentControlSet \ Services \ AFD \ Parameters

Добавить - DWORD - DefaultSendWindow

Значение - десятичное - 1640960

Это значение я нашел здесь: https://helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-

Я думаю, чтобы использовать правильное значение, вы должны рассчитать его самостоятельно, используя:

например. Объявленная загрузка: 15 Мбит / с = 15 000 Кбит / с

(15000/8) * 1024 = 1920000

Из того, что я понимаю, клиентское программное обеспечение, как правило, должно переопределять этот параметр в реестре, но если этого не происходит, используется значение по умолчанию, и, по-видимому, значение по умолчанию является очень низким в некоторых версиях файла AFD.sys.

Я заметил, что в основном продукты MS имели проблему медленной загрузки (IE, мини-редиректор (WebDAV), FTP через Windows Explorer и т. Д.). При использовании стороннего программного обеспечения (например, Filezilla) у меня не было таких же замедлений ,

AFD.sys влияет на все соединения Winsock, поэтому это исправление должно применяться к FTP, HTTP, HTTPS и т. Д.

Кроме того, это исправление было упомянуто где-то выше, так что я не хочу брать на себя ответственность за него, если оно работает для кого-либо, однако в этой теме было так много информации, что я боялся, что она могла быть закрыта.

jjspierx
источник
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 вопрос здесь ). Моя (и, вероятно, ваша) проблема - это буфер отправки клиента iperf в Windows. Объем не превышает 64 КБ. Предполагается, что Windows динамически увеличивает буфер, если он явно не определен процессом. Но этого динамичного роста не происходит.

Я не уверен в вашем графике масштабирования окна, который показывает открытие окна до 500 000 байтов для вашего "медленного" случая Windows. Я ожидал увидеть этот график открытым только для ~ 64 000 байтов, учитывая, что вы ограничены 5 Мбит / с.

Крис Станкевиц
источник
0

Это увлекательная тема, которая точно соответствует проблемам, с которыми я сталкивался при использовании Win7 / iperf для проверки пропускной способности на длинных толстых каналах.

Решением для Windows 7 является выполнение следующей команды как на сервере iperf, так и на клиенте.

интерфейс netsh tcp set global autotuninglevel = экспериментальный

NB. Перед тем как сделать это, обязательно запишите текущий статус автонастройки:

интерфейс netsh tcp show global

Уровень автоматической настройки окна получения: отключен

Затем запустите сервер / клиент iperf на каждом конце канала.

Сбросьте значение автонастройки в соответствии с вашими тестами:

интерфейс netsh tcp set 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
источник