В последних версиях ядра Linux была проделана большая работа по решению проблемы работы дисковой подсистемы с новыми, быстрым блочным устройствам. С выходом Linux ядра версии 4.12 у пользователей появилась возможность использовать несколько новых планировщиков (I/O scheduler) для блочных устройств. Эти планировщики основаны на новом способе передачи запросов — multiqueue block layer (blk-mq).
В этой статье я не буду рассматривать особенности работы новых планировщиков, я лишь расскажу как их включить на Ubuntu 18.04.
Статья дополнена 01.12.2020 командами для добавления планировщика kyber
Исходные данные: ОС Ubuntu 18.04 с ядром 4.15;
Задача: Активировать для SSD дисков I/O планировщик mq-deadline, bfq или kyber
В блоге компании Selectel достаточно хорошо описаны новые планировщики, так что рекомендую всем ознакомиться с из статьей.
Так же на habr.ru недавно вышла статья «Последние изменения в IO-стеке Linux с точки зрения DBA», в ней тоже много полезной информации по IO-стеку в Linux и в частности про blk-mq.
Проверим какие ядра у нас есть:
ls -lh /boot | grep -E "config-|initrd.img-|vmlinuz-|System.map-"
Вывод:
-rw-r--r-- 1 root root 213K Nov 26 16:18 config-4.15.0-72-generic -rw-r--r-- 1 root root 56M Nov 26 16:18 initrd.img-4.15.0-72-generic -rw------- 1 root root 3.9M Nov 26 16:18 System.map-4.15.0-72-generic -rw------- 1 root root 8.0M Nov 26 16:28 vmlinuz-4.15.0-72-generic
Проверим текущее ядро:
uname -a
Вывод:
Linux myserver 4.15.0-72-generic #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Проверим наличие в ядре включенной опции CONFIG_BLK_WBT_MQ
cat /boot/config-4.15.0-72-generic | grep CONFIG_BLK_WBT_MQ
Должно показать:
CONFIG_BLK_WBT_MQ=y
Отлично, теперь можно продолжить.
Теперь активируем в ядре multi-queue, для этого в файле /etc/default/grub в параметр GRUB_CMDLINE_LINUX_DEFAULT добавим:
scsi_mod.use_blk_mq=1 dm_mod.use_blk_mq=1
Например у меня строка GRUB_CMDLINE_LINUX_DEFAULT стала такой:
GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 transparent_hugepage=never scsi_mod.use_blk_mq=1 dm_mod.use_blk_mq=1"
у Вас она будет другой, не копируйте мою! Но примерный вид опций Вы поняли какой.
Запишем изменения в загрузчик:
update-grub
Добавим в образ initrd загрузку модулей планировщика mq-deadline и bfq:
echo "mq-deadline" >> /etc/initramfs-tools/modules echo "bfq" >> /etc/initramfs-tools/modules echo "kyber-iosched" >> /etc/initramfs-tools/modules
Обновим образ initrd для всех ядер:
update-initramfs -k all -u
Теперь перезагрузим сервер:
reboot
Проверим наличие новых I/O Scheduler для диска /dev/sda:
cat /sys/block/sda/queue/scheduler
Должно показать:
[none] mq-deadline bfq kyber
Отлично! По-умолчанию у нас активирован планировщик none.
Теперь скорректируем некоторые параметры работы mq-deadline для SSD диска /dev/sda
ВНИМАНИЕ! Перед созданием файла /etc/udev/rules.d/60-schedulers.rules с опциями планировщика Вам нужно убедиться, что в каталоге /etc/udev/rules.d нет уже созданного ранее файла для других планировщиков, иначе в зависимости от последовательности применения файлов у Вас может быть не тот результат который Вы ожидаете. Так же Вам нужно убедиться, что Вы не задавали ранее тип планировщика через файл /etc/default/grub, где в строке GRUB_CMDLINE_LINUX или GRUB_CMDLINE_LINUX_DEFAULT можно указать опцию elevator=XXXXX
Создадим правило для udev (файл 60-schedulers.rules), которое будет устанавливать текущим планировщиком mq-deadline для SSD диска /dev/sda:
echo "ACTION==\"add|change\", KERNEL==\"sda\", ATTR{queue/rotational}=\"0\", ATTR{queue/scheduler}=\"mq-deadline\"" > /etc/udev/rules.d/60-schedulers.rules
Обратите внимание, что мы меняем 2 атрибута — это /sys/block/sda/queue/rotational и /sys/block/sda/queue/scheduler
Можно скорректировать некоторые параметры работы mq-deadline и не только:
echo "ACTION==\"add|change\", KERNEL==\"sda\", ATTR{queue/rq_affinity}=\"2\"" >> /etc/udev/rules.d/60-schedulers.rules echo "ACTION==\"add|change\", KERNEL==\"sda\", ATTR{queue/iosched/fifo_batch}=\"1\"" >> /etc/udev/rules.d/60-schedulers.rules echo "ACTION==\"add|change\", KERNEL==\"sda\", ATTR{queue/iosched/read_expire}=\"100\"" >> /etc/udev/rules.d/60-schedulers.rules echo "ACTION==\"add|change\", KERNEL==\"sda\", ATTR{queue/iosched/writes_starved}=\"4\"" >> /etc/udev/rules.d/60-schedulers.rules
Изменение 4-х параметров выше (queue/rq_affinity, queue/iosched/fifo_batch и т.д.) приведено в качестве примера, не копируйте мои значения если Вы не знаете их назначение.
Описание всех опций и их назначение для deadline, bfq или kyber можно прочитать в официальной документации kernel.org.
Так же полезно почитать заметку о IOSchedulers в официальной Wiki Ubuntu.
Применим параметры:
udevadm control --reload udevadm trigger
Для включения mq-deadline для всех постоянных дисков нужно поменять первую строку в /etc/udev/rules.d/60-schedulers.rules на
ACTION=="add|change", KERNEL=="sd[a-z]|mmcblk[0-9]*|nvme[0-9]*", ATTR{queue/rotational}="0", ATTR{queue/scheduler}="mq-deadline"
После внесения изменений не забываем выполнить пару команд udevadm и проверить активацию выбранного планировщика для диска(ов):
udevadm control --reload udevadm trigger cat /sys/block/sda/queue/scheduler
Если хотим активировать для диска sda планировщик bfq, то выполните (Внимание! файл 60-schedulers.rules будет переписан):
echo "ACTION==\"add|change\", KERNEL==\"sda\", ATTR{queue/rotational}=\"0\", ATTR{queue/scheduler}=\"bfq\"" > /etc/udev/rules.d/60-schedulers.rules
После внесения изменений не забываем выполнить пару команд udevadm и проверить активацию выбранного планировщика для диска(ов):
udevadm control --reload udevadm trigger cat /sys/block/sda/queue/scheduler
Для отладки правил udev можно использовать udevadm с параметром test, например:
udevadm test /sys/block/sda
В выводе Вы можете увидеть много различных правил, а так же Ваше правило 60-schedulers.rules. Так же в выводе будет информация о том, что правило будет применено к определенным устройствам и изменит определенные атрибуты, сокращенный пример вывода:
.... Reading rules file: /etc/udev/rules.d/60-schedulers.rules .... probe /dev/sda raid offset=0 ATTR '/sys/devices/pci0000:00/0000:00:10.0/host32/target32:0:0/32:0:0:0/block/sda/queue/scheduler' writing 'mq-deadline' /etc/udev/rules.d/60-schedulers.rules:1 ....
На этом все, до скорых встреч. Если у Вас возникли вопросы или Вы хотите чтобы я помог Вам, то Вы всегда можете связаться со мной разными доступными способами.
Профессионально занимаюсь системным администрированием Linux -серверов и баз данных (MySQL, POstgreSQL) на протяжении последних 24 лет.
А зачем нужно добавлять эти модули в initramfs, что это даст? Почему бы не ограничиться добавлением в /etc/
modules?
Затем што выбор планировщика задаётся до загрузки модулей.
Это или статиком их пересобирать в ядре или в инитрамфс совать.
На самом деле можно добавить нужные модули в /etc/
modules, только правильно будет добавить каждый модуль в свой файл в каталог /etc/modules-load.d/ в xxx.conf файлы, например:
и не добавлять их в образ initrd и все будет работать, но после перезагрузки как и в случае добавления в образ initrd.
Просто если добавлять модули в образ initrd, то эти модули будут доступны на раннем этапе загрузки linux-ядра со всеми вытекающими плюсами.