Как были определены эти настройки Linux TCP по умолчанию?


13

Я потратил довольно много времени на то, чтобы отследить проблему на производстве, когда исчезновение сервера базы данных может привести к зависанию до 2 часов (долгое ожидание poll()вызова в клиентской библиотеке libpq) для подключенного клиента. Углубившись в проблему, я понял, что эти параметры ядра должны быть скорректированы до минимума, чтобы разорванные TCP-соединения были замечены своевременно:

net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_retries2 = 15

Четыре значения выше взяты из машины с Ubuntu 12.04, и похоже, что эти значения по умолчанию не отличаются от текущих значений по умолчанию для ядра Linux .

Эти настройки, кажется, сильно смещены в сторону сохранения существующего соединения открытыми и чрезвычайно скупы на пробные сообщения проверки активности. AIUI, значение tcp_keepalive_timeпо умолчанию, равное 2 часам, означает, что, когда мы ожидаем ответа для удаленного хоста, мы будем терпеливо ждать в течение 2 часов, прежде чем запустить проверку активности, чтобы убедиться, что наше соединение все еще действует. И затем, если удаленный хост не отвечает на тест активности активности, мы повторяем эти тесты активности 9 раз ( tcp_keepalive_probes) с интервалом 75 секунд ( tcp_keepalive_intvl), так что это дополнительные 11 минут, прежде чем мы решим, что соединение действительно разорвано.

Это соответствует тому, что я видел в поле: например, если я запускаю psqlсеанс, подключенный к удаленному экземпляру PostgreSQL, с некоторым запросом, ожидающим ответа, например

SELECT pg_sleep(30);

и затем, когда удаленный сервер умирает ужасной смертью (например, отбрасывает трафик на эту машину), я вижу, что мой psql-сеанс ждет до 2 часов и 11 минут, прежде чем он обнаружит, что его соединение разорвано. Как вы можете себе представить, эти настройки по умолчанию вызывают серьезные проблемы для кода, с которым мы общаемся в базе данных, например, при сбое базы данных. Отключение этих ручек очень помогло! И я вижу, что я не одинок в том, что рекомендую скорректировать эти значения по умолчанию.

Итак, мои вопросы:

  • Как долго значения по умолчанию были такими?
  • Каково было исходное обоснование для того, чтобы сделать эти настройки TCP настройками по умолчанию?
  • Какие-нибудь дистрибутивы Linux меняют эти значения по умолчанию?

И любая другая история или взгляд на обоснование этих настроек будут оценены.


Некоторая соответствующая информация здесь ... tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
Драв Слоан

Обратите внимание , что вы можете изменить первые три за соединение в коде клиента с параметрами сокетов TCP_KEEPIDLE, TCP_KEEPCNTи TCP_KEEPINTVL.
Внуаз

1
@wnoise, на самом деле, начиная с Linux 2.6.37, также должна быть возможность указать опцию сокета TCP_USER_TIMEOUT, вместо настройки net.ipv4.tcp_retries2всей системы. Конечно, многие приложения (такие как PostgreSQL в моем примере здесь) еще не поддерживают TCP_USER_TIMEOUT.
Джош Купершмидт

Ответы:


6

RFC 1122 указывает в разделе 4.2.3.6, что период поддержания активности не должен по умолчанию составлять менее двух часов.


1
Хорошо, спасибо, что выкопали это. Я думаю, что это в основном отвечает на вопрос о том, почему по tcp_keepalive_timeумолчанию 7200, хотя я все еще был бы заинтересован в прецеденте / объяснении для других трех соответствующих настроек.
Джош Купершмидт

Удаление Моего ответа, поскольку это отвечает на вопрос (по крайней мере, для одного из значений)
coteyr

1
@coteyr Спасибо в любом случае, я ценю усилия. В вашем ответе IIRC содержался интригующий комментарий, в котором говорилось, что в более ранних версиях Linux по умолчанию было 15 минут. Мне было бы интересно узнать, как / почему это было изменено на 2 часа или на 15 минут.
Джош Купершмидт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.