Настройка параметров IP-маршрутизации Linux - secret_interval и tcp_mem

Сегодня у нас была небольшая проблема с отказоустойчивостью на одной из наших виртуальных машин HAProxy. Когда мы копались в этом, мы нашли это:

26 января 07:41:45 ядро ​​haproxy2: [226818.070059] __ratelimit: 10 обратных вызовов подавлено
26 января 07:41:45 ядро ​​haproxy2: [226818.070064] Недостаточно памяти для сокетов
26 января 07:41:47 ядро ​​haproxy2: [226819.560048] Недостаточно памяти для сокетов
26 января 07:41:49 ядро ​​haproxy2: [226822.030044] Недостаточно памяти для сокетов

Что, по этой ссылке, очевидно связано с низкими настройками по умолчанию для net.ipv4.tcp_mem, Таким образом, мы увеличили их в 4 раза по сравнению с их значениями по умолчанию (это Ubuntu Server, не уверен, имеет ли смысл Linux):

текущие значения:    45984   61312   91968
новые значения:       183936  245248  367872

После этого мы начали видеть странное сообщение об ошибке:

26 января 08:18:49 ядро ​​haproxy1: [ 2291.579726] Слишком длинная цепочка хэшей в маршруте!
26 января 08:18:49 ядро ​​haproxy1: [ 2291.579732] Настройте свой secret_interval!

Тсс... это секрет!!

Это, очевидно, связано с /proc/sys/net/ipv4/route/secret_interval по умолчанию 600 и контролирует периодическую очистку кэша маршрутов

secret_interval Указывает ядру, как часто следует удалять ВСЕ записи хэша маршрута независимо от того, насколько они новые / старые. В нашей среде это вообще плохо. Процессор будет занят восстановлением тысяч записей в секунду каждый раз, когда очищается кэш. Однако мы настроили его запуск один раз в день для предотвращения утечек памяти (хотя у нас никогда не было таких).

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

После некоторого расследования мы нашли /proc/sys/net/ipv4/route/gc_elasticity который кажется лучшим вариантом для контроля размера таблицы маршрутов:

gc_elasticity лучше всего описать среднюю глубину сегмента, которую ядро ​​примет до того, как истечет срок действия хеш-записей маршрута. Это поможет сохранить верхний предел активных маршрутов.

Мы скорректировали эластичность с 8 до 4, в надежде, что кеш маршрутов обрежет себя более агрессивно. secret_interval не чувствует себя правильным для нас. Но есть множество настроек, и неясно, какой из них действительно правильный.

  • / proc / sys / net / ipv4 / route / gc_elasticity (8)
  • / proc / sys / net / ipv4 / route / gc_interval (60)
  • / proc / sys / net / ipv4 / route / gc_min_interval (0)
  • / proc / sys / net / ipv4 / route / gc_timeout (300)
  • / proc / sys / net / ipv4 / route / secret_interval (600)
  • / proc / sys / net / ipv4 / route / gc_thresh (?)
  • rhash_entries (параметр ядра, по умолчанию неизвестно?)

Мы не хотим ухудшать маршрутизацию Linux, поэтому боимся возиться с некоторыми из этих настроек.

Кто-нибудь может посоветовать, какие параметры маршрутизации лучше всего настроить для экземпляра HAProxy с высоким трафиком?

3 ответа

Решение

Я никогда не сталкивался с этой проблемой. Однако вам, вероятно, следует увеличить ширину хеш-таблицы, чтобы уменьшить ее глубину. Используя "dmesg", вы увидите, сколько записей у вас в данный момент:

$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)

Вы можете изменить это значение с помощью параметра командной строки загрузки ядра rhash_entries, Сначала попробуйте это вручную, затем добавьте это к своему lilo.conf или же grub.conf,

Например: kernel vmlinux rhash_entries=131072

Возможно, у вас очень ограниченная хеш-таблица, потому что вы выделили мало памяти для вашей виртуальной машины HAProxy (размер хеша маршрута регулируется в зависимости от общего объема ОЗУ).

Что касается tcp_mem, быть осторожен. Ваши начальные настройки заставляют меня думать, что вы работаете с 1 ГБ ОЗУ, 1/3 из которых может быть выделена для сокетов TCP. Теперь вы выделили 367872 * 4096 байт = 1,5 ГБ ОЗУ для сокетов TCP. Вы должны быть очень осторожны, чтобы не исчерпать память. Основное правило - выделить 1/3 памяти для HAProxy, еще одну 1/3 для стека TCP и последнюю 1/3 для остальной части системы.

Я подозреваю, что ваше сообщение "out of socket socket" приходит из настроек по умолчанию в tcp_rmem а также tcp_wmem, По умолчанию для каждого сокета выделено 64 КБ, а для входа - 87 КБ. Это означает всего 300 кБ для прокси-соединения, только для буферов сокетов. Добавьте к этому 16 или 32 кБ для HAProxy, и вы увидите, что с 1 ГБ ОЗУ вы будете поддерживать только 3000 соединений.

Изменяя настройки по умолчанию tcp_rmem а также tcp_wmem (средний параметр), вы можете получить гораздо меньше памяти. Я получаю хорошие результаты с такими низкими значениями, как 4096 для буфера записи и 7300 или 16060 в tcp_rmem (5 или 11 сегментов TCP). Вы можете изменить эти настройки без перезапуска, однако они будут применяться только к новым соединениям.

Если вы предпочитаете не слишком сильно трогать свои sysctl, последняя версия HAProxy, 1.4-dev8, позволяет настраивать эти параметры в глобальной конфигурации и на каждой стороне (клиент или сервер).

Я надеюсь, что это поможет!

Out of socket memory error часто вводит в заблуждение. В большинстве случаев на серверах, подключенных к Интернету, это не указывает на проблемы, связанные с нехваткой памяти. Как я объяснил в более подробном сообщении в блоге, наиболее распространенной причиной является число сокетов-сирот. Сиротский сокет - это сокет, который не связан с дескриптором файла. При определенных обстоятельствах ядро ​​выдаст Out of socket memory error даже если вы в 2 или 4 раза дальше от предела (/proc/sys/net/ipv4/tcp_max_orphans). Это часто происходит в интернет-сервисах и совершенно нормально. Правильный курс действий в этом случае - настроить tcp_max_orphans быть как минимум в 4 раза больше детей-сирот, которых вы обычно видите в своем пиковом трафике.

Не слушайте ни одного совета, который рекомендует тюнинг tcp_mem или же tcp_rmem или же tcp_wmem если вы действительно не знаете, что делаете. Те, кто раздает эти советы, обычно этого не делают. Их вуду часто неправильно или не подходит для вашей среды и не решит вашу проблему. Это может даже сделать хуже.

Мы настраиваем некоторые из этих параметров регулярно. Наш стандарт для торговых платформ с высокой пропускной способностью и низкой задержкой:

net.ipv4.tcp_rmem = 4096 16777216 33554432
net.ipv4.tcp_wmem = 4096 16777216 33554432
net.ipv4.tcp_mem = 4096 16777216 33554432
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 30000
net.core.netdev_max_backlog = 30000
Другие вопросы по тегам