Налаштування параметрів маршрутизації IP для Linux - secret_interval та tcp_mem


30

Сьогодні ми мали невелику проблему з відмовою в одному з наших VAP-апаратів 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] Налаштуйте свій секретний_інтервал!

Шш .. це секрет !!

Це, мабуть, пов'язане з тим, /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 з високим трафіком?

Відповіді:


28

Я ніколи не стикався з цим питанням. Однак, ймовірно, вам слід збільшити ширину таблиці хешу, щоб зменшити її глибину. Використовуючи "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 VM (розмір хеша маршруту регулюється залежно від загальної оперативної пам’яті).

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

Я підозрюю, що ваше повідомлення "з пам'яті сокета" надходить із налаштувань за замовчуванням у 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, дозволяє налаштувати ці параметри з глобальної конфігурації та з боку (клієнт чи сервер).

Я сподіваюся, що це допомагає!


8

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якщо ви дійсно не знаєте , що ви робите. Ті, хто видає ці поради, зазвичай ні. Їх вуду часто неправильне або невідповідне для вашого оточення і не вирішить вашу проблему. Це може навіть погіршити.


1
Коли це відбувається, повідомлення у dmesg відрізняється, ви бачите "занадто багато осиротілих розеток". Однак я згоден з вами, що сироти можуть споживати величезну кількість пам’яті.
Віллі Тарре

При перевищенні кількості у /proc/sys/net/ipv4/tcp_max_orphansвас виникне інша помилка. Наприклад, весь стек Stack Exchange має /proc/sys/net/ipv4/tcp_max_orphans65536 і /proc/net/sockstatпризводить до TCP: використання 2996 сирота 171 tw 15972 alloc 2998 mem 1621 - різницю, яку неможливо ігнорувати.
Джефф Дальгас

-4

Деякі з цих параметрів ми регулярно налаштовуємо. Наш стандарт для високої пропускної здатності та низьких затримок торгових платформ:

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

1
за математику Віллі, що означає, що ваш стандартний тиск в пам'яті # (середнє число) становить 68 ГБ ?! Три рази (rmem, wmem, mem) ??
Джефф Етвуд

10
Ці налаштування помилкові і дуже часто зустрічаються в лавочних середовищах, а потім сліпо копіюються. Вони не матимуть жодних проблем лише за кілька одночасних сеансів, але навіть при 100 TCP-сокетах ви виділите 3,2 ГБ оперативної пам’яті. Поки затримка низька, ви нічого не підозрюєте. Вам просто потрібно відключити віддалену машину під час передачі, щоб побачити заповнення вихідних буферів або заморозити локальне завдання та побачити заповнення буфера вводу. Це божевільно ...
Віллі Тарро

6
Джефф, це не три рази. tcp_mem знаходиться у сторінках і визначає глобальний розмір. tcp_rmem і tcp_wmem знаходяться в байтах і визначають розмір per-socket.
Віллі Тарре

Ці налаштування виглядають неправильно, оскільки для одночасних серверів з невеликими даними ви не хочете резервувати стільки буферів сокет, а tcp_mem повністю відрізняється від r / wmem, використання одних і тих же цифр насправді не має сенсу (один байт на з'єднання, інший сторінки в системі)
eckes
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.