И RAID, и LVM являются технологиями абстрагирования монтируемых томов от их физических эквивалентов (жёстких дисков или разделов на них); первая обеспечивает безопасность и доступность данных в случае аппаратных сбоев, добавляя избыточность, а вторая делает управление данными более гибким и независимым от реального размера физических дисков. В обоих случаях система получает новые блочные устройства, которые могут использоваться для создания файловых систем или пространства подкачки без обязательного размещения их на одном физическом диске. RAID и LVM возникли из разных нужд, но их функциональность может в чём-то перекрываться, поэтому их часто и упоминают вместе.
В случае и RAID, и LVM ядро предоставляет файл блочного устройства, сходный с соответствующими жёсткому диску или разделу. Когда приложению или другой части ядра требуется доступ к блоку такого устройства, надлежащая подсистема передаёт блок соответствующему физическому слою. В зависимости от конфигурации этот блок может быть сохранён на одном или нескольких физических дисках, и его физическое расположение может не прямо соотноситься с расположением блока в логическом устройстве.
RAID расшифровывается как Redundant Array of Independent Disks — избыточный массив независимых дисков. Цель этой системы — предотвратить потерю данных и гарантировать их доступность в случае сбоя жёсткого диска. Основной принцип прост: данные хранятся на нескольких физических дисках вместо одного, с настраиваемым уровнем избыточности, и даже в случае неожиданного выхода диска из строя данные могут быть без потерь восстановлены с остальных дисков.
RAID может быть реализован как в виде специального оборудования (модули RAID, встроенные в карты контроллеров SCSI или SATA), так и в виде программной абстракции (ядро). Как аппаратный, так и программный RAID с достаточной избыточностью может прозрачно продолжать работу, когда диск выходит из строя; верхние уровни стека (приложения) могут даже продолжать доступ к данным несмотря на сбой. Разумеется, такой «деградированный режим» может повлиять на производительность, а избыточность уменьшается, так что отказ следующего диска может привести к потере данных. На деле, однако, работать в этом деградированном режиме придётся лишь столько времени, сколько потребуется для замены отказавшего диска. Как только новый диск будет на месте, система RAID сможет восстановить необходимые данные для возврата в безопасный режим. Приложения не заметят ничего, кроме возможно снизившейся скорости доступа в то время, когда массив пребывает в деградированном состоянии, или на этапе восстановления.
Когда RAID реализован аппаратно, его настройка в общем случае производится с помощью инструмента настройки BIOS, и ядро принимает RAID-массив за отдельный диск, который будет работать как обычный физический диск, хотя его имя может быть другим (в зависимости от драйвера).
В этой книге мы сосредоточимся исключительно на программном RAID.
12.1.1.1. Разные уровни RAID
RAID представляет собой не единую систему, а набор систем, различаемых по их уровням; уровни отличаются по схеме размещения данных и по степени избыточности. Более избыточный является более отказоустойчивым, поскольку система сможет продолжить работу с бо́льшим числом вышедших из строя дисков. С другой стороны, доступное пространство для того же набора дисков уменьшается; другими словами, для хранения того же объёма данных потребуется больше дисков.
- Linear RAID
Хотя RAID-подсистема ядра позволяет создавать так называемый «linear RAID», собственно RAID он не является, поскольку не подразумевает какой-либо избыточности. Ядро просто объединяет несколько дисков «встык» и представляет получившийся том как один виртуальный диск (одно блочное устройство). Это единственное его назначение. Такая настройка редко используется сама по себе (об исключениях см. ниже), главным образом потому что отсутствие избыточности означает, что сбой одного диска делает всё объединение и, соответственно, все данные, недоступными.
- RAID-0
Этот уровень также не обеспечивает избыточности, но диски не просто соединяются один за другим : они разделяются на полосы, и блоки виртуального устройства сохраняются на полосах физических дисков поочерёдно. В двухдисковом RAID-0, например, чётные блоки виртуального устройства будут сохраняться на первом физическом диске, а нечётные разместятся на втором физическом диске.
Целью такой системы является не повышение надёжности, поскольку (как и в случае с linear) доступность всех данных оказывается под угрозой, как только один из дисков отказывает, а увеличение производительности: при последовательном доступе к большому объёму непрерывных данных ядро сможет читать с обоих дисков (или производить запись на них) параллельно, что увеличит скорость передачи данных. Диски используются RAID-устройством полностью, поэтому они должны быть одинакового размера, чтобы не терять производительности.
RAID-0 используется всё реже, его ниша сейчас занимается LVM (см. ниже).
- RAID-1
Этот уровень, также известный как «зеркальный RAID», является одновременно и самым простым, и самым широко используемым. В своём стандартном виде он использует два физических диска одного размера и предоставляет логический том опять-таки того же размера. Данные хранятся одинаково на обоих дисках, отсюда и название «зеркало». Когда один диск выходит из строя, данные по-прежнему доступны с другого. Для действительно ценных данных RAID-1, конечно, может быть настроен на более чем двух дисках, с пропорциональным увеличением отношения цены оборудования к доступному пространству.
Данный уровень RAID хотя и дорог (поскольку в лучшем случае используется только половина физического хранилища), но широко применяется на практике. Он прост для понимания и позволяет легко делать резервные копии: поскольку оба диска хранят одинаковое содержимое, один из них может быть временно извлечён без влияния на работающую систему. Скорость чтения часто возрастает, поскольку ядро может считывать половину данных с каждого диска одновременно, в то время как скорость записи существенно не уменьшается. В случае массива RAID-1 из N дисков данные остаются доступными даже при отказе N-1 диска.
- RAID-4
Этот довольно редко применяемый уровень RAID, использует N дисков для хранения полезных данных и дополнительный диск для хранения избыточной информации. Если этот диск выходит из строя, система восстанавливает его содержимое с оставшихся N дисков. Если один из N дисков с данными отказывает, оставшиеся N-1 в сочетании с диском контроля чётности содержат достаточно информации для восстановления необходимых данных.
RAID-4 не так дорог, поскольку приводит к увеличению цены только на один из N и не оказывает существенного влияния на скорость чтения, но запись замедляется. Кроме того, поскольку запись на любой из N дисков влечёт за собой запись на диск контроля чётности, на последний запись производится значительно чаще, и как следствие его время жизни существенно сокращается. Данные на массиве RAID-4 сохранны при отказе только одного диска (из N+1).
- RAID-5
RAID-5 нацелен на исправление асимметрии RAID-4: блоки контроля чётности распределяются по всем N+1 дискам, без выделения специального диска.
Скорость чтения и записи идентичны RAID-4. Опять-таки, система остаётся работоспособной только с одним отказавшим диском (из N+1), не более.
- RAID-6
RAID-6 можно считать расширением RAID-5, где каждая последовательность из N блоков предполагает два избыточных блока, и каждая последовательность из N+2 блоков распределяется по N+2 дискам.
Этот уровень RAID несколько дороже, чем предыдущие два, но он добавляет надёжности, поскольку до двух дисков (из N+2) могут выйти из строя без ущерба для доступа к данным. С другой стороны, операции записи теперь предполагают запись одного блока данных и двух избыточных блоков, что делает их ещё более медленными.
- RAID-1+0
Строго говоря, это не уровень RAID, а наложение двух группировок RAID. Начиная с 2×N дисков, первая собирает их попарно в тома RAID-1; эти N томов затем собираются в один при посредстве «linear RAID» или (всё чаще) LVM. Этот последний случай не является RAID в чистом виде, но это не создаёт проблем.
RAID-1+0 может пережить выход из строя нескольких дисков: до N в массиве из 2×N, описанном выше, в случае если хотя бы один диск остаётся работоспособным в каждой паре RAID-1.
Безусловно, уровень RAID следует выбирать в соответствии с ограничениями и потребностями конкретного приложения. Учтите, что в одном компьютере может быть несколько отдельных RAID-массивов разных конфигураций.
Настройка томов RAID требует пакета mdadm; он предоставляет команду mdadm
, с помощью которой можно создавать RAID-массивы и манипулировать ими, а также сценарии и инструменты для интеграции с остальными компонентами системы, в том числе с системами мониторинга.
Для примера рассмотрим сервер с несколькими дисками, некоторые из которых уже используются, а другие доступны для создания RAID. Изначально у нас есть такие диски и разделы:
диск sdb
, 4 ГБ, полностью доступен;
диск sdc
, 4 ГБ, также полностью доступен;
на диске sdd
доступен только раздел sdd2
(около 4 ГБ);
наконец, диск sde
, также 4 ГБ, полностью доступен.
Мы собираемся использовать эти физические носители для сборки двух томов, одного RAID-0 и одного зеркала (RAID-1). Начнём с тома RAID-0:
#
mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sdb /dev/sdc
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
#
mdadm --query /dev/md0
/dev/md0: 7.99GiB raid0 2 devices, 0 spares. Use mdadm --detail for more detail.
#
mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Mon Feb 28 01:54:24 2022
Raid Level : raid0
Array Size : 8378368 (7.99 GiB 8.58 GB)
Raid Devices : 2
Total Devices : 2
Persistence : Superblock is persistent
Update Time : Mon Feb 28 01:54:24 2022
State : clean
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Layout : -unknown-
Chunk Size : 512K
Consistency Policy : none
Name : debian:0 (local to host debian)
UUID : a75ac628:b384c441:157137ac:c04cd98c
Events : 0
Number Major Minor RaidDevice State
0 8 0 0 active sync /dev/sdb
1 8 16 1 active sync /dev/sdc
#
mkfs.ext4 /dev/md0
mke2fs 1.46.2 (28-Feb-2021)
Discarding device blocks: done
Creating filesystem with 2094592 4k blocks and 524288 inodes
Filesystem UUID: ef077204-c477-4430-bf01-52288237bea0
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
#
mkdir /srv/raid-0
#
mount /dev/md0 /srv/raid-0
#
df -h /srv/raid-0
Filesystem Size Used Avail Use% Mounted on
/dev/md0 7.8G 24K 7.4G 1% /srv/raid-0
Команда mdadm --create
требует нескольких параметров: имени создаваемого тома (/dev/md*
, где MD расшифровывается как Multiple Device), уровня RAID, количества дисков (это обязательный параметр, хотя он и имеет значение только для RAID-1 и выше), и физические устройства для использования. Когда устройство создано, мы можем использовать его, как если бы это был обычный раздел: создавать файловую систему на нём, монтировать эту файловую систему и т. п. Обратите внимание, что создание тома RAID-0 под именем md0
— не более чем совпадение, и нумерация массивов не обязана соответствовать выбранному уровню избыточности. Также можно создать именованные RAID-массивы, передавая mdadm
такие параметры как /dev/md/linear
вместо /dev/md0
.
RAID-1 создаётся сходным образом, различия заметны только после создания:
#
mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sdd2 /dev/sde
mdadm: Примечание: этот массив имеет метаданные в начале и
может не подойти в качестве загрузочного устройства. Если вы планируете
хранить '/boot' на этом устройстве убедитесь, что
ваш boot-loader понимает md/v1.x метаданные, или используйте
--metadata=0.90
mdadm: больший диск (/dev/sdd2) превышает размер (4192192K) более чем на 1%
Продолжить создание массива?
y
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md1 started.
#
mdadm --query /dev/md1
/dev/md1: 4.00GiB raid1 2 devices, 0 spares. Use mdadm --detail for more detail.
#
mdadm --detail /dev/md1
/dev/md1:
Version : 1.2
Creation Time : Tue Jun 25 10:21:22 2019
Raid Level : raid1
Array Size : 4189184 (4.00 GiB 4.29 GB)
Used Dev Size : 4189184 (4.00 GiB 4.29 GB)
Raid Devices : 2
Total Devices : 2
Persistence : Superblock is persistent
Update Time : Tue Jun 25 10:22:03 2019
State : clean, resyncing
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Consistency Policy : resync
Resync Status : 93% complete
Name : mirwiz:1 (local to host debian)
UUID : 7d123734:9677b7d6:72194f7d:9050771c
Events : 16
Number Major Minor RaidDevice State
0 8 64 0 active sync /dev/sdd2
1 8 80 1 active sync /dev/sde
#
mdadm --detail /dev/md1
/dev/md1:
[...]
State : clean
[...]
Здесь уместны несколько замечаний. Во-первых, mdadm
предупреждает, что физические элементы имеют разные размеры; поскольку это подразумевает, что часть пространства на большем элементе будет потеряна, здесь требуется подтверждение.
Что более важно, обратите внимание на состояние зеркала. Нормальное состояние зеркала RAID — когда содержимое двух дисков полностью идентично. Однако ничто не гарантирует этого, когда том только что создан. Поэтому подсистема RAID берёт эту гарантию на себя, и как только устройство RAID будет создано, начнётся этап синхронизации. Некоторое время спустя (точное его количество будет зависеть от размера дисков…) массив RAID переходит в состояние «active». Заметьте что на этом этапе восстановления зеркало находится в деградированном состоянии, и избыточность не гарантируется. Сбой диска в этот рискованный промежуток времени может привести к потере всех данных. Большие объёмы важных данных, однако, редко сохраняются на только что созданном RAID до конца начальной синхронизации. Отметьте, что даже в деградированном состоянии /dev/md1
может использоваться, на нём можно создать файловую систему и скопировать в неё какие-то данные.
Теперь посмотрим, что происходит, когда один из элементов массива RAID-1 выходит из строя. mdadm
, а точнее её опция --fail
, позволяет симулировать такой отказ диска:
#
mdadm /dev/md1 --fail /dev/sde
mdadm: set /dev/sde faulty in /dev/md1
#
mdadm --detail /dev/md1
/dev/md1:
Version : 1.2
Creation Time : Mon Feb 28 02:07:48 2022
Raid Level : raid1
Array Size : 4189184 (4.00 GiB 4.29 GB)
Used Dev Size : 4189184 (4.00 GiB 4.29 GB)
Raid Devices : 2
Total Devices : 2
Persistence : Superblock is persistent
Update Time : Mon Feb 28 02:15:34 2022
State : clean, degraded
Active Devices : 1
Working Devices : 1
Failed Devices : 1
Spare Devices : 0
Consistency Policy : resync
Name : debian:1 (local to host debian)
UUID : 2dfb7fd5:e09e0527:0b5a905a:8334adb8
Events : 19
Number Major Minor RaidDevice State
0 8 34 0 active sync /dev/sdd2
- 0 0 1 removed
1 8 48 - faulty /dev/sde
Содержимое тома по-прежнему доступно (и, если он смонтирован, приложения ничего не заметят), но сохранность данных больше не застрахована: если диск sdd
в свою очередь выйдет из строя, данные будут потеряны. Мы хотим избежать такого риска, поэтому мы заменим отказавший диск новым, sdf
:
#
mdadm /dev/md1 --add /dev/sdf
mdadm: added /dev/sdf
#
mdadm --detail /dev/md1
/dev/md1:
Version : 1.2
Creation Time : Mon Feb 28 02:07:48 2022
Raid Level : raid1
Array Size : 4189184 (4.00 GiB 4.29 GB)
Used Dev Size : 4189184 (4.00 GiB 4.29 GB)
Raid Devices : 2
Total Devices : 3
Persistence : Superblock is persistent
Update Time : Mon Feb 28 02:25:34 2022
State : clean, degraded, recovering
Active Devices : 1
Working Devices : 2
Failed Devices : 1
Spare Devices : 1
Consistency Policy : resync
Rebuild Status : 47% complete
Name : debian:1 (local to host debian)
UUID : 2dfb7fd5:e09e0527:0b5a905a:8334adb8
Events : 39
Number Major Minor RaidDevice State
0 8 34 0 active sync /dev/sdd2
2 8 64 1 spare rebuilding /dev/sdf
1 8 48 - faulty /dev/sde
#
[...]
[...]
#
mdadm --detail /dev/md1
/dev/md1:
Version : 1.2
Creation Time : Mon Feb 28 02:07:48 2022
Raid Level : raid1
Array Size : 4189184 (4.00 GiB 4.29 GB)
Used Dev Size : 4189184 (4.00 GiB 4.29 GB)
Raid Devices : 2
Total Devices : 3
Persistence : Superblock is persistent
Update Time : Mon Feb 28 02:25:34 2022
State : clean
Active Devices : 2
Working Devices : 2
Failed Devices : 1
Spare Devices : 0
Consistency Policy : resync
Name : debian:1 (local to host debian)
UUID : 2dfb7fd5:e09e0527:0b5a905a:8334adb8
Events : 41
Number Major Minor RaidDevice State
0 8 34 0 active sync /dev/sdd2
2 8 64 1 active sync /dev/sdf
1 8 48 - faulty /dev/sde
Опять-таки, ядро автоматически запускает этап восстановления, на протяжении которого том, хотя и по-прежнему доступный, находится в деградированном состоянии. Когда восстановление завершается, массив RAID возвращается в нормальное состояние. Можно сказать системе, что диск sde
следует удалить из массива, в результате чего получится классическое зеркало RAID на двух дисках:
#
mdadm /dev/md1 --remove /dev/sde
mdadm: hot removed /dev/sde from /dev/md1
#
mdadm --detail /dev/md1
/dev/md1:
[...]
Number Major Minor RaidDevice State
0 8 34 0 active sync /dev/sdd2
2 8 64 1 active sync /dev/sdf
После этого диск может быть физически извлечён из сервера при следующем отключении, или даже из работающего сервера, если аппаратная конфигурация позволяет горячую замену. Такие конфигурации включают некоторые контроллеры SCSI, большинство SATA-дисков и внешние накопители, работающие через USB или Firewire.
12.1.1.3. Создание резервной копии настроек
Большая часть метаданных, касающихся томов RAID, сохраняется непосредственно на дисках, входящих в эти массивы, так что ядро может определить массивы и их компоненты и собрать их автоматически при запуске системы. И всё же резервное копирование конфигурации крайне желательно, поскольку такое определение не защищено от ошибок, и следует ожидать, что оно наверняка даст сбой в самый неподходящий момент. В нашем примере, если бы отказ диска sde
был настоящим (а не симулированным), и система перезагрузилась бы без удаления диска sde
, он мог бы начать работать опять, поскольку был бы обнаружен при перезагрузке. Ядро получило бы три физических элемента, каждый из которых заявлял бы, что содержит половину одного и того же тома RAID. Другой источник путаницы может возникнуть, когда тома RAID с двух серверов переносятся на один и тот же сервер. Если эти массивы работали нормально до того, как диски были перемещены, ядро смогло бы обнаружить и пересобрать пары корректно; но если перемещённые диски были объединены в md1
на прежнем сервере, а на новом сервере уже был бы md1
, одно из зеркал было бы переименовано.
Поэтому резервное копирование важно хотя бы для справки. Стандартный путь для этого — редактирование файла /etc/mdadm/mdadm.conf
, пример которого приводится здесь:
Пример 12.1. Конфигурационный файл mdadm
# mdadm.conf
#
# !NB! Запустите update-initramfs -u после обновления этого файла.
# !NB! Это обеспечит наличие обновленной копии initramfs.
#
# Пожалуйста, обратитесь к mdadm.conf(5) за информацией об этом файле.
#
# умолчально (встроенно), сканирует все разделы (/proc/partitions) и все
# контейнеры в поисках MD суперблоков. Альтернативно, укажите устройства для сканирования, используя
# wildcards при желании.
DEVICE /dev/sd*
# автоматически помечать новые массивы как принадлежащие локальной системе
HOMEHOST <system>
# указать демону мониторинга, куда отправлять почтовые оповещения
MAILADDR root
# определения существующих MD массивов
ARRAY /dev/md/0 metadata=1.2 UUID=a75ac628:b384c441:157137ac:c04cd98c name=debian:0
ARRAY /dev/md/1 metadata=1.2 UUID=2dfb7fd5:e09e0527:0b5a905a:8334adb8 name=debian:1
# This configuration was auto-generated on Mon, 28 Feb 2022 01:53:48 +0100 by mkconf
Один из наиболее важных элементов здесь — опция DEVICE
, в которой перечисляются устройства, на которых система будет автоматически искать компоненты томов RAID во время запуска. В нашем примере мы заменили значение по умолчанию, partitions containers
, на явный список файлов устройств, поскольку мы выбрали использование целых дисков, а не только разделов, для некоторых томов.
Последние две строки в нашем примере позволяют ядру безопасно выбирать, какой номер тома какому массиву следует назначить. Метаданных, хранящихся на самих дисках, достаточно для пересборки томов, но не для определения номера тома (и соответствующего имени устройства /dev/md*
).
К счастью, эти строки могут быть сгенерированы автоматически:
#
mdadm --misc --detail --brief /dev/md?
ARRAY /dev/md/0 metadata=1.2 UUID=a75ac628:b384c441:157137ac:c04cd98c name=debian:0
ARRAY /dev/md/1 metadata=1.2 UUID=2dfb7fd5:e09e0527:0b5a905a:8334adb8 name=debian:1
Содержимое этих последних двух строк не зависит от списка дисков, входящих в том. Поэтому нет необходимости перегенерировать эти строки при замене вышедшего из строя диска новым. С другой стороны, следует аккуратно обновлять этот файл при создании или удалении массива RAID.
LVM, или Logical Volume Manager ("Менеджер Логических Томов") — другой подход к абстрагированию логических томов от их физических носителей, который фокусируется на увеличении гибкости, а не надёжности. LVM позволяет изменять логический том прозрачно для приложений; к примеру, можно добавить новые диски, перенести на них данные и удалить старые диски без отмонтирования тома.
Такая гибкость достигается за счёт уровня абстракции, включающего три понятия.
Первое, PV (физический том — "Physical Volume"), ближе всего к аппаратной стороне: это могут быть разделы на диске, целый диск или иное блочное устройство (в том числе и RAID-массив). Обратите внимание, что когда физический элемент настроен на использование в роли PV для LVM, доступ к нему должен осуществляться только через LVM, иначе система будет сбита с толку.
Несколько PV могут быть объединены в VG (группу томов — "Volume Group"), которую можно сравнить с виртуальными расширяемыми дисками. VG абстрактны и не имеют представления в виде файла в структуре иерархии /dev
, так что нет риска при использовании их напрямую.
Третий тип объектов — LV (логический том — "Logical Volume"), который является частью VG; если продолжить аналогию VG с диском, то LV соответствует разделу. LV представляется как блочное устройство в /dev
и может использоваться точно так же, как и любой физический раздел (как правило — для размещения файловой системы или пространства подкачки).
Важно, что разбиение VG на LV совершенно независимо от его физических компонент (PV). VG с единственным физическим компонентом (например диском) может быть разбита на десяток логических томов; точно так же VG может использовать несколько физических дисков и представляться в виде единственного большого логического тома. Единственным ограничением является то, что, само собой, общий размер, выделенный LV, не может быть больше, чем общая ёмкость всех PV в группе томов.
Часто, однако, имеет смысл использовать однородные физические компоненты в составе VG. К примеру, если доступны быстрые диски и более медленные, быстрые можно объединить в одну VG, а более медленные — в другую; порции первой можно выдавать приложениям, требующим быстрого доступа к данным, а вторую оставить для менее требовательных задач.
В любом случае помните, что LV не закреплены за конкретным PV. Можно повлиять на то, где физически хранятся данные с LV, но эта возможность не требуется для повседневного использования. С другой стороны, когда набор физических компонентов VG меняется, физические места хранения, соответствующие конкретному LV, можно переносить между дисками (в пределах PV, закреплённых за VG, разумеется).
Давайте пройдём шаг за шагом процесс настройки LVM для типичного случая: мы хотим упростить чрезмерно усложнённую ситуацию с хранилищами. Такое обычно получается в результате долгой и витиеватой истории накопления временных мер. Для иллюстрации возьмём сервер, на котором со временем возникала потребность в изменении хранилища, что в конечном итоге привело к путанице из доступных разделов, распределённых по нескольким частично используемым дискам. Если более конкретно, доступны следующие разделы:
на диске sdb
— раздел sdb2
, 4 ГБ;
на диске sdс
— раздел sdс3
, 3 ГБ;
диск sdd
, 4 ГБ, доступен полностью;
на диске sdf
— раздел sdf1
, 4 ГБ, и раздел sdf2
, 5 ГБ.
Кроме того, давайте считать, что диски sdb
и sdf
быстрее двух других.
Наша цель — настроить три логических тома для трёх разных приложений: файлового сервера, требующего 5 ГБ дискового пространства, базы данных (1 ГБ), и некоторое пространство для резервных копий (12 ГБ). Первым двум требуется хорошая производительность, а резервные копии менее критичны к скорости доступа. Все эти ограничения не позволяют разделы сами по себе; используя LVM, можно абстрагироваться от физического размера устройств, так что единственным ограничением является общее доступное пространство.
Необходимые инструменты находятся в пакете lvm2 и его зависимостях. После их установки настройка LVM проходит в три шага, соответствующих трём уровням организации.
Первым делом мы подготавливаем физические тома с помощью pvcreate
:
#
pvcreate /dev/sdb2
Physical volume "/dev/sdb2" successfully created.
#
pvdisplay
"/dev/sdb2" is a new physical volume of "4.00 GiB"
--- NEW Physical volume ---
PV Name /dev/sdb2
VG Name
PV Size 4.00 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID yK0K6K-clbc-wt6e-qk9o-aUh9-oQqC-k1T71B
#
for i in sdc3 sdd sdf1 sdf2 ; do pvcreate /dev/$i ; done
Physical volume "/dev/sdc3" successfully created.
Physical volume "/dev/sdd" successfully created.
Physical volume "/dev/sdf1" successfully created.
Physical volume "/dev/sdf2" successfully created.
#
pvdisplay -C
PV VG Fmt Attr PSize PFree
/dev/sdb2 lvm2 --- 4.00g 4.00g
/dev/sdc3 lvm2 --- 3.00g 3.00g
/dev/sdd lvm2 --- 4.00g 4.00g
/dev/sdf1 lvm2 --- 4.00g 4.00g
/dev/sdf2 lvm2 --- 5.00g 5.00g
Пока всё идёт неплохо; отметим, что PV может быть размещён как на целом диске, так и на отдельном его разделе. Как показано выше, команда pvdisplay
выводит список существующих PV, с двумя возможными форматами вывода.
Теперь давайте соберём эти физические элементы в VG с помощью vgcreate
. Мы соберём PV с быстрых дисков в VG под названием vg_critical
; другая VG, vg_normal
, будет также включать более медленные элементы.
#
vgcreate vg_critical /dev/sdb2 /dev/sdf1
Volume group "vg_critical" successfully created
#
vgdisplay
--- Volume group ---
VG Name vg_critical
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size 7.99 GiB
PE Size 4.00 MiB
Total PE 2046
Alloc PE / Size 0 / 0
Free PE / Size 2046 / 7.99 GiB
VG UUID JgFWU3-emKg-9QA1-stPj-FkGX-mGFb-4kzy1G
#
vgcreate vg_normal /dev/sdc3 /dev/sdd /dev/sdf2
Volume group "vg_normal" successfully created
#
vgdisplay -C
VG #PV #LV #SN Attr VSize VFree
vg_critical 2 0 0 wz--n- 7.99g 7.99g
vg_normal 3 0 0 wz--n- <11.99g <11.99g
И снова команды довольно просты (и vgdisplay
предоставляет два формата вывода). Заметьте, что можно использовать два раздела одного физического диска в двух разных VG. Мы использовали приставку vg_
в именах наших VG, но это не более чем соглашение.
Теперь у нас есть два «виртуальных диска» размером около 8 ГБ и 12 ГБ соответственно. Давайте разделим их на «виртуальные разделы» (LV). Для этого потребуется команда lvcreate
и несколько более сложный синтаксис:
#
lvdisplay
#
lvcreate -n lv_files -L 5G vg_critical
Logical volume "lv_files" created.
#
lvdisplay
--- Logical volume ---
LV Path /dev/vg_critical/lv_files
LV Name lv_files
VG Name vg_critical
LV UUID Nr62xe-Zu7d-0u3z-Yyyp-7Cj1-Ej2t-gw04Xd
LV Write Access read/write
LV Creation host, time debian, 2022-03-01 00:17:46 +0100
LV Status available
# open 0
LV Size 5.00 GiB
Current LE 1280
Segments 2
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0
#
lvcreate -n lv_base -L 1G vg_critical
Logical volume "lv_base" created.
#
lvcreate -n lv_backups -L 11.98G vg_normal
Rounding up size to full physical extent 11.98 GiB
Rounding up size to full physical extent 11.98 GiB
Logical volume "lv_backups" created.
#
lvdisplay -C
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_base vg_critical -wi-a----- 1.00g
lv_files vg_critical -wi-a----- 5.00g
lv_backups vg_normal -wi-a----- 11.98g
При создании логических томов обязательны два параметра; они должны быть переданы lvcreate
как опции. Имя создаваемого LV указывается с опцией -n
, а его размер обычно указывается с опцией -L
. Конечно, нужно ещё указать имя VG, который следует использовать, отсюда последний параметр командной строки.
Созданные логические тома появляются как блочные устройства в /dev/mapper/
:
#
ls -l /dev/mapper
total 0
crw------- 1 root root 10, 236 Mar 1 00:17 control
lrwxrwxrwx 1 root root 7 Mar 1 00:19 vg_critical-lv_base -> ../dm-1
lrwxrwxrwx 1 root root 7 Mar 1 00:17 vg_critical-lv_files -> ../dm-0
lrwxrwxrwx 1 root root 7 Mar 1 00:19 vg_normal-lv_backups -> ../dm-2
#
ls -l /dev/dm-*
brw-rw---- 1 root disk 253, 0 Mar 1 00:17 /dev/dm-0
brw-rw---- 1 root disk 253, 1 Mar 1 00:19 /dev/dm-1
brw-rw---- 1 root disk 253, 2 Mar 1 00:19 /dev/dm-2
Для облегчения жизни также создаются символические ссылки в каталогах, соответствующих VG:
#
ls -l /dev/vg_critical
total 0
lrwxrwxrwx 1 root root 7 Mar 1 00:19 lv_base -> ../dm-1
lrwxrwxrwx 1 root root 7 Mar 1 00:17 lv_files -> ../dm-0
#
ls -l /dev/vg_normal
total 0
lrwxrwxrwx 1 root root 7 Mar 1 00:19 lv_backups -> ../dm-2
LV можно использовать в точности как обычные разделы:
#
mkfs.ext4 /dev/vg_normal/lv_backups
mke2fs 1.46.2 (28-Feb-2021)
Discarding device blocks: done
Creating filesystem with 3140608 4k blocks and 786432 inodes
Filesystem UUID: 7eaf0340-b740-421e-96b2-942cdbf29cb3
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
#
mkdir /srv/backups
#
mount /dev/vg_normal/lv_backups /srv/backups
#
df -h /srv/backups
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_normal-lv_backups 12G 24K 12G 1% /srv/backups
#
[...]
[...]
#
cat /etc/fstab
[...]
/dev/vg_critical/lv_base /srv/base ext4 defaults 0 2
/dev/vg_critical/lv_files /srv/files ext4 defaults 0 2
/dev/vg_normal/lv_backups /srv/backups ext4 defaults 0 2
С точки зрения приложений, множество маленьких разделов теперь представлены в виде одного 12-гигабайтного тома с удобным именем.
Хотя возможность объединять разделы или физические диски и удобна, не она является главным преимуществом LVM. Её гибкость особенно заметна с течением времени, когда возникают потребности в изменениях. Допустим, что в нашем примере возникла потребность в сохранении новых больших файлов, и что LV, выделенный файловому серверу, слишком мал для них. Поскольку мы использовали не всё пространство, доступное на vg_critical
, мы можем увеличить lv_files
. Для этого мы используем команду lvresize
, затем resize2fs
чтобы соответствующим образом подогнать файловую систему:
#
df -h /srv/files/
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_files 4.9G 4.2G 485M 90% /srv/files
#
lvdisplay -C vg_critical/lv_files
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_files vg_critical -wi-ao---- 5.00g
#
vgdisplay -C vg_critical
VG #PV #LV #SN Attr VSize VFree
vg_critical 2 2 0 wz--n- 7.99g 1.99g
#
lvresize -L 6G vg_critical/lv_files
Size of logical volume vg_critical/lv_files changed from 5.00 GiB (1280 extents) to 6.00 GiB (1536 extents).
Logical volume vg_critical/lv_files successfully resized.
#
lvdisplay -C vg_critical/lv_files
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_files vg_critical -wi-ao---- 6.00g
#
resize2fs /dev/vg_critical/lv_files
resize2fs 1.46.2 (28-Feb-2021)
Filesystem at /dev/vg_critical/lv_files is mounted on /srv/files; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/vg_critical/lv_files is now 1572864 (4k) blocks long.
#
df -h /srv/files/
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_files 5.9G 4.2G 1.5G 75% /srv/files
Мы могли бы, действуя тем же образом, расширить том, на котором размещается база данных, только мы достигли предела доступного места на VG:
#
df -h /srv/base/
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_base 974M 883M 25M 98% /srv/base
#
vgdisplay -C vg_critical
VG #PV #LV #SN Attr VSize VFree
vg_critical 2 2 0 wz--n- 7.99g 1016.00m
Это не имеет значения, поскольку LVM позволяет добавлять физические тома в существующие группы томов. Например, мы заметили, что на разделе sdb3
, использовавшемся вне LVM, размещались только архивы, которые можно переместить на lv_backups
. Теперь можно утилизировать его и ввести в группу томов, тем самым восстановив доступное пространство. Для этой цели существует команда vgextend
. Само собой, раздел должен быть предварительно подготовлен как физический раздел. Когда VG расширена, мы можем использовать такие же команды, как и раньше, для увеличения логического тома, а затем файловой системы:
#
pvcreate /dev/sdb3
Physical volume "/dev/sdb3" successfully created.
#
vgextend vg_critical /dev/sdb3
Volume group "vg_critical" successfully extended
#
vgdisplay -C vg_critical
VG #PV #LV #SN Attr VSize VFree
vg_critical 3 2 0 wz--n- <12.99g <5.99g
#
lvresize -L 2G vg_critical/lv_base
[...]
#
resize2fs /dev/vg_critical/lv_base
[...]
#
df -h /srv/base/
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_base 2.0G 886M 991M 48% /srv/base
Как RAID, так и LVM предоставляют бесспорные преимущества как только мы выходим за рамки простейшего случая настольного компьютера с одним жёстким диском, где схема использования не меняется с течением времени.
Есть несколько простых примеров, где вопрос выбора не встаёт. Если требуется защитить данные от аппаратных сбоев, безусловно следует создать RAID на избыточном дисковом массиве, ведь LVM просто не предназначен для решения этой проблемы. Если, с другой стороны, требуется гибкая система хранения, где тома не зависят от реальных физических дисков, RAID мало чем поможет, и естественно выбрать LVM.
Третий характерный случай — когда хочется просто объединить два диска в один том из соображений производительности или чтобы иметь единую файловую систему, которая больше любого из доступных дисков. В этом случае подходят как RAID-0 (или даже linear-RAID), так и том LVM. В такой ситуации, если нет дополнительных ограничений (вроде унификации с другими компьютерами, на которых используется только RAID), более предпочтительным часто является выбор LVM. Начальная настройка несколько более сложна, но это небольшое увеличение сложности более чем покрывается дополнительной гибкостью, которую привнесёт LVM, если потребности изменятся, или если понадобится добавить новые диски.
Ну и конечно, есть ещё по-настоящему интересный случай, когда систему хранения нужно сделать одновременно устойчивой к аппаратным сбоям и гибкой, когда дело доходит до выделения томов. Ни RAID, ни LVM не могут удовлетворить обоим требованиям сами по себе; не страшно, в этом случае мы используем их одновременно — точнее, одно поверх другого. Схема, включающая всё и ставшая стандартом с тех пор, как RAID и LVM достигли стабильности, заключается в обеспечении сначала избыточности группировкой дисков в небольшое число RAID-массивов и использовании этих массивов в качестве физических томов LVM; логические разделы будут потом выделяться из этих LV для файловых систем. Преимущество такой настройки заключается в том, что при отказе диска потребуется пересобрать только небольшое число RAID-массивов, тем самым экономя время, которое потребуется администратору на восстановление.
Возьмём конкретный пример: отделу связей с общественностью Falcot Corp требуется рабочая станция для редактирования видео, но бюджет отдела не позволяет приобрести полный комплект оборудования класса high-end. Решено отдать предпочтение оборудованию, специфичному для работы с графикой (монитору и видеокарте), а для хранения использовать оборудование общего назначения. Однако, как общеизвестно, цифровое видео предъявляет определённые требования к хранилищу: объём данных велик, а скорость чтения и записи важна для производительности системы в целом (больше чем типичное время доступа, к примеру). Эти требования должны быть удовлетворены с помощью обычного оборудования, в данном случае двух жёстких дисков SATA объёмом по 300 ГБ; также необходимо сделать системные данные устойчивыми к аппаратным сбоям, в то время как обрабатываемое видео менее важно, поскольку оно ещё записано на видеокассеты.
Чтобы удовлетворить этим требованиям, совмещены RAID-1 и LVM. Диски подключены к двум разным SATA-контроллерам для оптимизации параллельного доступа и снижения риска одновременного отказа, поэтому они представлены как sda
и sdc
. Они размечены одинаково по следующей схеме:
#
sfdisk -l /dev/sda
Disk /dev/sda: 894.25 GiB, 960197124096 bytes, 1875385008 sectors
Disk model: SAMSUNG MZ7LM960
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: BB14C130-9E9A-9A44-9462-6226349CA012
Device Start End Sectors Size Type
/dev/sda1 2048 4095 2048 1M BIOS boot
/dev/sda2 4096 100667391 100663296 48G Linux RAID
/dev/sda3 100667392 134221823 33554432 16G Linux RAID
/dev/sda4 134221824 763367423 629145600 300G Linux RAID
/dev/sda5 763367424 1392513023 629145600 300G Linux RAID
/dev/sda6 1392513024 1875384974 482871951 230.3G Linux LVM
Первые разделы обоих дисков — это загрузочные разделы BIOS.
Следующие два раздела sda2
and sdc2
(около 48 ГБ) собираются в том RAID-1, md0
. Это зеркало напрямую используется для хранения корневой файловой системы.
Разделы sda3
и sdc3
разделы собираются в том RAID-0, md1
, и используются в качестве раздела подкачки, обеспечивая в общей сложности 32 ГБ пространства подкачки. Современные системы могут обеспечить достаточно оперативной памяти, и нашей системе не понадобится спящий режим. Таким образом, с добавлением этой суммы в нашей системе вряд ли закончится память.
Разделы sda4
и sdc4
, как и sda5
с sdc5
, собраны в два новых тома RAID-1, примерно по 300 ГБ каждый, md2
и md3
. Оба эти зеркала инициализированы как физические тома LVM, и добавлены в группу томов vg_raid
. Таким образом эта VG содержит около 600 ГБ надёжного пространства.
Остальные разделы, sda6
и sdc6
, напрямую используются как физические тома, и добавлены в другую VG под названием vg_bulk
, которая поэтому содержит приблизительно 460 ГБ пространства.
После создания VG можно разбить их весьма гибким образом. Следует помнить, что LV, созданные на vg_raid
будут сохранны даже если один из дисков выйдет из строя, чего нельзя сказать о LV, созданных на vg_bulk
; с другой стороны, последние будут размещаться параллельно на обоих дисках, что обеспечит более высокие скорости чтения и записи больших файлов.
По этой причине мы создадим LV lv_var
и lv_home
на vg_raid
для размещения соответствующих файловых систем; другой большой LV, lv_movies
, будет использоваться для размещения окончательных версий роликов после редактирования. Другая VG будет разбита на большой lv_rushes
для данных, захваченных с видеокамер, и lv_tmp
для временных файлов. Размещение рабочей области — не такой простой выбор: в то время как для этого тома нужна хорошая производительность, стоит ли она риска потери работы, если диск выйдет из строя во время сессии? В зависимости от ответа на этот вопрос соответствующий LV следует создать на одной VG или на другой.
Теперь у нас есть некоторая избыточность для важных данных и большая гибкость в распределении доступного пространства между приложениями.