Прокачуємо мережевий стек для iSCSI

Статтю було написано 29 травня 2011 р. Перенесено зі старого блогу.

Все починається з того, що мережева підсистема більшості дистрибутивів у тому числі і OpenFiler'a, що використовується як iSCSI-Target'a, оптимізована для великого спектру застосувань. У нашому випадку, для взаємодії хостів (Proxmox або XenServer) із загальним мережевим сховищем за протоколом iSCSI потрібні швидкі мережеві канали з мінімальним часом відгуку.

Використовуючи 1G Ethernet ми за більшим рахунком (порівняно з FC) не отримуємо широких каналів і особливо прийнятного, критичного для ВМ часу відгуку. У такому разі, упираючись у продуктивність мережного обладнання, залишається тільки спробувати оптимізувати роботу мережевих протоколів, для отримання максимального ефекту від того, що маємо:)

Збільшення MTU мережевих контролерів

Збільшення MTU (Maximum Transmission Unit) до 9000 байт дозволить мережевим контролерам пропускати наддовгі Ethernet-кадри (Jumbo-кадри)

У RedHat-подібних дистрибутивах (OpenFiler, XenServer) це робиться у файлі налаштувань конкретної мережевої картки (/etc/sysconfig/network-scripts/ifcfg- де ім'я пристрою, зазвичай eth0, eth1 і т.д.). Змінюємо стандартне значення MTU=1500 на MTU=9000.

Це збільшить розмір даних, що передаються за раз (максимальний розмір блоку), що значно підвищить продуктивність в залежності від типу трафіку т.к розмір блоку встановлюється на канальному рівні моделі OSI прозоро для високорівневих протоколів (NFS, iSCSI, CIFS та інші)

Мережеві параметри ядра Linux

Список найбільш важливих параметрів ядра, що стосуються ефективності та продуктивності мережі; net.core.somaxconn = 256 (за замовчуванням 128 ) — Максимальна кількість відкритих сокетів, які чекають на з'єднання. Має сенсзбільшити значення за більшої кількості сполук. Для високо навантажених серверів рекомендують значення в районі 15000-20000.

net.core.rmem_max = 1073741824 (за замовчуванням 124928) — Встановлює максимальний розмір буфера для всіх протоколів.

net.core.wmem_max = 1073741824 (за замовчуванням 124928) — Встановлює максимальний розмір буфера для всіх протоколів. net.ipv4.tcp_reordering = 20 (за замовчуванням 3) Іноді збільшення часу проходження пакета в локальній мережі може вважатися втратою пакета. Для таких випадків збільшення цього параметра підвищує продуктивність.

net.ipv4.tcp_rmem = 1048576 16777216 1073741824 (за замовчуванням 4096 87380 937024) Відповідно мінімум, за умовчанням і максимум. Змінна у файлі tcp_rmem містить 3 цілих числа, що визначають розмір приймального буфера сокетів TCP.Мінімум: кожен сокет TCP має право використовувати цю пам'ять за фактом свого створення. Можливість використання такого буфера гарантується навіть при досягненні порогу обмеження (moderate memory pressure). Розмір мінімального буфера за замовчуванням складає 8 Кбайт (8192).За замовчуванням: кількість пам'яті, допустима для буфера передачі сокету TCP за замовчуванням. Це значення застосовується замість параметра /proc/sys/net/core/rmem_default, який використовується іншими протоколами. Значення буфера, що використовується за замовчуванням, зазвичай (за замовчуванням) становить 87830 байт. Це визначає розмір вікна 65535 із заданим за замовчуванням значенням tcp_adv_win_scale і tcp_app_win = 0 трохи менший, ніж визначає прийняте за замовчуванням значення tcp_app_win.Максимум: максимальний розмір буфера, який може бути автоматично виділено для прийому сокету TCP. Це значення не скасовує максимуму, заданого вфайл /proc/sys/net/core/rmem_max. При "статичному" виділенні пам'яті за допомогою SO_RCVBUF цей параметр не має значення. За замовчуванням максимум становить 87380 * 2 байт.

net.ipv4.tcp_wmem = 1048576 16770216 1073741824 (за замовчуванням 4096 16384b937024 ) Змінна у файлі tcp_wmem містить 3 цілочисленних значення, визначальних сокет TCP.

Мінімум: кожен сокет TCP має право використовувати цю пам'ять за фактом свого створення. Розмір мінімального буфера за замовчуванням становить 4 Кбайт (4096)Значення за замовчуванням: кількість пам'яті, допустима для буфера передачі сокету TCP за замовчуванням. Це значення застосовується замість параметра /proc/sys/net/core/wmem_default, який використовується іншими протоколами і зазвичай менше, ніж /proc/sys/net/core/wmem_default. Розмір прийнятого за замовчуванням буфера зазвичай (за замовчуванням) становить 16 Кбайт (16384)Максимум: максимальна кількість пам'яті, яка може бути автоматично виділено для буфера передачі сокету TCP. Це значення не скасовує максимум, заданий у файлі /proc/sys/net/core/wmem_max. При "статичному" виділенні пам'яті за допомогою SO_SNDBUF цей параметр не має значення. За замовчуванням розмір максимального буфера складає 128 Кбайт (131 072).

УВАГА: Максимальні значення параметрів net.ipv4.tcp_rmem, net.ipv4.tcp_wmem не повинні перевищувати значення параметрів net.core.rmem_max та net.core.wmem_max !

net.ipv4.tcp_mem = 1048576 16770216 1073741824 (за замовчуванням 21960 29282 43920) Змінна у файлі tcp_mem містить 3 цілих числа (порога), що визначають відношення.Нижній поріг: при значеннях нижче цього рівняTCP не переймається витратою пам'яті.Поріг обмеження: при досягненні цього порога TCP контролює розмір пам'яті, що виділяється, і переходить в режим memory pressure (нестача пам'яті), з якого виходить при зниженні витрати пам'яті до нижнього порога.Верхній поріг: кількість сторінок пам'яті, доступних для створення черг усіма сокетами TCP. Значення всіх порогів розраховуються під час завантаження операційної системи з урахуванням доступної на комп'ютері пам'яті.

net.ipv4.tcp_window_scaling = 1 (за замовчуванням зазвичай 1) - Активує масштабування вікна, як визначено в RFC 1323; повинен бути включений(1) для підтримки вікон розміром більше 64KB.

net.ipv4.tcp_sack = 1 (за замовчуванням зазвичай 1) - Активує вибіркове підтвердження (selective acknowledgment), яке покращує продуктивність, вибірково підтверджуючи пакети, отримані позачергово (в результаті відправник повторно передає лише пропущені сегменти); повинен бути включений (для великої області мережевих комунікацій), але може посилити використання CPU.

net.ipv4.tcp_fack = 1 (за замовчуванням зазвичай 1) - Включає Forward Acknowledgment (прогнозне підтвердження), яке оперує з вибірковим підтвердженням (SACK - Selective Acknowledgment) для зменшення навантаження; має бути включений(1).

net.ipv4.tcp_timestamps = 1 (за промовчанням зазвичай 1) — Активує обчислення RTT більш достовірним способом (див. RFC 1323), ніж інтервал для повторної передачі; має бути включений для швидкодії.

net.ipv4.tcp_low_latency = 0 (за замовчуванням зазвичай 0) Дозволяє стеку TCP/IP віддавати перевагу низькому часу очікування перед більш високою пропускною здатністю. Ось тут спірний момен. Якщо канали високонавантажені, то краще не включати. Якщо трафік не більший і більш важливий час відгукукраще увімкнути.

Встановити значення наведених вище параметрів можна за допомогою команди: #sysctl -w =

Наприклад: #sysctl -w net.ipv4.tcp_low_latency=1 встановлює нове значення параметра net.ipv4.tcp_low_latency

Зміна значень параметрів за допомогою утиліти sysctl, діють лише до перезавантаження системи. Для встановлення постійних значень необхідно прописати відповідні параметри та їх значення у вайлі /etc/sysctl.conf

Зміна значення перерахованих вище параметрів по-різному але все ж таки впливаю на споживання пам'яті та ресурсів CPU.

Всі перелічені вище параметри не є панацеєю, але певною мірою дозволяють використовувати наявні канали більш ефективно в контексті віртуалізації.