Зміна значення TCP RTO в Linux


12

Я хочу змінити значення TCP RTO (тайм-аут повторної передачі) для з’єднання, і деяке читання, яке я зробив, говорить про те, що я міг би це зробити, але не розкриває, де і як це змінити.

Я переглянув /proc/sys/net/ipv4змінні, але жодна зі змінних не пов'язана з RTO. Буду вдячний, якщо хтось може сказати мені, як змінити це значення.


Це не працює для мене. Як мінімум, включаючи 'ms' з часом rto, дає мені помилку! Я отримав команду працювати, але ss -i говорить інакше. Крім того, 2 системи sctctl не існують. Я працюю на ядрі 4.4
Марк Сегер

Я спробував новіший дистрибутив і ip route replaceнатомість мав успіх, але замість цього ip routeсинтаксис трохи змінився. Мені вдалося зробити модифікацію успішно. Зауважимо, ви повинні прокоментувати відповідь, а не питання, чи хочете ви пінг - я в основному бачив це випадково, чиста удача, що це було недавно :)
Адам C

Відповіді:


30

Причина, по якій ви не можете конкретно змінити RTO, полягає в тому, що це не є статичним значенням. Натомість (за винятком початкового SYN, природно), він базується на RTT (час туди і назад) для кожного з'єднання. Власне, він заснований на згладженій версії RTT та дисперсії RTT з деякими константами, кинутими в суміш. Отже, це динамічне, обчислене значення для кожного з'єднання TCP, і я настійно рекомендую цю статтю, яка детальніше розглядає обчислення та RTO загалом.

Також актуальною є RFC 6298, де зазначено (серед багатьох інших):

Щоразу, коли RTO обчислюється, якщо вона менша за 1 секунду, RTO ОБОВ'ЯЗКОВО повинен бути округлий до 1 секунди.

Чи завжди ядро ​​встановлює RTO на 1 секунду? Ну, за допомогою Linux ви можете показати поточні значення RTO для відкритих підключень, запустивши ss -iкоманду:

State       Recv-Q Send-Q                                                  Local Address:Port     Peer Address:Port
ESTAB       0      0                                                           10.0.2.15:52861   216.58.219.46:http
     cubic rto:204 rtt:4/2 cwnd:10 send 29.2Mbps rcv_space:14600
ESTAB       0      0                                                           10.0.2.15:ssh          10.0.2.2:52586
     cubic rto:201 rtt:1.5/0.75 ato:40 cwnd:10 send 77.9Mbps rcv_space:14600
ESTAB       0      0                                                           10.0.2.15:52864   216.58.219.46:http
     cubic rto:204 rtt:4.5/4.5 cwnd:10 send 26.0Mbps rcv_space:14600

Наведене вище - це вихід з VM, на якому я ввійшов у SSH і має пару з’єднань, відкритих для google.com. Як бачите, RTO насправді встановлений на 200-іш (мілісекунд). Ви зауважите, що воно не округлене до значення 1 секунди від RFC, і ви також можете подумати, що це трохи вище. Це тому, що є мінімальні (200 мілісекунд) та максимум (120 секунд) межі, коли мова йде про RTO для Linux (є чудове пояснення цього в статті, яку я пов’язував вище).

Таким чином, ви не можете змінити значення RTO безпосередньо, але для втрачених мереж (наприклад, бездротових) ви можете спробувати налаштувати F-RTO (це може бути вже включено залежно від вашого дистрибутива). Насправді є два варіанти, пов'язані з F-RTO, які ви можете налаштувати (хороший підсумок тут ):

net.ipv4.tcp_frto
net.ipv4.tcp_frto_response

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

EDIT: перевірка на можливість налаштування rto_min / max значень для TCP з коментарів.

Ви не можете змінити глобальний мінімальний RTO для TCP (як сторону, ви можете зробити це для SCTP - вони виставлені в sysctl), але гарна новина полягає в тому, що ви можете налаштувати мінімальне значення RTO на маршрут основа. Ось моя таблиця маршрутизації на моєму CentOS VM:

ip route
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.2.2 dev eth0

Я можу змінити значення rto_min на маршруті за замовчуванням так:

ip route change default via 10.0.2.2 dev eth0 rto_min 5ms

А тепер моя таблиця маршрутизації виглядає приблизно так:

ip route
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.2.2 dev eth0  rto_min lock 5ms

Нарешті, давайте розпочнемо з’єднання та перевіримо, ss -iчи дотримувались цього:

ss -i
State       Recv-Q Send-Q                                               Local Address:Port                                                   Peer Address:Port   
ESTAB       0      0                                                        10.0.2.15:ssh                                                        10.0.2.2:50714   
     cubic rto:201 rtt:1.5/0.75 ato:40 cwnd:10 send 77.9Mbps rcv_space:14600
ESTAB       0      0                                                        10.0.2.15:39042                                                 216.58.216.14:http    
     cubic rto:15 rtt:5/2.5 cwnd:10 send 23.4Mbps rcv_space:14600

Успіху! Rto на HTTP-з’єднанні (після зміни) становить 15 мс, тоді як з'єднання SSH (до зміни) становить 200+, як і раніше.

Мені насправді подобається такий підхід - він дозволяє встановлювати нижнє значення на відповідних маршрутах, а не глобально, де це може призвести до іншого трафіку. Аналогічно (див. Сторінку ip man ) можна налаштувати початкову оцінку rtt та початкову rttvar для маршруту (використовується під час обчислення динамічного RTO). Хоча це не повне рішення з точки зору налаштування, я думаю, що більшість важливих фрагментів є саме там. Ви не можете налаштувати налаштування максимуму, але я думаю, що це не буде настільки корисним, як правило, у будь-якому випадку.


Дякую @Adam C за уточнення, але ви згадали про мінімум (200 мілі) і макс (120 сек), чи можу я змінити будь-яке з них (хв або макс)? якщо так, то як? ...
obiigbe91

Я вважаю, що вони є константами в коді, і я не знаю, як динамічно їх встановити, але я перекопаю трохи і побачу, оскільки я припускаю, що зміна коду і складання власного ядра трохи більше :)
Адам С

З'ясував, як налаштувати rto_min, і додав його та ще пару пов’язаних речей у відповідь :)
Адам C

Чому немає нічого подібного rto_max? Як ми встановимо глобальний максимальний тайм-аут?
оцінка

Якщо встановити мінімум (або прийняти за замовчуванням), а потім змінити кількість дозволених повторів ( net.ipv4.tcp_retries1і net.ipv4.tcp_retries2або подібних IIRC), я думаю, ви можете отримати еквівалент максимуму RTO.
Адам С
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.