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