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

Настройка параметров 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 с высоким трафиком?

решение1

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

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

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

Надеюсь, это поможет!

решение2

Часто 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если выДействительноЗнайте, что вы делаете. Те, кто дает такие советы, обычно этого не делают. Их вуду часто неправильно или не подходит для вашей среды и не решит вашу проблему. Это может даже ухудшить ее.

решение3

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

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

Связанный контент