Назад | Перейти на главную страницу

Поведение стека tcp solaris с относительно высоким RTT и импульсным трафиком

У меня есть приложение, которое распределяет данные из Нью-Йорка в Токио через TCP под управлением Solaris 10. Средняя пропускная способность <1 Мбит / с, пиковая пропускная способность может достигать 20-30 Мбит / с в течение нескольких секунд, хотя типичные всплески больше похожи на 10 Мбит / с. Размеры отдельных сообщений невелики (~ 300 байт), и стабильность задержки является ключевым фактором. Это означает, что мы пытаемся удалить пакетную обработку, иначе nagles отключен, а приложение настроено на отправку как можно скорее, а не на очередь, а затем на отправку.

RTT между Нью-Йорком и Токио составляет ~ 180 мс, а окно TCP настроено на теоретическую пропускную способность в районе ~ 40 Мбит / с, или 1M tcp_xmit_hiwat / tcp_rcv_hiwat. tcp_max_buf и tcp_cwnd_max также имеют размер 1M.

Проблема здесь в том, что мы часто, но время от времени видим загадочные «паузы», когда отправитель получает EWOULDBLOCK, что приводит к накоплению во внутренней очереди и последующей разрядке данных. Здесь 2 проблемы

  1. нет очевидной причины для блокирующего сокета, похоже, что мы не достигаем пика пропускной способности, и ничто в захватах пакетов не предполагает какого-либо замедления
  2. в течение «периода разгрузки» (т.е. когда сокет отправителя больше не блокируется, но у него есть буфер данных для отправки), мы видим неуклонно увеличивающуюся пилообразную диаграмму скорости передачи сообщений.

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

Использование ЦП не является проблемой ни с одной стороны, SA утверждают, что коробки выглядят хорошо. Перегрузка канала WAN также не проблема, сети говорят, что сеть выглядит хорошо. На самом деле все говорят, что каждая вещь выглядит хорошо, но она по-прежнему плохо работает!

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

EWOULDBLOCK / EAGAIN означает, что данные не могут быть отправлены сразу. Чтобы разобраться, нам нужно больше информации о вашем коде.

  • Попытайтесь выяснить, что происходит на стороне отправителя, когда возвращается EWOULDBLOCK. Проверяйте потоки и другие процессы, отслеживайте использование памяти / подкачки и процессора. Проверьте свои журналы (/ var / messages, ...) на наличие аппаратных ошибок.
  • Определите потерю пакетов
  • Запустите программу на другой ОС, прежде чем обвинять TCP-стек Solaris, или напишите небольшую тестовую программу, которая отправляет 300B / s на удаленный конец (нет необходимости в неблокирующих сокетах, просто отправьте), проверьте любую задержку, это позволит изолировать проблему сети .

Я не разработчик, но предлагаю вам попробовать заменить неблокирующие сокеты мультиплексором ввода-вывода: выберите или опросите или / dev / poll и проверьте, готов ли сокет к записи. Это может изменить поведение вашей программы к лучшему или, в худшем случае, дать вам больше отладки и подсказок о реальной проблеме.

На таких больших расстояниях все пакеты, вероятно, используют разные маршруты, проходя через разные AS, поэтому никто не может реально оценить качество сети. Пакет может занять много времени, чтобы прибыть и быть подтвержденным из-за проблемы где-то глубоко в Интернете (хотя это, вероятно, рядом, иначе люди сообщили бы о ней и исправили ее), попробуйте присоединиться из / в других местах. Если для подтверждения одного пакета требуется много времени, окно TCP застревает, и дальнейшие данные могут не обрабатываться. Вы можете попробовать настроить размер окна TCP на большее значение.

Кроме того, вы можете просто запустить mtr чтобы быстро проверить качество сети. Запустите его несколько раз, так как пакеты могут идти разными путями.

Надеюсь, это как-то помогло: /