Linux: программные RAID-массивы

Зачем нужен программный RAID на пользовательской машине? Резонный человек ответит - потому что нет RAID'а аппаратного. И даже если он есть - не факт, что, например, Linux с произвольным ядром будет исправно работать со столь же произвольным контроллером ATA RAID - мой опыт общения с ними показал, что поддержка их даже современными ядрами, мягко говоря, далека от идеала (в отличие от FreeBSD, где все попадавшиеся мне дивайсы этого рода опознавались системой 5-й ветки безошибочно). Так что если есть уж очень большое желание использовать RAID, возможно, что программная его реализация (т.н. Soft RAID) окажется единственно возможной.

Кое-что о RAID вообще

Вне зависимости от того, реализован он аппаратно или программно, RAID-массив предназначен для представления нескольких физических дисков (или, при программном подходе, также и их разделов) в виде единого устройства. Различают RAID массивы с избыточностью и без оной. К первым относятся RAID level 0 и программный линейный режим. Цель таких массивов - повышение быстродействия дисковых операций или просто соображения удобства.

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

На практике в Linux (да и FreeBSD) используются два уровня избыточных RAID'ов - 1-й и 5-й (в The Software-RAID HOWTO описана и конфигурация программного level 4, но это не более чем догадка автора, по его собственному признанию).

RAID level 1 (называемый также режимом зеркалирования, mirroring) - это простое зеркало из двух дисков, то есть массив этот обладает 100-процентной избыточностью: при выходе из строя одного диска вся информация сохраняется на диске-дублере (хотя в процессе работы они выступают как равноправные). Разумеется, ни о каком росте производительности тут речи идти не может. Однако на сей предмет level 1 можно комбинировать с level 0 (это называют level 0+1 или, иногда, level 10), когда одна пара дисков в параллельном режиме зеркалируются второй парой. Правда, как нетрудно подсчитать, для этого желательно иметь 4 отдельных IDE-контроллера.

В RAID level 5 данные распределяются по всем составляющим массив дискам и дополняются контрольными суммами. По последним и осуществляется восстановление их в случае отказа одного устройства. Мнимальное количество дисков в таком массиве - три, и общий его объем равен произведению объема наименьшего на их число минус единица, так как для хранения контрольных используется часть пространства от каждого диска, в сумме равное объему единичного устройства. Массивы 5-го уровня считаются весьма надежными и теоретически даже обещают прирост быстродействия.

Пара слов об аппаратном ATA RAID

До недавнего времени аппаратные контроллеры ATA RAID, реализованные на отдельных PCI платах или "размазанные по маме", основывались на чипах производства трех фирм: Promise, HighPoint и Silicon Image. Теоретически все три поддерживаются каноническим ядром Linux. Для чего при его конфигурировании (в меню ATA/IDE/MFM/RLL support) следует включить общую поддержку ATA RAID (Support for IDE Raid controllers) и поддержку соответствующего чипа.

Поддержка ATA RAID может быть модульной или, если предполагается загрузка с аппаратного массива, встроенной в ядро. Последний случай потребует и еще одной опции - загрузки с устройств на внешнем контроллере (Boot off-board chipsets first support). А также некоторых ухищрений, если в качестве системного загрузчика выступает GRUB.

Однако на практике все оказывается не так здорово, и работу с ATA RAID нельзя отнести к сильным сторонам Linux. Из трех прошедших через мои руки материнских плат с встроенными RAID-контроллерами на двух RAID-контроллеры не виделись системой ни под каким соусом. Вернее, при соответствующей настройке ядра сами контроллеры-то опознавались, но вот подключенных к ним винчестеров как бы и не было. Более того, обнаружился парадоксальный факт: в качестве RAID-массива подчас представал обычный Master на первом канале обычного IDE-контроллера.

В некоторых случаях могут помочь драйверы от производителя чипа. Однако тут следует помнить: драйверы эти (в сущности, подключаемые модули ядра) доступны исключительно в бинарном виде и скомпилированы не только под определенную версию ядра, но и под конкретный дистрибутив (мне обычно попадались под Red Hat и Suse) конкретной (как правило, не самой юной) версии. Так что гарантировать их работосопособность в произвольной Linux-системе я бы не стал.

До сих пор такое положение можно было бы если не оправдать, то хотя бы объяснить тем, что ATA RAID воспринимался как устройство не то чтобы экзотическое, но, если угодно, опциональное (хотя, по моим наблюдениям, минимум треть материнок последних двух лет издания комплектовались RAID-контроллерами той или иной фирмы). Ныне такой отмазки нет: с появлением чипсетов i875/865 и их южных мостов в варианте ICH5R аппаратные RAID-контроллеры становятся стандартной фичей современных машин. Будем надеяться, что это поспособствует исправлению ситуации с поддержкой таких устройств ядром Linux. Тем более, что пример FreeBSD, в 5-й ветке которой никаких проблем с ними не обнаруживается - что называется, перед глазами.

Нужен ли RAID народу?

Остается все-таки определиться, для чего вообще RAID на десктопе. Тот же резонный человек скажет, что либо а) для повышения производительности (RAID level 0), либо б) для увеличения надежности (RAID level 1), либо в) для счастливого сочетания того и другого (RAID level 5, прочие уровни для десктопа действительно практического значения не имеют).

На все эти ответы можно привести не менее резонные возражения, как-то:

Таким образом, чуть ли не единственная причина использовать RAID - просто соображения удобства: разделы на двух (или более) физических дисках сливаются воедино и на них создается единая файловая система, например, под каталог /home со всеми пользовательскими данными (конечно, теоретически RAID можно создать из разделов на одном диске, однако это не более осмысленно, чем чесать правое ухо мизинцем левой ноги).

Конечно, есть и другой способ конкатенации разделов на разных носителях - технология LVM (Linux Volume Manager), подробно описанная ранее. Которая, помимо этого, предоставляет такие полезные возможности, как изменение размера файловой системы, подключение к ней "на лету" дополнительных разделов и т.д. Только нужно ли это на десктопе? Мое мнение (а я использовал LVM в течении длительного времени именно на своей БНВ (боевой настольной машине) - нет, не очень. За год у меня ни разу не появилось потребности в перераспределении дискового пространства. А если вдруг образовывались новые диски - то необходимости аккумулировать их в существующие файловые системы также не возникало. Тем более, что нынче мне и диски-то пихать уже некуда...

Так что если программный RAID - более простой способ конкатенации дискового пространства, чем LVM, почему бы им не воспользоваться. Вот я и решил изучить этот вопрос при очередном переконфигурировании машины на примере Linux. Благо, перед этим появился опыт создания программного RAID'а под FreeBSD (где LVM не поддерживается).

Договоримся сразу - наш программный RAID будет использоваться только под файловую систему, монтируемую в каталог /home - ни о корневой файловой системе, ни о загрузке с RAID'а речи не идет. А потому имеет смысл рассматривать только две RAID-разновидности - т.н. линейный режим и RAID level 0. При обоих дисковые разделы просто как бы механически соединяются воедино и выглядт для операционки (и ее пользователя) как одна партиция. Разница - в том, что при линейном режиме данные физически пишутся на сначала на один диск, потом - на второй. То есть, кроме собственно удобства в обращении с двумя дисками, он ничего не обеспечивает.

В массиве нулевого уровня (именуемый также режимом striple, что в данном случае можно трактовать как параллельный), напротив, каждая порция записываемых данных расслаивается на две равные части, одна из которых в одну и ту же единицу времени записывается на первый диск раздела, другая - на второй. Что теоретически должно способствовать быстродействию дисковых операций. И - способствует практически, но только при условии, что диски массива разнесены на разные IDE-каналы (о SCSI-дисках у нас тоже речи не будет). В противном случае выигрыша в производительности не только не будет, но весьма вероятно даже ее падение (в случае с LVM, где общение с дисками идет по сходному механизму, оно оказалось просто катастрофическим, сужу по собственному опыту).

Кроме того, RAID нулевого уровня не способствует надежности хранения данных - при отказе хотя бы одного диска пропадут они все (тогда как в линейном режиме информация на исправном диске в первом приближении сохранится). Тем не менее, применение праллельного режима может быть оправданным: сколько бы я ни говорил о некритичности дискового быцстродействия в настольных условиях, все же приятно, когда пара-тройка гигабайт копируется пусть не вдвое, но хотя бы в полтора раза быстрее (правда, за точность количественной оценки не ручаюсь).

Подготовительный этап

Как это в обычае в Linux, программный RAID любого выбранного уровня можно создать более чем одним способом - конкретно, двумя (впрочем, и во FreeBSD есть два метода организации RAID'ов). Однако на каком бы способе мы ни остановились, и какой бы RAID не выбрали, в любом случае потребуется выполнение некоторых условий и некоторый комплекс однотипных действий.

Первое условие, разумеется, - физическое наличие более чем одного диска. Причем очевидно, что число их для линейного режима значения не имеет, а для level 0 предпочтительно четное количество (хотя, насколько я понимаю, в отличие от аппаратной реализации RAID'а, это не обязательно). Опять же повторюсь: при линейном режиме порядок подключения дисков к контроллерам большой роли не играет, при выборе же нулевого RAID'а желательно разнести их на разные контроллеры.

Далее, на дисках необходимо создать (средствами fdisk, cfdisk, parted или любыми дистрибутив-специфичными утилитами) два раздела. Опять-таки, при использовании линейного режима размер разделов не имеет значения, тогда как при режиме параллельном их желательно делать равными (или хотя бы примерно равными) по объему: в противном случае размер суммарного массива будет уменьшена на величину разности его составляющих.

Наконец, разделам, предназначенным для объединения в массив, хорошо бы присвоить соответствующий идентификатор типа файловой системы - fd (в 16-теричной нотации), который так и называется - RAID Auto detection. В принципе, это не обязательно, но, как станет видно из дальнейшего, здорово упрощает жизнь.

Да, если разбиение диска осуществляется посредством cfdisk, в списке доступных идентификаторов RAID Auto detection там не обнаружится. Что отнюдь не значит, что его нельзя присвоить с помощью этой программой: следует просто после выбора пункта смены типа раздела нагло ввести fd - и все будет в порядке.

Теперь - ядро системы: для использования программного RAID'а в его конфигурации должны быть включены соответствующие опции в пункте Multi-device support (RAID and LVM) главного меню, генерируемого по команде

$ make menuconfig

А именно:

Общая поддержка "многочленных" устройств может быть только встроена в ядро, прочие же опции либо встраиваются, либо подключаются в качестве модулей (последнее имеет место быть по умолчанию в большинстве известных пакетных дистрибутивов типа Red Hat сотоварищи). В рассматриваемом нами случае это безразлично. Встраивание поддержки RAID в ядро обязательно только в том случае, если на массиве располагается корневая файловая система и (или) он выступает в качестве загрузочного устройства - ни того, ни другого мы договорились не делать. Да и то, при должном конфигурировании виртуального загрузочного диска (initrd) даже в этих случаях можно обойтись модулями. Тем не менее, я всегда встраиваю поддержку нужным мне устройств - пусть ядро становится больше, зато меньше возни с настройкой подключения модулей (да и интегрально так, мне кажется, выходит быстрее - а кого нынче волнует размер ядра?).

Из опций конфигурации ядра, прямо не связанных с RAID'ами, полезно иметь включенной также поддержку файловой системы процессов (procfs) - это позволит в дальнейшем иметь информацию о текущем состоянии массива. Делается это в пункте File systems главного меню (/proc file system support). Разумеется, эта файловая система должна быть прописана в файле /etc/fstab соответствующей строкой:

proc /proc proc defaults 0 0

для автоматического монтирования при старте системы. Впрочем, поддержка procfs не вредна в любом случае...

В процессе созидания

Теперь можно приступать к созданию RAID-массива. Для чего потребуется соответствующий программный инструментарий. И тут возникает та самая альтернатива, о которой я упоминал ранее: существует два набора подходящих для этого инструментов - традиционный raidtools и более новый mdadm. По крайней мере, один из них в любом полнофункциональном дистрибутиве найдется (и что-то подсказывает мне, то этот один окажется raidtools'ом).

Тем не менее, именно о raidtools я говорить бы здесь не хотел. Во-первых, он многократно описан. Существует фундаментальный The Software-RAID HOWTO, написанный Якобом Остергардом (Jakob Ostergaard) и переведенный на русский язык Максимом Дзюманенко (http://dmv.webjump.com/HOWTOs/, можно найти также на http://linux.yaroslavl.ru). Немало внимания RAID-массивам уделил в своей серии публикаций на сайте IBM-Linux Дэниэл Роббинс, создатель Gentoo Linux (часть 1, часть 2. И все эти документы посвящены исключительно использованию инструментария raidtools (каковой, кстати, имеет своим местопребыванием http://people.redhat.com/mingo/raidtools).

А вот о mdadm сведения можно почерпнуть только из его штатной документации . Русскоязычных его описаний мне не встречалось. Главное же, mdadm много превосходит raidtools с точки зрения удобства употребления (в очередной раз вынужден подчеркнуть - я рассуждаю с позиций пользователя, а не админа крутого сервера).

Итак, mdadm. Далеко не факт, что он имеет место быть в вашем дистрибутиве. Не беда - его всегда можно скачать - либо с автоского сайта, либо с канонической Linux-локации в виде тарбалла исходников (для текущей версии - mdadm-1.3.0.tgz). Обращение с которым, после обычной (tar xzvf mdadm-1.X.X.tgz) распаковки, столь же своеобычно - последовательность команд make и make install (обратим внимание - программа столь проста, что в предварительном конфигурировании посредством ./configure не нуждается).

По завершении установки мы обнаруживаем единственный исполняемый бинарник /sbin/mdadm (изменить каталог для него можно, залезши руками в ~/mdadm_src_dir/Makefile, но - нужно ли? в каталоге /sbin программе такого рода самое место) и пару относящихся к нему man-страниц (/usr/share/man/man5/mdadm.conf.5 и /usr/share/man/man8/mdadm.8). Содержащих вполне достаточно информации для того, чтобы приступить к делу создания собственного RAID'а. Приступим к этому и мы.

Нетрудно догадаться, что раз из всего пакета в итоге образовался только один бинарник, именно его и следует запустить для создания массива. Как - узнаем из man -8 mdadm (кое-какие сведения можно почерпнуть и из mdadm --help). И тот, и другой источник показывают, что для образования RAID'а команда mdadm требует одной из двух опций: -C (эквивалент --create) или -B (сиречь --build) - в обоих случаях обратите внимание на регистр краткой формы. В чем разница между ними?

Опция -B создает массив без собственного суперблока. Что, как будет ясно из дальнейшего, для пользователя снимает ряд преимуществ инструмента mdadm - и потому к этой опции мы возвращаться не будем. А вот опция -C этот суперблок учреждает - и ею определяется вся сила программы mdadm.

Итак, опция -C. Элементарная логика подсказывает, что она, будучи основной, требует аргумента - имени файла устройства, соответствующего создаваемому массиву (например, /dev/md0 или, при задействованной файловой системе устройств, /dev/md/0), а также указания некоторых дополнительных данных, как то: его уровня (режима), количества устройств в нем и, наконец, имен файлов устройств, массив составляющих. Что и достигается указанием опций --level=# (или, сокращенно, -l #) и --raid-devices=## (в краткой форме -n ##), после которой перечисляются имена файлов, вроде /dev/hda3, /dev/hdb3). В итоге простейший случай создания RAID'а параллельного режима выглядит следующим образом:

$ mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/hd[a,b]3

Для массива нулевого уровня допустимые значения опции --level также raid0 или stripe. А для массива линейного режима она примет значение linear (то есть -l linear).

Для параллельного режима дополнительно можно задать еще один параметр - размер блока "распараллеливаемых" данных, т.н. chunk, в виде одноименной опции --chunk=значение_в_килобайтах (в краткой форме -c ##). Теоретически рассуждая, чем больше величина chunk'а (давайте не будем подбирать к нему русского эквивалента), тем выше должно быть быстродействие массива. Однако практические измерения этого не подтверждают. И потому вполне можно опустить данную опцию - при этом умолчальное значение составит 64 Кбайт. Впрочем, если кто путем количественного тестирования опровергнет мое утверждение - буду признателен за информацию. Очевидно, что для массива в линейном режиме опция -c физического смысла не имеет.

В любом случае после указанной выше команды RAID создан, в чем легко убедиться командой

$ less /proc/mdstat

Более того, он сразу же готов к использованию - командой типа mkefs (или, в зависимости от предпочтений, mkreiserfs, mkxfs и т.д.) на нем можно создать ту или иную файловую систему. Хотя, с другой стороны, никто не запрещает поделить его программой fdisk на разделы (по моим наблюдениям, cfdisk на это не способен). Однако повторяю, если мы создавали RAID под единственную файловую систему типа /home, в каких либо действиях по организации раздела необходимости нет.

Создав файловую систему на новообразованном массиве, ее нужно смонтировать в желаемый каталог, увековечив это в файле /etc/fstab строкой типа

/dev/md/0 /home reiserfs noatime,notail 0 0

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

Внимательный читатель, особенно знакомый с документацией по raidtools, спросит: пардон, а где же тут конфиг, описывающий RAID-массив. Отвечаю: при использовании mdadm, установке соответствующих идентификаторов на составляющих массив разделах (вспомним добрым словом RAID Auto detection), и, наконец, создании массива с собственным суперблоком необходимости ни в каком конфиге не возникает. Так, файл данной статьи пишется в данный момент в каталог /home/alv, распооженный на RAID'е нулевого уровня, не описанном ни в каком файле каталога /etc.

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

$ mdadm --detail --scan

способна вывести информацию о существующем массиве. Достаточно перенаправить ее вывод в файл (таковым традиционно будет /etc/mdadm.conf) - и соответствующий конфигурационный файл будет создан (проделаю ка я эту операцию, пока опять не забыл - и продолжу после перезагрузки).

Дополнительные замечания

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

$ mdadm --create --help

распишет нам процесс создания массива в деталях.

С другой опцией (--detail, или -D - все опции, отнесенные к числу основных, в сокращенной форме даются в верхнем регистре) мы столкнулись в предыдущем разделе: она призвана выводить информацию о существующих массивах. Близкий смысл имеют и опции --query и --examine (в сокращенной форме, соответственно, -Q и -E) - за деталями можно обратиться к man-странице.

А вот опции --assemble (-A) и --monitor, или --follow (-F) предназначены для управления существующим массивом. В частности, они позволяют добавить к нему новое устройство или удалить существующее. Правда, при выполнении некоторых условий. Впрочем, и об этом подробно расскажет тетя Маня, если попросить ее должным образом.

В общем, создание RAID-массива средствами mdadm - процесс очень простой (а управление им пользователю на десктопе, скорее всего, не понадобится). Так что, если нет необходимости в дополнительных возможностях, предоставляемых LVM, при наличии двух дисков есть резон им и ограничится. Тем более, что и логические тома никто не запрещает расположить на программном RAID'е.

Альтернатива

Справедливости ради следует сказать пару слов и об инструментарии raidtools и способах обращения с ним. В отличие от maadm, он требует обязательного наличия конфигурационного файла - /etc/raidtab. Причем создать его нужно (вручную, в текстовом редакторе) до запуска каких-либо команд по созданию RAID'а.

Впрочем, структура /etc/raidtab очень проста. Стоит только помнить, что каждый из перечисленных ниже пунктов выступает в отдельной строке, значения в которой отделяются пробелами или табулятором - все же база данных (хотя и простая), а не хвост собачий... Итак:

Наконец, последовательно перечисляются имена всех объединяемых устройствс их порядковыми номерами, начиная с нуля:

device /dev/hda3 raid-disk 0 device /dev/hdb3 raid-disk 1

Закончив редактирование /etc/raidtab (рискну повториться, это - простой текстовый файл, создаваемый в текстовом же редакторе), активизируем RAID командой mkraid /dev/md0 и просмотром файла proc/mdstat убеждаемся, что все произошло так, как и задумывалось.

Сложнее, конечно, чем использование mdadm, но не намного, не так ли? Тем более, что весь процесс создания RAID именно применительно к инструментарию raidtools в деталях расписан в соответствующем HOWTO и ряде специальных статей.

Комментарии Владимира Холманова

О взаимодействии программного RAID и LVM

По моим наблюдениям, взаимодействие возможно только между soft-RAID 1 и LVM (другие уровни недоступны, но это не более чем "практическое" наблюдение). Собственно для этого и требуется опция -B команды mdadm. Иначе, в начале создается raid - зеркало "старого стиля", то есть без дескриптора (а не суперблока, как в статье) - дескриптор потребуется для LVM. Суперблок присутствует независимо от стиля и хранится где-то в последних 4 Kb раздела, а место дескриптора - среди первых 512 b. В качестве основы берутся два раздела, только не типа 83 (как для "классического старого стиля"), а дисковые разделы типа 8e. Разумеется, конфигурационный файл в каталоге /etc становится обязательным (впрочем, я предпочитаю пользоваться raidtools, но это не должно оказывать влияния). После таких манипуляций md становится возможным передать под управление логики.

О надежности raid

У меня "застучал" один из дисков raid зеркала. Заметил это не сразу. Результат - некоторые бады переползли на исправный диск. Но использовать raid можно и под надежный backup. Если где-то в "хвосте" дисков создать отдельный райд, "демонтированный и дезактивированный" в процессе работы и монтируемый только для backup - это будет весьма надежно.

Mdadm vs raidtools

Пакет mdadm содержит один большой универсальный бинарник, что удобно для интерактивной работы с RAID. Пакет raidtools содержит несколько специализированных небольших бинарников, а размер файла - важный параметр при использовании загрузочного initrd (в случае, если поддержка soft RAID подключается как модуль - А.Ф.).

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


Источник статьи