Темы
Критерии выбора планировщика ввода-вывода для HDD и SSD
Оптимизация дисковой подсистемы
SYSCTL
Оптимизация сетевых интерфейсов
Критерии выбора планировщика ввода-вывода для HDD и SSD
1. Общие принципы
Для HDD (жёстких дисков)
HDD имеют механические ограничения (головки, вращение диска), поэтому планировщик должен:
- Минимизировать перемещение головки (уменьшить seek time).
- Объединять запросы (merging, elevator алгоритмы).
- Балансировать задержки и пропускную способность.
Для SSD (твердотельных накопителей)
SSD не имеют механических ограничений, но у них:
- Ограниченное число циклов записи.
- Параллельные очереди (в NVMe — тысячи).
- Низкие задержки доступа.
Планировщик должен:
- Минимизировать накладные расходы (лучше none или kyber).
- Не пытаться "оптимизировать" seek time (он не нужен).
2. Доступные планировщики в Linux (актуальные)
Планировщик | Лучше для | Особенности | HDD | SSD/NVMe |
mq-deadline | Серверы, СУБД | Гарантирует deadlines (предсказуемые задержки) | ДА | (не всегда) |
bfq | Десктоп, мультимедиа | Fair-queue (честное распределение между процессами) | ДА | (неэффективен) |
kyber | SSD/NVMe | Адаптивный, низкие задержки | НЕТ | ДА |
none | NVMe | Прямой доступ к железу (нет планировщика) | НЕТ | ДА (лучший для NVMe) |
3. Критерии выбора для HDD
Когда выбирать mq-deadline?
- Серверы (MySQL, PostgreSQL, виртуалки) – даёт предсказуемую производительность.
- Высокая многопоточная нагрузка – хорошо балансирует между процессами.
- Торренты + веб-сервер – лучше, чем bfq, если важна пропускная способность.
Когда выбирать bfq?
- Десктоп / интерактивные задачи – гарантирует, что фоновая нагрузка (торренты) не "задушит" систему.
- Мультимедиа (стриминг, запись видео) – минимизирует лаги.
- Не нужны для HDD (разработаны для SSD/NVMe).
4. Критерии выбора для SSD/NVMe
Когда выбирать none?
- NVMe-диски – у них свои hardware-очереди, планировщик ядра только мешает.
- Высоконагруженные серверы – минимум накладных расходов.
Когда выбирать kyber?
- SATA SSD – если none недоступен.
- Низкие задержки важнее пропускной (например, веб-сервер).
Когда mq-deadline?
- Если kyber нестабилен (редко).
- Смешанная нагрузка (HDD + SSD в одном массиве).
Когда bfq?
- Не рекомендуется для SSD – создаёт лишние накладные расходы.
5. Как проверить, что работает?
- Код: выделить все
# Текущий планировщик
cat /sys/block/sdX/queue/scheduler
Задержки (iostat)
iostat -x 1
Нагрузка на диск (iotop)
iotop -o
Если сомневаетесь:
- HDD → mq-deadline
- SSD → kyber
- NVMe → none
Оптимизация дисковой подсистемы
Определяем текущий планировщик ввода-вывода для всех SATA дисков sda, sdb, sdc
cat /sys/block/sd[a-c]/queue/scheduler
- Код: выделить все
none mq-deadline kyber [bfq]
none mq-deadline kyber [bfq]
none mq-deadline kyber [bfq]
Если присутствуют диски nvme то посмотреть используемый ими планировщик можно так:
cat /sys/block/nvme*/queue/scheduler
- Код: выделить все
[none] mq-deadline kyber bfq
/etc/udev/rules.d/60-ioschedulers.rules
- Код: выделить все
# Для HDD
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="mq-deadline"
Для SSD (если нужно)
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="kyber"
Если нужно сослаться на конкретный диск, то можно это сделать по его серийному номеру. Для примера воспользуемся атрибутом D_SERIAL_SHORT. Подобные настройки желательно делать на нагруженных дисках, например гипервизор, СУБД. Определим его значение:
- Код: выделить все
udevadm info --name=/dev/sda | grep -E '(WWN|SERIAL)'
S: disk/by-id/wwn-0x50014ee1af672166
E: ID_SERIAL=WDC_WD20EARX-00PASB0_WD-WCAZAH446734
E: ID_SERIAL_SHORT=WD-WCAZAH446734
E: ID_WWN=0x50014ee1af672166
E: ID_WWN_WITH_EXTENSION=0x50014ee1af672166
E: DEVLINKS=/dev/disk/by-diskseq/1 /dev/disk/by-path/pci-0000:02:00.1-ata-3.0 /dev/disk/by-id/wwn-0x50014ee1af672166 /dev/disk/by-path/pci-0000:02:00.1-ata-3 /dev/disk/by-id/ata-WDC_WD20EARX-00PASB0_WD-WCAZAH446734
Вместо IDNAME указать например ID_SERIAL_SHORT и в кавычках сам серийник:
- Код: выделить все
ACTION=="add|change", SUBSYSTEM=="block", ENV{ID_SERIAL_SHORT}=="WD-WCAZAH446734", ATTR{queue/scheduler}="mq-deadline"
Для гостевой ВМ желательно отключить планировшик:
- Код: выделить все
ACTION=="add|change", SUBSYSTEM=="block", KERNEL=="vda", ATTR{queue/scheduler}="none"
Следующая команда перезагрузит правила, гарантируя, что udev усвоит изменения.
- Код: выделить все
udevadm control --reload-rules
Если вам нужно, чтобы изменения были применены к уже подключенным устройствам, вам необходимо активировать правила
- Код: выделить все
udevadm trigger --type=devices --action=change
SYSCTL
cat /etc/sysctl.d/30-network.conf
- Код: выделить все
# Включение IP Forwarding
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
# Локальная маршрутизация (route_localnet)
net.ipv4.conf.enp42s0.route_localnet = 1
# net.ipv4.conf.wlo1.route_localnet = 1
# Защита от IP spoofing
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
# Логирование подозрительных пакетов
net.ipv4.conf.all.log_martians = 1
# Значения TTL для IPv4
net.ipv4.ip_default_ttl = 65
cat /etc/sysctl.d/40-ipv6.conf
- Код: выделить все
# Privacy Extensions для IPv6
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
net.ipv6.conf.enp42s0.use_tempaddr = 2
cat /etc/sysctl.d/50-tcp.conf
- Код: выделить все
# Размеры буферов TCP
net.ipv4.tcp_rmem = 1048576 16777216 1073741824
net.ipv4.tcp_wmem = 1048576 16777216 1073741824
net.core.rmem_max = 1073741824
net.core.wmem_max = 1073741824
# Очереди и лимиты соединений
net.core.netdev_max_backlog = 100000
net.core.somaxconn = 65000
net.ipv4.tcp_max_syn_backlog = 65000
net.ipv4.tcp_max_orphans = 51232
net.ipv4.tcp_max_tw_buckets = 4098560
# Таймауты и Keepalive
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_fin_timeout = 20
net.ipv4.tcp_orphan_retries = 1
# Опции производительности
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_fack = 1
net.ipv4.tcp_dsack = 1
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_reordering = 20
net.ipv4.tcp_ecn = 0
net.ipv4.tcp_syncookies = 0
# Локальные порты
net.ipv4.ip_local_port_range = 1024 65535
cat /etc/sysctl.d/60-memory.conf
- Код: выделить все
# Swappiness и кэш
vm.swappiness = 0
vm.vfs_cache_pressure = 1000
vm.overcommit_memory = 1
# Dirty pages
vm.dirty_background_ratio = 5
vm.dirty_ratio = 15
vm.min_free_kbytes = 327887
# Общая память TCP
net.ipv4.tcp_mem = 1048576 16770216 1073741824
cat /etc/sysctl.d/70-kernel.conf
- Код: выделить все
# Настройки планировщика
kernel.sched_autogroup_enabled = 0
# Shared memory
kernel.shmmax = 30218102784
kernel.shmall = 8197185
# Логирование и дампы
kernel.printk = 4 4 1 7
kernel.core_uses_pid = 1
kernel.sysrq = 0
kernel.msgmax = 65536
kernel.msgmnb = 65536
fs.suid_dumpable = 2
# Лимиты файлов
fs.file-max = 2049280
fs.inotify.max_user_watches = 65536
Оптимизация сетевых интерфейсов в Linux
Оптимизация сети включает настройку буферов, очередей, аппаратных оффлоадов и параметров ядра. Ниже — детальный разбор для серверов и высоконагруженных систем.
- Определение текущих настроек
Перед тюнингом проверьте:- Код: выделить все
# 1. Список интерфейсов
ip -br link show
# 2. Текущие параметры буферов RX/TX
ethtool -g eth0
# 3. Поддерживаемые оффлоады
ethtool -k eth0
# 4. Статистика ошибок
ethtool -S eth0 | grep -i error
# 5. Параметры ядра
sysctl -a | grep -E 'net.core|net.ipv4.tcp'
- Настройка буферов (Ring Buffers)
Ring Buffers — это аппаратные очереди для приёма (RX) и передачи (TX) пакетов.
Как проверить текущие значения?- Код: выделить все
ethtool -g eth0
Вывод:- Код: выделить все
Ring parameters for eth0:
Pre-set maximums:
RX: 4096 # Максимальный RX-буфер
RX Mini: 0
RX Jumbo: 0
TX: 4096 # Максимум TX-буфер
Current hardware settings:
RX: 512 # Текущий RX
TX: 256 # Текущий TX
Как увеличить буферы?- Код: выделить все
sudo ethtool -G eth0 rx 4096 tx 4096
Рекомендации:- Для 1G сетей: RX/TX = 2048–4096.
- Для 10G+ сетей: RX/TX = 8192–16384 (если драйвер поддерживает).
Важно: Если команда возвращает Operation not supported, буферы фиксированы (часто на дешёвых NIC или виртуальных интерфейсах). - Настройка аппаратных оффлоадов
Аппаратные оффлоады разгружают CPU, передавая задачи сетевой карте.
Включение оффлоадов
Разгружаем checksum и сегментацию- Код: выделить все
sudo ethtool -K eth0 tx-checksum-ip-generic on
sudo ethtool -K eth0 rx-checksum on
sudo ethtool -K eth0 tso on gso on gro on lro off
# Для NVMe-over-Fabrics/RDMA (если нужно)- Код: выделить все
sudo ethtool -K eth0 rx-udp-gro-forwarding on
Проверка- Код: выделить все
ethtool -k eth0 | grep -E 'tso|gro|gso'
- Настройка очередей (Queues) распределяет нагрузку по ядрам CPU.
RSS (Receive Side Scaling)
Проверить текущее количество очередей- Код: выделить все
ethtool -l eth0
Установить максимум (если поддерживается)- Код: выделить все
sudo ethtool -L eth0 combined 8
RPS/XPS (Software-based Queuing). Если RSS недоступен, используйте RPS/XPS:
Включить RPS (для RX-очередей)- Код: выделить все
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus # f = все ядра (0-3)
Включить XPS (для TX-очередей)- Код: выделить все
echo 1 > /sys/class/net/eth0/queues/tx-0/xps_cpus
- Оптимизация параметров ядра
Чуть выше описаны оптимизированные настройки параметров ядра - IRQ Balance и CPU Affinity
Закрепление прерываний на конкретные ядра снижает конкуренцию за ресурсы.
Определение IRQ для интерфейса- Код: выделить все
grep eth0 /proc/interrupts | awk '{print $1}' | cut -d: -f1
Закрепление на ядра
Например, закрепить IRQ 42 на ядро 0- Код: выделить все
echo 1 > /proc/irq/42/smp_affinity
Автоматический балансировщик- Код: выделить все
systemctl enable irqbalance
systemctl start irqbalance
- Проверка результата
Мониторинг нагрузки
nload eth0 # Трафик в реальном времени
ethtool -S eth0 # Статистика ошибок
sar -n DEV 1 # Пакеты/ошибки
Критерии успеха- Нет ошибок (dropped, overruns) в ethtool -S.
- Нет перегрузки CPU (top, htop).
- Хорошая пропускная способность (iperf3).