LINUX.ORG.RU
решено ФорумAdmin

Посоветуйте настройки TCP/IP для медленного канала?


0

2

Здраствуйте, Уважаемые!

Прошу помощи в настройке параметров TCP/IP для медленного канала с задержкой обычных пингов в ~200ms. Для оптимизации трафика, я выключаю tcp_timestamps (0). Кроме того, у интерфейса есть особенность — MTU=228 + включена самописная упаковка IP-заголовков (не путать с SLHC, там пакуются IP+TCP). Проблема такая, что в процессе соединения бывают недопустимые по времени затыки, что снижает и так небольшую полосу канала.

Пытался подобрать параметр tcp_congestion_control (cubic, reno, veno, westwood и пр), однако экспериметны только усугубили непонимание того, как бороться с проблемой.

Спасибо.

★★

Может быть вам внешний канал потюнить? Если там протокол с коррекцией ошибок (наподобие X25 или что-нибудь другое с коррекцией V42, например асинхронная модемная связь), то пока там повторные передачи идут для исправления ошибок, ваш tcp продолжает свои повторные передачи и забивает входной буфер внешнего канала. И потом это все долго рассасывается.

Если так, то стоит использовать вместо X25 - Frame Relay, к примеру. Или входной буфер уменьшить. Тогда непереданные пакеты будут отбрасываться и tcp свое отработает, если повезет. Даже уменьшение скорости в полтора-два раза может значительно улучшить связь.

Вообще, что у вас на внешнем канале?

Ну и задержка 200 мс ничего не говорит о пропускной способности канала. О пропускной способности килобиты/сек говорят.

ansky ★★★★★ ()
Ответ на: комментарий от ansky

У меня радио-модемная связь, я использую собственную модификацию SLIP-протокола, т.к. радиостанции работают в широковещательном полу-дуплексном режиме и необходимо обеспечить возможность работы нескольких устройств в общем адресном пространстве. Размер передаваемого в эфир фрейма ограничен 256 байтами. В силу особенностей работы модемов, я кодирую данные в 7-битную кодировку и добавляю в начало каждого фрейма небольшой адресный заголовок, а в конец фрейма — символ 0xFF, являющийся индикацией начала передачи данных для модема. Модемы вяжутся на 19200 Бит/c, однако всё, что мне удалось выжать из канала - это около 4 КБит (100000 байтов передаётся в среднем за 3 минуты, 180 секунд). Сейчас думаю, что возможно ситуацию поможет улучшить LAPB, однако не уверен.

Что скажете, может быть есть лучшее решение? К сожалению, я с X25 и FrameRelay не знаком близко.

i82 ★★ ()

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

visual ★★★ ()
Ответ на: комментарий от i82

Ну дак, LAPB это и есть кусок X25 и Frame Relay.

Может быть есть возможность не гнаться за скоростью и обменять ее на запас надежности. К примеру если использовать скорость 14400 или 9600 то может быть удастся выжать из канала 6-8 кбит/сек?

И вот еще. У вас на интерфейсах, между которыми tcp-соединение устанавливается MTU действительно такой маленький или там на самом деле полтора килобайта? А то может быть у вас фрагментация IP-пакетов происходит? Фрагментации на каналах с потерями нужно избегать, тк это очень сильно увеличивает потери целых пакетов и задержки.

Ну и в вашем случае анонсируемое окно на tcp имеет смысл сделать небольшим, может быть 1 килобайт, не более. Вот смотрите, максимальная скорость у вас 19200, это 2 кбайт/сек, задержка на круг 0.2 сек, стало быть неподтвержденных байт в сети около 400 байт. Если у вас окно больше, то остальные данные торчат во входном буфере канала и в случае потери одного пакета дают только лишнюю задержку. Стало быть окно можно сделать около 500 байт, возможно это будет близко к оптимуму.

Больше ничего не могу сказать.

ansky ★★★★★ ()
Ответ на: комментарий от ansky

> Ну дак, LAPB это и есть кусок X25 и Frame Relay.

Угу, но с LAPB я хотя бы знаком и имел дело :) X25 же вообще не использовал ни разу...

Может быть есть возможность не гнаться за скоростью и обменять ее на запас надежности. К примеру если использовать скорость 14400 или 9600 то может быть удастся выжать из канала 6-8 кбит/сек?


Да, я попробую - это интересная мысль, понизить скорость соединения и повысить надёжность.

И вот еще. У вас на интерфейсах, между которыми tcp-соединение устанавливается MTU действительно такой маленький или там на самом деле полтора килобайта? А то может быть у вас фрагментация IP-пакетов происходит? Фрагментации на каналах с потерями нужно избегать, тк это очень сильно увеличивает потери целых пакетов и задержки.


Нет, уменя MTU действительно такой маленький - 228 (ну или 214, если без сжатия IP-заголовков). Т.е. каждый отправляемый в эфир фрейм является полноценным IP-пакетом, содержащим в себе IP-заголовок + ICMP/TCP/UDP данные. Фрагментации нет, ибо по-сути своей все соединения типа точка-точка. Здесь, кстати, одно из узких мест - много служебных данных в каждом фрейме и я думаю, что есть смысл это как-то оптимизировать путём повышения MTU и разбивки пакетов при отправке на фреймы и склейки их при приёме (тут как раз может работать LAPB).

Ну и в вашем случае анонсируемое окно на tcp имеет смысл сделать небольшим, может быть 1 килобайт, не более. Вот смотрите, максимальная скорость у вас 19200, это 2 кбайт/сек, задержка на круг 0.2 сек, стало быть неподтвержденных байт в сети около 400 байт. Если у вас окно больше, то остальные данные торчат во входном буфере канала и в случае потери одного пакета дают только лишнюю задержку. Стало быть окно можно сделать около 500 байт, возможно это будет близко к оптимуму.


Как играть с окном? Я через sysctl пробовал менять min_adv_mss и tcp_base_mss, это оно и есть или нет?

i82 ★★ ()
Ответ на: комментарий от visual

У меня есть множество территориально распределённых устройств, обединённых в группы и связанных по радио-каналу. В каждой группе ест лидер, который осуществляет сбор информации с подчинённых устройств.

Проблема в том, что:
1) модемы работают в широковещательном режиме в полу-дуплексе
2) максимальный размер фрейма в эфире 256 байт
Отсюда следует, что при приёме данные с разных устройств могу смешиваться.

Я модифицировал драйвер slip из ядра изменив структуру потока данных и добавив в него поддержку адресации на уровне фреймов. Т.е. при приёме фрейма проверяется адресное значение в его заголовке и если это фрейм данной группы, то пакет передаётся выше по стеку.

i82 ★★ ()
Ответ на: комментарий от i82

> Здесь, кстати, одно из узких мест - много служебных данных в каждом фрейме и я думаю, что есть смысл это как-то оптимизировать путём повышения MTU и разбивки пакетов при отправке на фреймы и склейки их при приёме

Вот кстати может быть и не стоит. Например если MTU около 450 и вероятность потери одного фрейма 1%, то вероятность потери пакета уже будет 2%. На LAPB перекладывать коррекцию ошибок и переповторы стоит или нет, вопрос сложный. ТСР с этим справляется не хуже.

X25 - протокол был очень хорошо продуманный, на низком уровне корректирует ошибки, но для tcp/ip эта фича избыточна, тк tcp сам прекрасно справляется с коррекцией ошибок. Собственно поэтому frame Relay придумали. В X25 на втором уровне OSI проверяются контрольные суммы и повторно передаются ошибочно переданные фреймы, а в FR на том же втором уровне фреймы проверяются и ошибочно принятые просто отбрасываются и все. Стало быть в FR нет избыточной коррекции ошибок. Кстати в асинхронных модемах коррекция ошибок V42 работает по тому же принципу, как в X25. Вот LAPB это и есть второй уровень OSI.

Играть с окном, насколько я понимаю, примерно так: http://www.ibm.com/developerworks/linux/library/l-hisock/index.html

ansky ★★★★★ ()
Ответ на: комментарий от ansky

> Вот кстати может быть и не стоит. Например если MTU около 450 и вероятность потери одного фрейма 1%, то вероятность потери пакета уже будет 2%. На LAPB перекладывать коррекцию ошибок и переповторы стоит или нет, вопрос сложный. ТСР с этим справляется не хуже.

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

X25 - протокол был очень хорошо продуманный, на на низком уровне корректирует ошибки, но ...

Я правильно понимаю вашу мысль, что TCP/IP может эффективно решать данную задачу и основной вопрос всё-таки в его корректной настройке?

За ссылку спасибо.

i82 ★★ ()
Ответ на: комментарий от i82

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

Вот в том то и проблема, что пока LAPB справляется с коррекцией ошибок, tcp уже начнет передавать неподтвержденные данные повторно и тем самым забьет входной буфер внешнего канала. Получается, что задержки суммируются.

Это примерно такая же проблема, как с tcp-based-VPN. На столе такое работает, как часы, а на реальных каналах с реальными потерями начинает невыносимо глючить.

ansky ★★★★★ ()
Ответ на: комментарий от ansky

> Вот в том то и проблема, что пока LAPB справляется с коррекцией ошибок, tcp уже начнет передавать неподтвержденные данные повторно и тем самым забьет входной буфер внешнего канала. Получается, что задержки суммируются.

Звучит разумно, вы меня убедили.

Мне удалось поиграть с окном TCP — действительно, изменение этого параметра позволяет добиться лучших результатов. Я проверял на значениях 256, 512, 1024, 2048 и 4096 (например, tcp_rmem=«256 256 256» и tcp_wmem=«256 256 256»). К моему удивлению, из этих значений результат оказался лучшим на размере окна 4096. Вот примерно что получается после анализа TCP-потока передачи файла:

Throughput:
.... http://imageshack.us/photo/my-images/15/snapshot1fr.png/

Time/Sequence:
.... http://imageshack.us/photo/my-images/232/snapshot11p.png/

Кроме того, для TCP устанавливаю:
.... tcp_sack=0
.... tcp_timestamps=0
Это позволяет избежать передачи опций TCP, и в сумме со сжатием IP-заголовка даёт экономию в пару десятков байтов на 256-байтный фрейм.

i82 ★★ ()

Результаты экспериментов

Удалось добиться существенных результатов :)

Итак, настройки TCP:
.... tcp_sack=0 (отключение выборочных подтверждений)
.... tcp_timestamps=0 (отключение временных отметок)
.... tmp_wmem=«5120 5120 5120» (размеры буферов на отправку)

Из настроек IP отмечу, что применяется сжатие IP-заголовков. Вместо 20 байтов передаётся 6, тем самым MTU повышается на 14 байтов.

В результате, файл объёмом 500.000 байтов передаётся из одного конца в другой за 8m50s, что соответствует пропускной способности для данных в 940 байт/с, или около 7.5 КБит/c. Это почти в 2 раза выше, того что было в начале :)

Throughput:
.... http://imageshack.us/photo/my-images/64/rtt51208m50s.png/
Time/Sequence:
.... http://imageshack.us/photo/my-images/88/throughput51208m50s.png/

Открытым для меня остаётся вопрос, каким образом рассчитывать величину буфера? В моём случае, RTT для максимально-заполненного фрейма (256 байтов) составляет 0.500с, тогда как ширина радио-канала 19200 Бит/с. Соответственно, BDP = 19200 * 0.5 / 8 = 1200 байт. Это, я так понимаю, оптимальное число байтов, которые должны находиться в канале.

Но откуда 5120? И да, достигнута ли граница пропускной способности?

i82 ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.