Сценарий. У нас есть ряд клиентов 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 -c -w1M
Windows SYN - Windows 64 КБ, Масштаб 1 - Linux SYN, ACK: Окно 14 КБ, Масштаб: 9
Ясно, что ссылка может поддерживать эту высокую пропускную способность, но я должен подробно установить размер окна, чтобы использовать его, что большинство реальных приложений мне не позволят. 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
- Еще два
iperf
s, оба с 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) с использованием Cygwinncftp
. Опять предел есть. Пример такой же, как в Windows Filezilla.
Изменение iperf
длины буфера делает ожидаемую разницу с графиком временной последовательности (намного больше вертикальных секций), но фактическая пропускная способность остается неизменной.
источник
netsh int tcp set global timestamps=enabled
Ответы:
Вы пытались включить Compound TCP (CTCP) в своих клиентах Windows 7/8.
Пожалуйста, прочитайте:
Повышение производительности на стороне отправителя для передачи с высоким BDP
http://technet.microsoft.com/en-us/magazine/2007.01.cableguy.aspx
Редактировать 30.06.2014
чтобы увидеть, действительно ли CTCP включен
т.е.
CTCP агрессивно увеличивает окно отправки
http://technet.microsoft.com/en-us/library/bb878127.aspx
источник
Set-NetTCPSetting
соответствует-CongestionProvider
параметру ..., который принимает CCTP, DCTCP и Default. Клиент и серверы Windows используют разных поставщиков перегрузок по умолчанию. technet.microsoft.com/en-us/library/hh826132.aspxiperf
а окно по-прежнему никогда не масштабировалось за пределы ~ 520kb. Что-то еще ограничивает CWND, прежде чем этот агрессивный алгоритм может показать какие-либо преимущества.Разъяснение проблемы:
TCP имеет два окна:
В файле захвата вы указали. Мы видим, что буфер приема никогда не переполняется:
Мой анализ состоит в том, что отправитель не отправляет достаточно быстро, потому что окно отправки (также известное как окно контроля перегрузки) не открывается достаточно, чтобы удовлетворить RWIN получателя. Короче говоря, получатель говорит «Дай мне больше», а когда Windows является отправителем, он отправляет недостаточно быстро.
Об этом свидетельствует тот факт, что на приведенном выше графике RWIN остается открытым, и при времени кругового обхода 0,09 секунд и RWIN ~ 500 000 байтов мы можем ожидать, что максимальная пропускная способность в соответствии с произведением задержки полосы пропускания будет равна (500 000). /0.09) * 8 = ~ 42 Мбит / с (и вы выигрываете в захвате Linux только на ~ 5).
Как это исправить?
Я не знаю.
interface tcp set global congestionprovider=ctcp
звучит как то, что мне нужно сделать, потому что это увеличило бы окно отправки (что является еще одним термином для окна перегрузки). Вы сказали, что это не работает. Так что просто чтобы убедиться:netsh interface tcp show heuristics
. Я думаю, что это может быть RWIN, но это не говорит, так что, возможно, поиграйте с отключением / включением, если это повлияет на окно отправки.Я бы попробовал начать все эти эксперименты со всеми вашими функциями разгрузки, чтобы исключить возможность того, что сетевые драйверы выполняют некоторые действия по переписыванию / модификации (следите за процессором, пока разгрузка отключена). Структура TCP_OFFLOAD_STATE_DELEGATED , кажется, по крайней мере , означает , что CWnd разгрузка по крайней мере , возможно.
источник
Здесь была отличная информация от @Pat и @Kyle. Обязательно обратите внимание на объяснение @ Kyle окон TCP для приема и отправки, я думаю, что в этом была некоторая путаница. Чтобы еще больше запутать ситуацию, iperf использует термин «окно TCP» с
-w
настройкой, которая является своего рода неоднозначным термином в отношении получения, отправки или общего скользящего окна. На самом деле он устанавливает буфер отправки сокета для-c
экземпляра (клиента) и буфер приема сокета для-s
экземпляра (сервера). Вsrc/tcp_window_size.c
:Как упоминает Кайл, проблема заключается не в окне приема в окне Linux, но отправитель недостаточно открывает окно отправки. Дело не в том, что он не открывается достаточно быстро, он ограничен 64k.
Размер буфера сокета по умолчанию в Windows 7 составляет 64 КБ. Вот что говорится в документации о размере буфера сокета относительно пропускной способности в MSDN
Хорошо, бла-бла-бла, теперь мы идем:
Средняя пропускная способность вашего последнего теста 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:
iperf использует
SO_SNDBUF
при использовании-w
опции, поэтому динамическая буферизация отправки будет отключена. Однако, если вы не используете,-w
то он не используетSO_SNDBUF
. Динамическая буферизация отправки должна быть включена по умолчанию, но вы можете проверить:Документация говорит, что вы можете отключить его с помощью:
Но это не сработало для меня. Мне пришлось внести изменения в реестр и установить это в 0:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters\DynamicSendBufferDisable
Я не думаю, что отключение этого поможет; это просто к вашему сведению.
Почему ваш буфер отправки не масштабируется выше 64 КБ по умолчанию при отправке данных в ящик Linux с достаточным пространством в окне приема? Отличный вопрос Ядра Linux также имеют стек TCP с автонастройкой. Как T-Pain и Kanye вместе делают дуэт автонастройки, это может звучать не очень хорошо. Возможно, есть какая-то проблема с этими двумя стеками TCP для автонастройки, которые разговаривают друг с другом.
У другого человека была такая же проблема, как у вас, и он мог исправить ее с помощью редактирования реестра, чтобы увеличить размер буфера отправки по умолчанию. К сожалению, это больше не работает, по крайней мере, для меня это не получилось, когда я попробовал.
На данный момент, я думаю, ясно, что ограничивающим фактором является размер буфера отправки на хосте Windows. Учитывая, что, похоже, он не растет должным образом динамически, что делать девушке?
Ты можешь:
Отказ от ответственности: я потратил много часов, исследуя это, и это, насколько мне известно, правильно и Google-фу. Но я не буду ругаться на могиле моей матери (она все еще жива).
источник
После настройки стека TCP у вас может остаться узкое место в слое Winsock. Я обнаружил, что настройка Winsock (драйвера вспомогательных функций в реестре) имеет огромное значение для скорости загрузки (передачи данных на сервер) в Windows 7. Microsoft признала ошибку в автонастройке TCP для неблокирующих сокетов - только вид сокета, который используют браузеры ;-)
Добавьте ключ DWORD для DefaultSendWindow и установите его в BDP или выше. Я использую 256000.
Может помочь изменение параметра Winsock для загрузки - добавьте ключ для DefaultReceiveWindow.
Вы можете поэкспериментировать с различными настройками уровня сокетов, используя прокси-сервер Fiddler и команды для настройки размеров буфера сокетов клиента и сервера:
источник
Прочитав весь анализ ответов, эта проблема звучит так, как будто вы работаете под 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
источник
Я вижу, что это немного более старый пост, но он может помочь другим.
Короче говоря, вы должны включить «Автоматическую настройку окна приема»:
CTCP ничего не значит без включенного выше.
Если вы отключите «Автоматическую настройку окна приема», вы застрянете с размером пакета 64 КБ, что отрицательно скажется на длинных RTT в высокоскоростных соединениях. Вы также можете поэкспериментировать с «ограниченным» и «сильно ограниченным» вариантом.
Очень хорошая ссылка: https://www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html
источник
У меня была похожая проблема с клиентами 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 и т. Д.
Кроме того, это исправление было упомянуто где-то выше, так что я не хочу брать на себя ответственность за него, если оно работает для кого-либо, однако в этой теме было так много информации, что я боялся, что она могла быть закрыта.
источник
Ну, я сам столкнулся с подобной ситуацией (мой вопрос здесь ), и в итоге мне пришлось отключить эвристику масштабирования TCP, вручную установить профиль автонастройки и включить CTCP:
источник
У меня недостаточно очков, чтобы комментировать, поэтому вместо этого я отправлю «ответ». Я имею то , что , как представляется, подобная / идентичной проблемой (см Serverfault вопрос здесь ). Моя (и, вероятно, ваша) проблема - это буфер отправки клиента iperf в Windows. Объем не превышает 64 КБ. Предполагается, что Windows динамически увеличивает буфер, если он явно не определен процессом. Но этого динамичного роста не происходит.
Я не уверен в вашем графике масштабирования окна, который показывает открытие окна до 500 000 байтов для вашего "медленного" случая Windows. Я ожидал увидеть этот график открытым только для ~ 64 000 байтов, учитывая, что вы ограничены 5 Мбит / с.
источник
Это увлекательная тема, которая точно соответствует проблемам, с которыми я сталкивался при использовании Win7 / iperf для проверки пропускной способности на длинных толстых каналах.
Решением для Windows 7 является выполнение следующей команды как на сервере iperf, так и на клиенте.
интерфейс netsh tcp set global autotuninglevel = экспериментальный
NB. Перед тем как сделать это, обязательно запишите текущий статус автонастройки:
интерфейс netsh tcp show global
Уровень автоматической настройки окна получения: отключен
Затем запустите сервер / клиент iperf на каждом конце канала.
Сбросьте значение автонастройки в соответствии с вашими тестами:
интерфейс netsh tcp set global autotuninglevel =
источник