Статья внаглую скопипизжена отсюда: https://sites.google.com/site/linuxoptimization/home/nastrojka-io-sheduler
Noop I/O Scheduler
NOOP планировщик является самым базовым из доступных планировщиков. Он не выполняет каких сортировок, только основные слияния. Он используется для специализированных устройств, которые не требуют сортировки их запросов.
Deadline I/O Scheduler
Deadline I/O Scheduler хранит отсортированную очередь, и вводит две дополнительные очереди: FIFO очередь на чтение и FIFO очередь на запись. Записи в каждой из этих очередей отсортированы по времени поступления (фактически, первый вошел -
первый вышел). Каждому запросу в очереди FIFO назначено время окончания. Для очереди запросов чтения - это 500 миллисекунд. Для очереди запросов записи - это пять секунд. При поступлении нового I/O запроса, он вставляется-сортируется в стандартную очередь и помещается в конец соответствующей (на чтение или запись) FIFO очереди.
Как правило, к жесткому диску посылаются запросы ввода/вывода с головы стандартной отсортированной очереди. Это максимизирует общую пропускную способность при минимизации операций поиска и установки головок на диске, так как нормальная очередь сортируется по номеру блока (как и с Linus Elevator). Когда у записи вначале списка одной из дополнительных FIFO очередей истечет назначенное время, I/O scheduler останавливает обработку I/O запросов из стандартной очереди, и начинает обслуживание запросов из этой FIFO очереди. I/O scheduler проверяет и обрабатывает запросы только с головы очереди, где находятся старейшие запросы.
Таким образом, Deadline I/O Scheduler поддерживает эффективную общую пропускную способность без голодания какого-либо одного запроса недопустимо длительное время. Проблема writes-starving-reads сводится к минимуму.
Anticipatory (упреждающий) I/O Scheduler
Проблема предыдущих планировщиков ввода/вывода вновь вытекает из зависимости: каждый новый запрос на чтение выдается только тогда, когда предыдущий будет возвращен, но к тому времени, когда приложение получает прочитанные данные и посылает следующий запрос на чтение, I/O планировщик уже начал обслуживание других запросов. В этом случае планировщик
ввода/вывода в течении некоторого времени мог бы подождать поступление следующего запроса на чтение. Именно так и работает Anticipatory I/O Scheduler. Он основан на Deadline I/O Scheduler с добавлением механизма ожидания, до шести миллисекунд, следующего чтения. Если 6-ть миллисекунд истекли, но запроса на чтение не поступило, планировщик возвращается к работе, которую выполнял до этого (например, обслуживание стандартной отсортированной очереди).
CFQ IO Scheduler
В CFQ каждому процессу присваивается собственная очередь, и каждой очереди присваивается квант времени (timeslice). Планировщик ввода/вывода по кругу обходит каждую очередь и обслуживает запросы из очереди до тех пор, пока не будет исчерпан лимит времени (timeslice) или не останется запросов в этой очереди. В последнем случае CFQ планировщик будет ждать, по умолчанию 10-мс, нового запроса из очереди. Если ожидание было напрасным, то планировщик переходит к следующей очереди.
В рамках каждой очереди процесса, синхронизированные запросы (как, например, читающие) имеют приоритет над
несинхронизированными запросами. Таким образом, CFQ способствует чтению и предотвращает проблему
writes-starving-reads.
CFQ планировщик хорошо подходит для большинства задач.
в ядрах 2.6.32 и новее можно немного повысить производительность на сервере путём отключения low latency , включенного по умолчанию, которое снижает пиковую производительность, но повышает отзывчивость, нужную только для десктопа.
отключить
echo 0 > /sys/class/block/<device name>/queue/iosched/low_latency
________________________________________________
посмотреть используемый планировщик
cat /sys/block/<HDD>/queue/scheduler
если выбран метод anticipatory, то на выводе будет показано следующее:
noop [anticipatory] deadline cfq
Чтобы заменить его на cfq (например), делаем следующее:
echo cfq > /sys/block/<HDD>/queue/scheduler
и если мы еще раз выведем содержимое файла, то увидим:
noop anticipatory deadline [cfq]
добавьте
echo cfq > /sys/block/<HDD>/queue/scheduler
в /etc/rc.d/rc.local
или при сборке ядра выберите планировщик в
Enable the block layer --->IO Schedulers --->XXX I/O scheduler поддержка желаемых планировщиков
Enable the block layer --->IO Schedulers --->Default I/O scheduler планировщик, который будет использоваться по умолчанию
BFQ IO Scheduler
Планировщик BFQ (Budget Fair Queueing I/O Scheduler) создан как замена CFQ (и основан на его коде), основная мысль – более честное разделение I/O между процессами.
Он существует пока в beta-варианте и в официальную поставку ядра не включен. Однако, патч вполне стабилен и лично у меня никаких проблем не вызвал.
Работает планировщик отлично – тормоза GUI во время активной работы с диском фоновых процессов (например, загрузки виртуальной машины или обновления дерева portage) просто как рукой сняло.
Патчи можно взять здесь
http://feanor.sssup.it/~fabio/linux/bfq/patches/
Последняя поддерживаемая версия ядра по ссылке – 2.6.30
для ядра 2.6.31, 2.6.32, 2.6.34 по ссылкам дальше
Скачиваем патчи
Переходим в /usr/src/linux
Патчим:
patch -p1 < BFQ-2.6.32.patch
make menuconfig
Block layer -> I\O schedulers ставим BFQ=m (модуль - для теста - дальше можно прямо в ядро), сохраняемся, выходим,собираем.
modprobe bfq-iosched
Проверяем, загрузился ли модуль:
cat /sys/block/<HDD>/queue/scheduler, должно быт что-то вроде
no-op [cfq] bfq
Включаем:
echo «bfq» > /sys/block/<HDD>/queue/scheduler
Снова проверяем, изменился ли планировщик.
Радуемся увеличению производительности.
P.S.
патч для 2.6.32 ядра имеем благодаря georgy http://www.linux.org.ru/view-message.jsp?msgid=4341449
патч ниже это 3 патча для 2.6.30 и *.diff выложенный по ссылке выше, обьединённые в один файл - патч ложится без проблем :)
А Это - отсюда: http://habrahabr.ru/post/116601/
Уже не помню, когда начились проблемы с производительностью при копировании файлов, но тогда я этому не придал большого значения так, как копировал файлы редко. Относительно недавно в моем распоряжении появилось высокоскоростное подключение к сети Интернет и теперь я часто копирую/качаю большие файлы и проблема падения производительности для меня стала очень актуальной.
Поверхностный гуглеж не дал результатов и я начал копать глубже, оказалось, что проблемы высокой нагрузки CPU есть у многих убунтоводов, если не у всех, а решение данной проблемы быстрым поиском не находится, поэтому я решил написать небольшой how-to по устранению высокой нагрузки на процессор при копировании файлов.
Проблема
При высокоскоростной закачке торрентов, многопоточном копировании с диска на диск, на флешки, загрузка процессора зашкаливает в 100%, быстро растет LA.
При этом на файловых операциях с небольшим числом потоков всё работает хорошо.
Немного теории
Есть такие штуки в операционной системе, называются планировщики ввода-вывода (IO schedulers), которыe являются прослойкой между блочными устройствами и драйверами низкого уровня. Задача планировщика — оптимальным образом обеспечить доступ процесса к запрашиваемому дисковому устройству. В случае жесткого диска — это означает минимизацию перемещений считывающей головки.
Деятельность планировщиков сводится к следующим аспектам:
Увеличение производительности за счет переупорядочения и слияния запросов
Предотвращение зависаний и перетирания считываемых данных записью
Честное распределение времени доступа к ресурсам разным процессам
Планировщиков есть много и, как выяснилось, именно с ними была связана проблема, решаемая этим постом.
Рассмотрим вкратце наиболее распространенные.
Простейший планировщик, работающий по принципу FIFO. Переупорядочения нет, слиянию могут подлежать только запросы, находящиеся рядом в очереди. Хорошо подходит для устройств со случайным доступом, вроде Flash памяти.
Планировщик, который ставит больший приоритет запросам на чтение, нежели запросам на запись. Запросы переупорядочиваются, но при этом время обработки запроса не должно превышать заданные пределы(по умолчанию, 0.5 с для чтения, 5 с для записи)
Для реализации используются 4 очереди: 2 очереди sorted-by-start-sector(для чтения и для записи) и 2 очереди FIFO(тоже для чтения и для записи). Обычно, запросы берутся из сортированных очередей, но если поджимает deadline(таймаут) первого запроса из очереди FIFO, то обработка запросов продолжается по сортированным очередям с этого элемента.
Лучше всего подходит для организации баз данных.
CFQ — Completely Fair Queuing
Цель этого планировщика — честное распределения времени доступа к ресурсу всех инициаторов запросов. CFQ может быть настроен для уравнивания процессов, групп процессов, пользователей.
По реализации, CFQ подразумевает по одной FIFO-очереди на инициатора запросов и переключается между очередями по алгоритму Round-robin.
Не знаю, кому нужна такая честность, но переупорядочения запросов для минимизации перемещения считывающей головки жесткого диска в этом планировщике нет.
Ключевая идея — перед обработкой запросов можно немного подождать, отдохнуть. Зато за эти несколько миллисекунд, соберется информация наперед, которая позволит более взвешенно принимать решения, в каком порядке запросы выполнять.
Планировщик Anticipatory базируется на Deadline. Подходит для десктопов, т.к. сохраняется отзывчивость подсистемы ввода вывода. Не подходит для RAID, TCQ. Плохо подходит в ситуациях, когда синхронные запросы посылаются разными процессами.
Решение
Планировщик по умолчанию в Ubuntu 10.10 — CFQ, но как показывает практика именно этот планировщик и вызывает высокую нагрузку на CPU при многопоточном копировании. Изменяем планировщик на другой, например, на Deadline и вуаля — больше нету загрузки CPU под 100%.
Для SSD дисков и Flash памяти вообще, как отмечено выше, рекомендуется использовать Noop.
Немного практики
Узнать активный планировщик
Чтобы посмотреть все доступные планировщики в системе и узнать, какой из них активен выполняем:
$ cat /sys/block/{DEVICE-NAME}/queue/scheduler
Здесь {DEVICE-NAME} — имя блочного устройства, например sda.
Например, если диск sda, то нужно выполнить:
$ cat /sys/block/sda/queue/scheduler
На выходе получаем строку вроде этой:
noop anticipatory deadline [cfq]
В квадратных скобках указан текущий планировщик.
Смена планировщика на лету
Чтобы поменять планировщик в реальном времени без перезагрузки выполняем:
$ sudo -i
# echo {SCHEDULER-NAME} > /sys/block/{DEVICE-NAME}/queue/scheduler
Здесь {SCHEDULER-NAME} — один из присутствующих в системе планировщиков, у меня это: noop anticipatory deadline cfq. Например, чтобы поставить планировщик deadline, выполяем
$ sudo -i
# echo deadline > /sys/block/sda/queue/scheduler
Фиксация настройки планировщика
Далее, нам нужно заставить Ubuntu использовать выбранный нами планировщик и после перезагрузки. Для этого добавляем строку GRUB_CMDLINE_LINUX_DEFAULT="elevator={SCHEDULER-NAME}" в конфиг GRUB 2.
$ sudo nano /etc/default/grub
UPD: После внесения изменений нужно обновить конфигурацию grub:
$ sudo update-grub
Если у вас grub, а не grub2, то добавляем строку elevator={SCHEDULER-NAME} в /boot/grub/grub.conf.
Помощь в выборе планировщика
На хабре уже писали про автоматизированный выбор планировщика. Конечно, простой проверки скорости чтения недостаточно для оптимального выбора, но кое-какое представление дать может.
Полезные ссылки
Ссылки, использованные при написании поста:
Презентация на тему I/O Schedulers в Linux
Linux Io Scheduler — Waikato Linux Users Group
A comparison of I/O Schedulers
Планировщики ввода/вывода в Linux (linux kernel io schedule optimization tune)
Рассказав о данном твике друзьям, удивился, что никто об этом не знал, решил запостить на Хабре, вдруг кому-то пригодится.
P.S.
UPD:
Данная статья рассказала лишь об одном, по сути самом простом, способе решения проблемы, связанной, c т.н. багом 12309. Есть еще советы по решению данной проблемы:
— не менять планировщик CFQ, но отконфигурировать
— поставить zen ядро
— настроить аггресивность Swap
— купить жесткий диск с аппаратным планировщиком и много оперативки(чтоб в Swap не уходить)