Выбор планировщика ввода-вывода Linux

Я прочитал, что, возможно, возможно изменить планировщик ввода-вывода для определенного устройства на запущенном ядре, написав в /sys/block/ [disk]/queue/scheduler. Например, я могу видеть в своей системе:

[email protected]:~$ cat /sys/block/sda/queue/scheduler 
noop anticipatory deadline [cfq] 

что по умолчанию это полностью справедливый планировщик очередей. Мне интересно, есть ли какие-либо возможности для включения всех четырех планировщиков в мое собственное ядро. Казалось бы, нет большого смысла в том, чтобы скомпилировать более одного планировщика, если ядро ​​не достаточно интеллектуально, чтобы выбрать правильный планировщик для правильного оборудования, в частности, планировщик "noop" для флеш-дисков и один из других для традиционного жесткий диск.

В этом случае?

Ответ 1

Как описано в /usr/src/linux/Documentation/block/switching-sched.txt, планировщик ввода-вывода на любом конкретном блочном устройстве может быть изменен во время выполнения. Может быть некоторая задержка, так как предыдущие запросы планировщика все размываются перед тем, как использовать новый планировщик, но его можно без проблем изменить, даже когда устройство находится в тяжелом режиме.

# cat /sys/block/hda/queue/scheduler
noop deadline [cfq]
# echo anticipatory > /sys/block/hda/queue/scheduler
# cat /sys/block/hda/queue/scheduler
noop [deadline] cfq

В идеале, один планировщик должен удовлетворять всем потребностям. Кажется, он пока не существует. Ядро часто не хватает знаний, чтобы выбрать лучший планировщик для вашей рабочей нагрузки:

  • noop часто является лучшим выбором для блочных устройств с памятью (например, ramdisks) и других невращающихся носителей (flash), где попытка перенести ввод-вывод является пустой тратой ресурсов.
  • deadline - это легкий планировщик, который пытается ограничить задержку
  • cfq пытается поддерживать общесистемную справедливость пропускной способности ввода/вывода

По умолчанию был anticipatory в течение длительного времени, и он получил много настроек, но был удален в 2.6.33 (начало 2010 года). cfq стал по умолчанию некоторое время назад, так как его производительность разумна, и справедливость является хорошей целью для многопользовательских систем (и даже для одиночных настольных компьютеров). Для некоторых сценариев в качестве примеров часто используются базы данных, поскольку они, как правило, уже имеют свои собственные схемы планирования и доступа и часто являются наиболее важным сервисом (так кто же заботится о справедливости?) - anticipatory имеет долгую историю от перестраиваемой для лучшей производительности при этих рабочих нагрузках, а deadline очень быстро передает все запросы на базовое устройство.

Ответ 2

Можно использовать правило udev, чтобы система приняла решение о планировщике, основанном на некоторых характеристиках hw.
Пример правила udev для SSD и других невращательных дисков может выглядеть как

# set noop scheduler for non-rotating disks
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="noop"

внутри нового файла правил udev (например, /etc/udev/rules.d/60-ssd-scheduler.rules). Этот ответ основан на debian wiki

Чтобы проверить, будут ли диски ssd использовать правило, можно заранее проверить атрибут триггера:

for f in /sys/block/sd?/queue/rotational; do printf "$f "; cat $f; done

Ответ 3

Целью поддержки ядра является то, что вы можете попробовать их без перезагрузки; вы можете запустить тестовые рабочие нагрузки через sytsem, измерить производительность, а затем сделать это стандартным для своего приложения.

На современном оборудовании серверного уровня только полезная функция noop оказывается полезной. Остальные кажутся медленнее в моих тестах.

Ответ 4

Вы можете установить это при загрузке, добавив параметр "elevator" в cmdline ядра (например, в grub.cfg)

Пример:

elevator=deadline

Это сделает "крайний срок" планировщиком ввода/вывода по умолчанию для всех блочных устройств.

Если вы хотите запросить или изменить планировщик после загрузки системы или хотите использовать другой планировщик для конкретного блочного устройства, я рекомендую установить и использовать инструмент ioschedset, чтобы упростить это.

https://github.com/kata198/ioschedset

Если вы используете Archlinux, он доступен в aur:

https://aur.archlinux.org/packages/ioschedset

Некоторые примеры использования:

# Get i/o scheduler for all block devices
[[email protected] ~]$ io-get-sched
sda:    bfq
sr0:    bfq

# Query available I/O schedulers
[[email protected] ~]$ io-set-sched --list
mq-deadline kyber bfq none

# Set sda to use "kyber"
[[email protected] ~]$ io-set-sched kyber /dev/sda
Must be root to set IO Scheduler. Rerunning under sudo...

[sudo] password for username:
+ Successfully set sda to 'kyber'!

# Get i/o scheduler for all block devices to assert change
[[email protected] ~]$ io-get-sched
sda:    kyber
sr0:    bfq

# Set all block devices to use 'deadline' i/o scheduler
[[email protected] ~]$ io-set-sched deadline
Must be root to set IO Scheduler. Rerunning under sudo...

+ Successfully set sda to 'deadline'!
+ Successfully set sr0 to 'deadline'!

# Get the current block scheduler just for sda
[[email protected] ~]$ io-get-sched sda
sda:    mq-deadline

Использование должно быть само за себя. Инструменты автономны и требуют только bash.

Надеюсь это поможет!

РЕДАКТИРОВАТЬ: Отказ от ответственности, это сценарии, которые я написал.

Ответ 5

Ядро Linux автоматически не изменяет планировщик ввода-вывода во время выполнения. Под этим я подразумеваю, что ядро ​​Linux на сегодняшний день не может автоматически выбирать "оптимальный" планировщик в зависимости от типа вторичного хранилища. Во время запуска или во время выполнения можно изменить планировщик ввода-вывода вручную.

Планировщик по умолчанию выбирается при запуске на основе содержимого файла, расположенного в /linux -2.6 /block/Kconfig.iosched. Тем не менее, во время выполнения можно изменить планировщик ввода-вывода на echo правильное имя планировщика в файл, расположенный в /sys/block/ [DEV]/queue/scheduler. Например, echo deadline > /sys/block/hda/queue/scheduler