Зависает копирование файлов

Метки:  , , ,

В определенный момент времени, от пользователя одной межрегиональной компании было получено обращение о довольно таки необычной и впервые мною наблюдаемой ошибке. В заявке отмечалось, что время от времени у клиента зависает копирование файлов по сети. Постепенно проблема эскалировалась на некоторое ограниченное количество других станции, при этом не приобретя характер эпидемии. По началу, описанная ситуация была зафиксирована в корпоративной сети между клиентскими рабочими станциями, функционирующими под управлением операционной системы Windows 7 и файловым сервером на Windows 2008R2. Зависание копирования файлов наблюдалось только для файлов, имеющих определенный размер, ориентировочно в диапазоне от 100 мегабайт и более, и визуально характеризовалось останавливающимся на произвольной отметке индикатором прогресса копирования и оценочной скоростью 0 байт/сек.:

Копирование файлов зависает

..в таком вот состоянии процесс копирования мог пребывать сколь угодно долго, абсолютно не реагируя ни на какие действия пользователя применительно к окну.

Проблема

Поначалу создалось впечатление, что в проблеме однозначно участвует файловый сервер Windows 2008R2, однако чуть позже, после более детального изучения инцидента стало очевидным, что зависает копирование файлов так же и между двумя произвольными клиентскими рабочими станциями, включенными в корпоративную локальную сеть. И в то же время, инцидент проявлял себя не часто и далеко не на всех машинах, было зафиксировано, что некоторые станции в корпоративной сети работали с тем же файловым сервером и между собой абсолютно нормально. При проявлении описанной проблемы сама система функционировала в штатном режиме, однако процесс explorer.exe, в контексте которого происходило копирование, зависал наглухо, зачастую не давая себя снимать через диспетчер задач. При этом, как минимум, протокол SMB переставал нормально функционировать, наблюдались проблемы с доступам к сетевым ресурсам. К тому же, в процессе выключения проблемной станции, этап завершения сеанса мог выполняться бесконечно долго. На основании обобщенного анализа всех деталей инцидента, можно было сделать вывод о достаточно сыром коде обработки различных нештатных ситуаций в стеке TCP/IP Windows 7, однако истинная причина крылась вовсе не в этом.
Как всегда, по началу применялся всеми горячо любимый, великий и могучий "метод тыка", обновлялись драйвера, сбрасывались настройки сетевого интерфейса, сравнивались установленные обновления, устраивались различные ритуальные танцы с бубном вокруг проблемных машин :), использовались и прочие, не менее действенные методы из арсенала технического специалиста. В итоге всего этого увлекательного действа виновник был найден, и им оказался сетевой маршрутизатор (располагающийся на пути следования пакетов данных), имеющий одну интересную особенность: прошивка не поддерживала динамическое окно передачи.

Теория

Перед нами встает резонный вопрос, что же это за динамическое окно передачи и какое влияние данная технология оказывает на процесс передачи файлов между хостами в сети? Применительно к протоколу TCP/IP определены такие понятия как окно приема TCP (TCP Receive Window, RWIN) и окно передачи TCP (TCP Send Window). В действительности это одно логическое окно, просто создается оно как на принимающей, так и на передающей сторонах при инициализации TCP соединения между двумя узлами сети, имеет на обеих сторонах одинаковую размерность, представляет из себя, фактически, типичный буфер (блок данных в памяти). Окно используется для контроля скорости потока принимающей стороной, а так же для указания количества данных, которые могут быть отправлены отправителем за один прием, оно так же определяет, какой объем неподтвержденных данных может находиться в пути от отправителя к получателю. Отправитель может посылать только байты передаваемого потока, находящиеся в данный момент внутри этого логического окна. Окно как бы перемещается по исходящему байтовому потоку данных на отправляющей стороне и входящему байтовому потоку данных на принимающей стороне. Выражаясь яснее, участок данных в исходящем байтовом потоке, который отправителю разрешено отправлять, соответствует участку данных во входящем байтовом потоке, который получатель может принять.

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

Технология масштабирования окна TCP (TCP Window Scaling), описанная в предложении RFC 1323, была реализована разработчиками впервые еще в сетевом стеке TCP/IP операционной системы Windows 2000, но по-умолчанию предусмотрительно была отключена. В версиях Windows, предшествующих Vista, окно приема TCP имело максимальный размер, равный 64 килобайта (65535 байт). Начиная с Windows Vista разработчики модифицировали стек TCP/IP и реализовали алгоритм автоматической настройки окна приема TCP (TCP Receive Window Auto-Tuning), который использует TCP Window Scaling Option. Теперь уже окно приема TCP, за счет введения дополнительной опции в заголовке TCP пакета, может расширяться аж до 16 мегабайт. Алгоритм TCP Receive Window Auto-Tuning позволяет ядру определять оптимальный размер окна приема TCP на основании измерения интегрального показателя задержки передачи и скорости извлечения данных принимающим приложением, после чего размер окна адаптируется (в реальном времени) в соответствии с изменяющимися параметрами физического канала передачи и приложения. Во время передачи данных в рамках TCP-сессии обе стороны стараются установить оптимальный размер данного окна для повышения производительности обмена данными через каналы с высокой пропускной способностью и высоким показателем задержки передачи, к коим и относится большинство современных каналов сети Интернет.

Отличная технология, и всё было бы хорошо, если бы все устройства поддерживали алгоритм автоматической настройки окна приема TCP.

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

Решение

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

Приведенные ниже команды необходимо выполнять из-под учетной записи с правами локального администратора.

Давайте посмотрим текущее состояние некоторых параметров настройки интерфейса TCP/IP, выполнив следующую команду:

netsh interface tcp show global

В ответ мы получили вывод текущих параметров настройки TCP/IP, среди которых нас интересует "Уровень автонастройки окна получения", который по-умолчанию имеет значение "normal":

зависает копирования файлов

Параметр может принимать следующие значения:

  • disabled предписывает использовать фиксированное значение окна приема TCP. Значение по-умолчанию = 64 килобайта (65535 байт). Полная совместимость со устаревшим сетевым оборудованием;
  • highlyrestricted позволяет окну приема TCP выходить за границы значения по-умолчанию, в разумных пределах;
  • restricted позволяет окну приема TCP выходить за границы значения по-умолчанию, еще более свободно;
  • normal установка по умолчанию. Допускает увеличение окна приема TCP с учетом большинства возможных сценариев обмена;
  • experimental позволяет окну приема TCP увеличиваться до максимальных значений (16+ мегабайт). Не рекомендуется, потому как может вызвать падение производительности в большинстве возможных сценариев обмена;
После применения нижеописанных команд потребуется перезагрузка операционной системы.

Для начала переводим уровень автонастройки окна получения в значение disabled, фактически отключая автонастройку и предписывая использование фиксированного значения:

netsh interface tcp set global autotuninglevel=disabled

Вышеприведенная команда полностью устраняет зависание копирования файлов, однако, опционально, я бы рекомендовал выполнить еще и следующую.
Следующая команда отключает масштабирование на принимающей стороне (receive-side scaling), которое распределяет сетевую нагрузку между несколькими ядрами процессора в многопроцессорной системе:

netsh interface tcp set global rss=disabled

Выводы

В ситуации, когда обмен данными происходит между двумя, напрямую подключенными друг к другу, станциями под управлением операционных систем Windows версий Vista и более поздних, проблема никогда себя не обнаруживает. Однако в современной корпоративной сетевой среде довольно часто применяются управляемые коммутаторы и прочие сложные сетевые устройства, и вот именно их собратья с устаревшим микропрограммным обеспечением, не поддерживающие динамическое окно передачи, и становятся источником проблемы зависания копирования файлов (и ряда смежных). Конкретно в нашем случае виновником был Cisco Catalyst 3750 v2 с версией Cisco IOS Software младше 12.3(15). В дополнение к данной конфигурации, теоретически ошибка может проявляться при передаче между двумя станциями, подключенными напрямую, одна из которых работает под управлением Windows версии Vista и более поздних, а другая под управлением старых операционных систем (таких как Windows XP и более ранних), однако я лично подобную связку не тестировал.

Комментарии: 22

  1. Одмин

    спасибо - полезно

  2. Прекрасная грамотная и вдумчивая статья, позволяющая (по аналогии,если с умом подойти) понять львиную долю неисправностей в среде Windows.
    Остается только воскликнуть: " Автора!"
    В общем глубокий респект и уважение.

    1. einaare

      спасибо. действительно, у Windows огромное количество замаскированных недоработок... и периодически они "выстреливают" :) ну что поделать, надо как то дальше жить..

  3. Петр

    Впрочем, желаю автору сохранения его скромности и не слишком витиеватого стиля.
    Это намного важнее всех писаний.

  4. Большое спасибо за статью! Помогла решить эту проблему. Я не особо разбираюсь в глубинах. Как раньше называли таких как я "эникейщик". Реально работа встала из-за нехватки места, а сбросить на nas не могу, виснет :(
    Понимаю, что дело не в оборудовании так как неделю назад все работало. Пробно залил на nas большой файл с ноутбука - все ок, значит понял, что комп виноват. Применил ваши настройки - все ок.
    Еще раз спасибо за ваше решение!

    1. einaare

      не за что, заходите :)

  5. Иван

    Спасибо! К такому невозможно прийти

  6. дэн

    ах*енно, теперь вообще не грузит

    1. einaare

      подробности?

  7. Alex

    Аналогичные симптомы. Только у меня локальная сеть с altlinux 8 и mac os x 10.7.5. Компьютеры соединены проводами через рутер keenetic. Копирую папку с фото и видео из mac os на диск в altlinux. Начинает резво, но на каких-то файлах замерзает и всё. В папке есть несколько больших (100, 200, ...1000...mb) файлов с видео. Отдельные файлы любого объема копирует нормально. Интересно, что при попытке очередной раз скопировать туже папку в тоже место, с указанием не перезаписывать уже имеющиеся файлы замерзает сразу. Поведение одинаково как с smb так и с afp. Возможно это не ваш случай. Что делать не пойму. Может здесь подскажут?

    1. shofixti

      keenetic на свежей прошивке? тогда надо смотреть в сторону протоколов. может сетевой стек где-нибудь тюнинговался при помощи sysctl? сетевые анализаторы пробовали типа tcptrace и подобные?

  8. Alex

    Спасибо.
    Keenetic свежий и прошивка в нем последняя.
    Попробую покапать по вашим наводкам.

  9. Не нашел...
    У меня винда 10, оперативы 32...
    Висит, собака. Мертво висит(

  10. Максим

    Спасибо огромное! Больше года мучался с этой проблемой, только сегодня нашел эту статью! Наконец-то заработало копирование по сети!

    1. einaare

      советую прошивку у роутера/маршрутизатора/коммутатора обновить заодно, если доступен.

  11. Oleg

    Огромное Спасибо!

  12. Oleg

    Данная статья помогла устранить проблему зависания при копировании.
    Но Через неделю ситуация повторилась.
    ЧЯДНТ?
    Куда копать дальше?
    Может быть подобную настройку надо произвести и на роутере (Mikrotik hAP ac^2 , RouterOS v6.47.1 (stable)).
    Но возможно ли это?

  13. Oleg

    При этом заметил разницу:
    При копировании файла (56Гиг) с использованием \\tsclient\...., т.е. с сервера на станцию - Виснит на 8-10процентах. Скорость при этом не более 29мб.
    При копировании с Сетевого ресурса на станцию этого же файла (скорость до 100Мб) и зависания нет.
    Что это?

    1. einaare

      что за ОС на серверах и клиенте?

  14. Oleg

    При этом копирование аналогичного файла с другого сервера на эту же станцию (уже через интернет ) проходит успешно.

  15. Егор

    Отличная статья ;) Доступно и внятно написано.
    Возможно немного не по теме, но мало ли -2 сервера на 2019й винде, копирование через свитч по 10Gbit между 2мя серверами волнообразное с выраженной периодичностью. Может, кто сталкивался и смог победить? :)

    1. einaare

      скрины дадите поглядеть?

Добавить комментарий

Ваш адрес email не будет опубликован.