Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Тематический каталог -> Аппаратное обеспечение

Оптимизация жестких дисков для достижения максимальной скорости работы в Linux

Оригинал: "Optimizing Hard Drives For Maximum Speed in Linux"
Автор: Paul Rubens
Дата публикации: May 12, 2009
Перевод: Н.Ромоданов
Дата перевода: январь 2010 г.

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

Для того, чтобы считать данные с диска или записать их на диск, головка диска должна переместиться в правильную позицию и подождать, пока нужная часть поверхности пройдет под головкой. На это могут быть затрачены сотые доли секунды — во много раз больше, чем требуется для доступа к данным, запомненным, например, в оперативной памяти. В результате подсистема дискового ввода/вывода может оказаться «узким горлышком» при передаче большого объема данных, и можно достигнуть существенного повышения общей производительности сервера, если минимизировать эффект этого «узкого горлышка».

Для того, чтобы понять, как это можно сделать, давайте рассмотрим, как данные перемещаются на диск и с жесткого диска.

Проще говоря, подсистема ввода/вывода получает поток запросов на чтение данных с диска и запись данных на диск и помещает запросы в очередь. Чтобы ускорить процесс, подсистема обычно объединяет запросы на чтение или запись вместе, если запросы в очереди находятся близко друг к другу и если в них задействованы соседние области диска.

Запросам на чтение обычно присваивается больший приоритет, чем запросам на запись, поскольку процесс должен ждать, пока запрошенные данные будут прочитаны прежде, чем он будет продолжен, тогда как процесс не должен ждать пока выполниться запрос на запись.

Подсистема также обычно может определить, когда данные читаются с диска последовательно, и использует технику, называемую «упреждающее чтение», для того чтобы прочитать и поместить в кэш блок данных, который находится за читаемыми в настоящий момент данными. Это при последовательном чтении может уменьшить время доступа к данным, хотя это не увеличит скорость чтения других частей диска, если они произвольным образом расположены на диске. «Упреждающее чтение» будет отключено, если подсистема обнаружит, что происходит произвольное (не последовательное) чтение данных с диска.

После того, как будет выполнено такое простое слияние запросов, подсистема ввода/вывода могла бы обрабатывать запросы по очереди начиная с головы очереди по мере их поступления, но обычно так не делается. Вместо этого подсистема пытается увеличить скорость путем использования алгоритма планировщика, чтобы определить порядок, в котором запросы должны обрабатываться. В самом общем случае планировщик переупорядочивает запросы с тем, чтобы минимизировать движение головок диска, поскольку на механическое движение тратится сравнительно много времени. Таким образом, будут сгруппированы все запросы на чтение в некоторой одной области диска, затем — в другой и т.д.

Для того, чтобы проиллюстрировать, что делают алгоритмы планировщиков, полезно в качестве аналогии взять лифт. Когда лифт останавливается на первом этаже многолюдного офисного здания, большинство людей, зашедших в лифт, в произвольном порядке нажимают кнопки тех этажей, куда они хотят попасть. Очевидно, что не стоить сначала ехать на пятый этаж, затем — на сороковой, затем — на второй, а затем — на тридцать девятый, только потому, что в таком порядке были нажаты кнопки. Значительно более разумная стратегия останавливаться в порядке возрастания номеров этажей: на втором, на пятом, на тридцать девятом и, наконец, на сороковом. За счет того, что движение происходит в одном направлении вместо того, чтобы каждый раз возвращаться, лифт доставит каждого пассажира на его этаж за минимальное время.

Но оказывается, что этот вид планирования не всегда является оптимальным для подсистемы ввода / вывода (или для лифта); в действительности у этого алгоритма имеется ряд недостатков. Если вернуться к аналогии с лифтом, люди, работающие на самых высоких этажах, должны потратить много лишнего времени останавливаясь на десятках или, потенциально, на сотнях промежуточных этажах каждый раз, когда они пытаются добраться в свой офис. По этой причине во многих больших зданиях имеется несколько лифтов, которые вообще не обслуживают первые этажи, вместо этого они сразу двигаются до самого высокого этажа прежде, чем остановиться. Работники верхних этажей получают преимущество за счет работников более низких этажей, у которых теперь меньше лифтов, обслуживающих их этажи.

Наилучший алгоритм планировщика

Так какой алгоритм планировщика наилучший? Фактически нет такого, который был одним «наилучшим» алгоритмом. Вместо этого имеется несколько различных планировщиков, каждый из которых подходит для различных типов серверов. В большинстве систем Linux имеются следующие четыре принципиально различных планировщика:

  • noop (никаких действий по планированию не делается)
  • deadline (задается предельный срок, в течение которого запрос должен быть обработан)
  • anticipatory (планирование с упреждением)
  • completely fair queuing ("абсолютно справедливая очередь")

Планировщик noop

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

Планировщик noop полезен в системах, где используются современные RAID контроллеры, которые могут выполнять планирование ввода/вывода лучше, чем операционные системы. Он также полезен в системах с твердотельными дисками (в том числе — RAM дисками), в которых скорость доступа к данным одинакова независимо от того, где эти данные располагаются на диске.

Планировщик deadline

Планировщик deadline («крайний срок» обслуживания запроса) создан для преодоления проблем, связанных с запросом на чтение данных, расположенных в дальних частях диска, которые обслуживаются медленно из-за того, что эти запросы добавляются в очередь после тех запросов, которые обращаются к более близким частям диска. Это похоже на попытку достичь верхнего этажа здания на лифте, который постоянно останавливается на промежуточных этажах для посадки и высадки пассажиров. Для того, чтобы это преодолеть, для каждого запроса указывается время ожидания или «крайний срок» обслуживания запроса. Если запрос не будет обслужен до истечения срока, то он будет установлен в начало очереди, объединившись с запросами к ближайшей области на диске, и будет обработан немедленно.

Планировщик deadline полезен для приложений реального времени, поскольку в большинстве случаев при его использовании задержка операций небольшая и поскольку все запросы обслуживаются в течение сравнительно короткого промежутка времени, задаваемого значением deadline.

Планировщик anticipatory

Планировщик anticipatory работает с предположением, что следующий запрос будет для блока на диске, который следует за тем блоком, который только что был обслужен. После выполнения операции чтения или записи планировщик делает некоторую задержку с тем, чтобы дать приложению время послать запрос на действие со следующим блоком. Если такой запрос (как предполагалось) поступит, головка диска окажется в правильном месте для обслуживания запроса, вместо того, чтобы переместиться куда-нибудь в другое место для выполнения следующего запроса.

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

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

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

Планировщик cfq

cfq является сокращение термина "completely fair queuing" ("абсолютно справедливая очередь"). В этом случае планировщик поддерживает несколько внутренних очередей обслуживания запросов и каждый процесс, работающий в в системе, назначается одной из этих очередей. Затем планировщик берет запросы с начала каждой очереди и помещает их в очередь диспетчера, где запросы переупорядочиваются с целью минимизации времени доступа к данным и времени обслуживания запросов.

Это аналогично зданию с одним лифтом с отдельной очередью для каждой компании, офис которой находится в этом здании. Каждый раз, когда лифт достигает вестибюля, в него садятся люди, стоящие в начале каждой очереди каждой компании, поэтому ни одна из компаний не может перегрузить лифт. Планировщик cfq хорошо работает в средних и больших мультипроцессорных системах и используется по умолчанию в таких дистрибутивах Linux, как, например, Red Hat Enterprise Linux.

Продолжение ...