Нечетные tcp заходят в тупик под окнами

Мы перемещаем большие объемы данных по LAN, и это должно произойти очень быстро и надежно. В настоящее время мы используем окна TCP, как реализовано в C++. Используя (синхронный) большой отправляет перемещениям данные намного быстрее, чем набор (синхронных) меньших отправляет, но будет часто заводить в тупик для больших разрывов времени (.15 секунд) то, чтобы заставлять полную скорость передачи резко упасть. Эта мертвая блокировка происходит при очень конкретных обстоятельствах, который заставляет меня полагать, что это должно быть предотвратимо в целом. Что еще более важно, если мы действительно не знаем причины, мы действительно не знаем, что этого не произойдет, некоторое время с меньшим отправляет так или иначе. Кто-либо может объяснить эту мертвую блокировку?

Описание мертвой блокировки (хорошо, заблокированный зомби, это не мертво, но в течение приблизительно.15 секунд это останавливается, затем запускается снова),

  1. Сторона получения отправляет ACK.
  2. Передающая сторона отправляет, пакет, содержащий конец сообщения (продвиньте флаг, установлен),
  3. Вызов к socket.recv занимает приблизительно.15 секунд (!) для возврата
  4. Во время возвращается вызов, ACK отправляется стороной получения
  5. Следующий пакет от отправителя наконец отправляется (почему он ожидает? tcp окно - много большое),

Нечетная вещь, которая приблизительно (3) - то, что обычно, что вызов не занимает время вообще и получает точно тот же объем данных. На машине на 2 ГГц это - 300 миллионов ценности инструкций времени. Я предполагаю, что вызов (не дай бог) не ожидает полученных данных, чтобы быть затвердевшим, прежде чем это возвратится, таким образом, ack должен ожидать вызова для возврата, или оба должны быть задержаны из-за чего-то еще.

Проблемы НИКОГДА не происходит, когда существует второй пакет данных (часть того же сообщения) прибывающий между 1 и 2. Та часть очень ясно заставляет его казаться, что это имеет отношение к тому, что окна TCP не передадут ACK без данных обратно, пока или второй пакет не прибудет или таймер на 200 мс, истекает. Однако задержка составляет меньше чем 200 мс (больше как 150 мс).

Третий непристойный символ (и по моему мнению настоящий преступник) (5). Отправьте определенно называется задолго до того, на который возросли.15 секунд, но данные НИКОГДА не поражают провод перед этим возвраты ack. Это - самая причудливая часть этой мертвой блокировки мне. Не tcp блокировка, потому что окно TCP - много большое, так как мы устанавливаем SO_RCVBUF на что-то как 500*1460 (который все еще находится под meg). Данные входят очень быстро (в основном существует цикл, затягивающий данные через, отправляют), таким образом, буфер должен заполниться почти сразу. MSDN упоминает, что там различная "эвристика" использовала в решении, когда отправить хиты провод, и что уже ожидание отправляет + полный буфер, вызовет, отправляют к блоку, пока данные не совершают нападки, провод (иначе отправляют, по-видимому, действительно, просто копирует данные в tcp, отправляют буфер и возвраты).

Anway, почему отправитель на самом деле не отправляет больше данных во время тех.15 вторых пауз, является самой причудливой частью мне. Информация выше была получена на стороне получения через wireshark (кроме, конечно, времен возврата socket.recv, которые были зарегистрированы текстовый файл). Мы пытались изменить отправить буфер, чтобы обнулить и выключить nagel на отправителе (да, я знаю, что nagel о не отправке небольших пакетов - но мы пытались выключить nagel в случае, если это было частью неустановленного влияния "эвристики", будет ли сообщение добавлено к проводу. Технически nagel Microsoft - то, что небольшой пакет не отправляется, если буфер полон и существует выдающийся ACK, таким образом, он походил на возможность).

5
задан John Robertson 12 May 2010 в 21:43
поделиться

1 ответ

Блокировка отправки до получения предыдущего ACK почти наверняка указывает на то, что окно приема TCP заполнено (вы можете проверить это, используя Wireshark для анализа сетевого трафика).

Неважно, насколько велико ваше TCP-окно, если принимающее приложение не обрабатывает данные так быстро, как они поступают, тогда TCP-окно в конечном итоге заполнится. Как быстро мы здесь разговариваем? Что получающая сторона делает с данными? (Если вы записываете полученные данные на диск, вполне возможно, что ваш диск просто не справляется с гигабитной сетью на полную мощность).


Итак, у вас есть окно приема 730 000 байт, и вы передаете данные со скоростью 480 Мбит / с. Это означает, что для полного заполнения вашего окна требуется всего 12 мсек - поэтому, когда возникает задержка 150 мс на стороне приема, окно приема заполняется почти мгновенно и заставляет отправителя зависать.

Итак, ваша основная причина - задержка в 150 мс при планировании процесса приема. Это может быть вызвано множеством причин (это может быть так же просто, как ядру нужно сбрасывать грязные страницы на диск, чтобы создать еще несколько свободных страниц для вашего приложения); вы можете попробовать увеличить приоритет планирования процессов, но нет гарантии, что это поможет.

3
ответ дан 15 December 2019 в 06:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: