Einrichten eines Raid 0 oder 1 mithilfe von mdadm

Ein Software-Raid unter Linux zu erstellen, ist keine Hexerei. Wenn man einmal das Prinzip und die Funktionsweise eines Raid-Arrays verstanden hat, so ist es gar nicht schwer, Linux auf einem Raid-Array zu installieren oder ein bestehendes Linux-System in ein Raid-System zu migrieren.

In diesem Artikel wird beschrieben, wie man ein bestehendes Linux-Betriebssystem aus dem laufenden Betrieb in ein Raid-0 bzw Raid-1-System konvertiert. Anhand einiger Tests und Benchmarks sollen die Vorteile eines Raids verdeutlicht werden.

Hinweis: Sicherheitshalber sollte man ein Backup des Systems erstellen. Hier bieten sich Festplattenprogramme wie Acronis TrueImage oder Norton Ghost an. Außerdem sollte man bei jedem Befehl wissen, was man tut. Man sollte sich daher stets die Manpage des jeweiligen Programms zur Rate ziehen!

Raid-Grundlagen

Man unterscheidet grundlegend zwischen einem Software- und einem Hardware-Raid. Letzterer wird wie der Name schon sagt von einer bestimmten Hardware, dem so genannten Raid-Controller verwaltet. Hierbei handelt es sich um eine (meist teure) Steckkarte, an welche die Festplatten angeschlossen werden. Das Raid wird hier vom Hardware-Controller erstellt.

Beim Software-Raid wird kein Hardware-Controller gebraucht. Hier übernimmt das Betriebssystem die Verwaltung des Raid-Array. Somit entstehen keine weitere Kosten und die eingebauten Festplatten können zu einem Raid zusammengeschlossen werden.

Raid-0 (Striping, Performance steigern)

Bei einem Raid 0 werden die Daten abwechselnd auf beide oder mehrere Festplatten verteilt geschrieben. Somit wird die Performance nahezu verdoppelt, da die Daten auf die Festplatten-Laufwerke verteilt werden. Bildlich gesehen würde eine 5 GB Datei in zwei 2,5 GB Dateien Stücken auf beide Festplatten geteilt. Dieses erhöht natürlich den Datenausfall. Fällt eine Festplatte aus, so sind die Daten komplett gelöscht ("der 5 GB Datei fehlt die Hälfte").

Raid 0 Linux

Raid-1 (Spiegelung, Datensicherheit)

Raid-1 ist für Datensicherheit konzipiert worden. Hier werden die Daten doppelt gespeichert, so dass auf beiden oder mehreren Festplatten derselbe Inhalt vorhanden ist. Fällt eine der Festplatten aus, so funktioniert das System weiter, da auf der zweiten Festplatte die Daten weiterhin vorhanden sind.

Raid 1

Hinweis: Genauere Informationen zum Thema Raid findet man hier https://www.pc-erfahrung.de/hardware/hardware-raid.html

Ausgangssituation

Das für dieses How-To genutzte Linux-System basiert auf einer normalen IDE-Festplatte, welche in drei Partitionen aufgeteilt ist:

/dev/hda1               /boot           ext2            auto,rw         1 2
/dev/hda3               /               reiserfs        noatime         0 1
/dev/hda2               none            swap            sw              0 0

Ziel ist es nun, eine weitere Festplatte in das System einzubauen und beide Festplatten aus dem laufenden Betrieb heraus in ein Raid-Array zu migrieren.

Voraussetzungen

Der Kernel muss natürlich mit Raid-Unterstützung kompiliert sein. Ist Raid nicht in den Kernel kompiliert, so reicht es, die benötigten Raid-Komponenten als Module zu kompilieren und zu laden:

#cd /usr/src/linux && make menuconfig

-> Device Drivers
 -> Multi-device support (RAID and LVM)
  -> Multiple devices driver support (RAID and LVM)
   -> RAID support

// Module laden

modprobe raid1
modprobe raid0
modprobe raid5

Linux Software-Raid-1 erstellen

Nachdem eine weitere Festplatte an den Secondary Master angeschlossen wurde, so dass wir die Gerätedatei /dev/hdc erhalten, können wir mit der Einrichtung des Raid-Arrays beginnen. Aus Performance-Gründen sollte bei einem Raid-Array die Festplatten an unterschiedlichen Controllern angeschlossen werden, ansonsten wird der Datendurchsatz durch das IDE-Kabel gedrosselt.

Nun muss die Partitionstabelle der aktiven Festplatte auf die neue Festplatte kopiert werden, damit wir eine Kopie der Partitionstabelle erhalten. Anschließend können wir mit fdisk alle Partitionen als "Linux Raid Autodetected" deklarieren. Somit erkennt der Linux-Kernel beim Booten, dass es sich bei den Partitionen um ein Raid-Array handelt:

dd if=/dev/hda of=/dev/hdc count=1
fdisk /dev/hdc
Command (m for help): t
Partition number (1-3): 1
Hex code (type L to list codes): fd
Changed system type of partition 1 to fd (Linux raid autodetect)

Zu diesem Zeitpunkt haben wir die zweite, noch nicht genutzte Partition für das Raid vorbereitet. Das Problem, das jetzt besteht, liegt darin, dass wir die aktiven Partitionen nicht einfach als Raid deklarieren können, da sie noch in Gebrauch ist. Dazu benutzen wir folgenden Trick: Das neue Raid-Array wird nur mit der neuen Festplatte initialisiert. Die zweite Raid-Platte wird als "missing" deklariert.

// Raid initialisieren
// missing ist Platzhalter für die aktive Festplatte
// -l 1 steht Raid-1
// -n 2 steht für zwei Raid-Devices

mdadm -C /dev/md0 -l 1 -n 2 missing /dev/hdc1
mdadm -C /dev/md1 -l 1 -n 2 missing /dev/hdc2
mdadm -C /dev/md2 -l 1 -n 2 missing /dev/hdc2

Wichtig ist, dass ein Raid für Partitionen gesetzt wird und nicht die ganze Festplatte. Es ist beispielsweise möglich, ein Mischbetrieb zu betreiben, beispielsweise hda1 und hda2 bleiben normal und nur hda3 wird gespiegelt. Nun kann ein Dateisystem auf den Raid-Partitionen erstellt werden.

mkfs.ext2 /dev/md0
mkswap /dev/md1
swapon /dev/md1
mkreiserfs /dev/md2

Zu diesem Zeitpunkt haben wir bereits ein aktives Raid mit erstellten Dateisystemen. Die Partitionen erreichen wir nun über /dev/md0, /dev/md1, /dev/md2. Nun kopieren wir den Inhalt von /dev/hda1 (/boot) nach /dev/md0:

mkdir /mnt/quelle
mkdir /mnt/ziel

// /boot nach md0 kopieren
mount /dev/hda1 /mnt/quelle
mount /dev/md0 /mnt/ziel
rsync -avH --progress /mnt/quelle /mnt/ziel

umount /mnt/quelle
umount /mnt/quelle

// Root-Verzeichnis nach md2 kopieren
mount /dev/hda3 /mnt/quelle
mount /dev/md2 /mnt/ziel
rsync -avH --progress /mnt/quelle/ /mnt/ziel/

Nach der Kopie der aktiven Festplatte auf das Raid-Array können wir den Neustart vorbereiten. Nach dem Neustart soll von dem Raid-Array gebootet werden. Dazu muss der Bootloader und die Datei /etc/fstab angepasst werden. Natürlich müssen die Änderungen auf dem Raid-Array vorgenommen werden, also vi /etc/ziel/etc/fstab!

Hinweis: Grub kann nur auf physikalische Partitionen und nicht auf Raid-Partitionen zugreifen. Daher müssen wir in der grub.conf als Boot-Partition weiterhin /dev/hda angeben.

// /etc/fstab

/dev/md0               /boot           ext2            auto,rw         1 2
/dev/md1               /               reiserfs        noatime         0 1
/dev/md2               none            swap            sw              0 0

// /boot/grub/grub.conf

title GENTOO [2.6.20]
root (hd0,0)
kernel (hd0,9)/gentoo-2.6.20.1 root=/dev/md2

Und zu guter letzt muss noch der Bootloader auf der zweiten Festplatte installiert werden:

grub> find /boot/grub/stage1
(hd0,0)
(hd1,0)
grub>
device (hd0) /dev/hdc
root (hd0,0)
setup (hd0)

Neustart des Systems

Nach dem Neustart des Systems bootet Linux nun von dem Raid-Array. Wir können dieses mit folgendem Befehl überprüfen:

cat /proc/mdstat

md1 : active raid1 hdc2[1] hda2[0]
505920 blocks [2/2] [UU]

md2 : active raid1 hdc3[1] hda3[0]
77063552 blocks 64k chunks

md0 : active raid1 hdc1[1] hda1[0]
40064 blocks [2/2] [UU]

Hieraus können wir erkennen, um welches Raid-Level es sich handelt und welche Partitionen diesem Raid-Array angehören. Die Ziffern in den eckigen Klammern geben, ob und wieviele Partitionen aktiv vorhanden sind.

Nun müssen wir die erste Festplatte, die bis vor dem Neustart die aktive Festplatte war, in das Raid mit aufnehmen. Dazu tippen wir folgendes ein:

mdadm /dev/md0 -a /dev/hda1
mdadm /dev/md2-a /dev/hda3

In der /proc/mdstat kann man sich nun den aktuellen Status der Synchronisation anschauen:

Personalities : [raid1]
md2 : active raid1 hdc3[1] hda3[0]
184859840 blocks [2/2] [UU]
[======>..............] resync = 33.1% (61296896/184859840) finish=34.3min speed=59895K/sec

Nach der Synchronisation haben wir ein aktives Raid-1-Array vorliegen. Nun kann eine der beiden Festplatten ausfallen, ohne dass Daten verloren gehen oder sich das System aufhängt. In diesem Test wurde im laufenden Betrieb die Stromzufuhr einer Festplatte unterbrochen. Trotzdem lief das System weiter. In der /proc/mdstat konnte man dann die Änderungen sehen.

Linux Software-Raid-0 erstellen

Bei einem Raid-0 werden die Partitionen nicht gespiegelt, sondern mittels Striping die Leistungsfähigkeit verdoppelt. Da bei einem Raid-0 alle Devices vorhanden sein müssen, können wir das Raid-0 nicht über den Trick mit dem fehlenden Device (missing) erstellen. Um ein aktives System in ein Raid-0 zu konvertieren, müssen wir zwei zusätzliche Festplatten in den Rechner einbauen. Ziel ist es, von dem aktiven Single-System zu booten, das Raid-Array mit den beiden neuen Festlatten zu erstellen, das aktive System mittels rsync auf das neue Raid zu kopieren, um anschließend von dem Raid-0 zu booten.

Booten von Raid-0. Ist das möglich?

In diesem Artikel handelt es sich bekanntlich um ein Linux-System mit den Partitionen hda1 (/boot), hda2 (swap) und hda3 (/). Der Bootloader Grub ist nicht in der Lage, von einer Raid-Partition zu booten und daher bootet Grub immer direkt vom physikalischen Device. Bei einem Raid-1 wird Grub auch auf jeder installierten Festplatte installiert, so dass beim Ausfall einer Festplatte von der anderen gebootet werden kann.

Beim Raid-0 ist das anders: wenn wir die Boot-Partition als Raid-0 deklarieren, liegen Boot-Dateien (Kernel, grub.conf,etc) gesplittet auf beiden Partitionen. Grub ist nicht in der Lage, auf das Raid-0 zuzugreifen, so dass ein Booten unmöglich ist.

Die Lösung des Problems ist, dass die Boot-Partition als Raid-1, die beiden anderen Partitionen als Raid-0 deklariert werden. Somit wird die Boot-Partition gespiegelt, Grub kann auf die physikalische Partition zugreifen und die Swap- bzw. Root-Partition kommen in den Genuss des Stripings.

Wichtig beim Raid-0 ist, dass die beiden Festplatten an unterschiedlichen IDE-Controllern hängen, also beispielsweise /dev/hda und /dev/hdc. Ansonsten kann die volle Leistungssteigerung nicht ausgenutzt werden. In dieser Anleitung hängt die aktive Single-Festplatte an /dev/hdb, die beiden Raid-Festplatten an /dev/hda und /dev/hdc. Die Vorgehensweise ist nun ähnlich wie bei Raid-1:

// Raid initialisieren
// md0 = Raid-1 (/boot)
// md1 = Raid-0 (swap)
// md2 = Raid-0 (/)

mdadm -C /dev/md0 -l 1 -n 2 /dev/hda1 /dev/hdc1
mdadm -C /dev/md1 -l 0 -n 2 /dev/hda2 /dev/hdc2
mdadm -C /dev/md2 -l 0 -n 2 /dev/hda3 /dev/hdc2

Und nun müssen die Dateisysteme wie gewohnt angelegt.

mkfs.ext2 /dev/md0
mkswap /dev/md1
swapon /dev/md1
mkreiserfs /dev/md2

Und nun wieder das aktuelle System auf das neu erstellte Raid kopieren:

mkdir /mnt/quelle
mkdir /mnt/ziel

// /boot nach md0 kopieren
mount /dev/hda1 /mnt/quelle
mount /dev/md0 /mnt/ziel
rsync -avH --progress /mnt/quelle/ /mnt/ziel/

umount /mnt/quelle
umount /mnt/quelle

// Root-Verzeichnis nach md2 kopieren
mount /dev/hda3 /mnt/quelle
mount /dev/md2 /mnt/ziel
rsync -avH --progress /mnt/quelle/ /mnt/ziel/

Auch beim Raid-0 installieren wir den Bootloader Grub wieder auf beide Festplatten:

#grub
device (hd0) /dev/hda
root (hd0,0)
setup (hd0)

device (hd0) /dev/hdc
root (hd0,0)
setup (hd0)

Nachdem die Dateien /boot/grub/grub.conf und /etc/fstab, welche sich auf dem Raid-Array befinden, angepasst wurden, kann das System neugestartet werden

Benchmarks Raid-0, Raid-1

Ausgangssituation:
==================
Pluto chef # hdparm -tT /dev/hda

/dev/hda:
Timing cached reads: 642 MB in 2.00 seconds = 320.52 MB/sec
Timing buffered disk reads: 26 MB in 3.28 seconds = 7.93 MB/sec
Pluto chef # hdparm -d /dev/hda

/dev/hda:
using_dma = 1 (on)

Die Festplattenleistung kann mittels hdparm gemessen werden. Im "Single-Drive-Modus" schafft die Festplatte eine Leseleistung von rund 7,93 MB pro Sekunde.

Raid 1
======
Pluto chef # hdparm -tT /dev/md2

/dev/md2:
Timing cached reads: 594 MB in 2.00 seconds = 296.52 MB/sec
Timing buffered disk reads: 26 MB in 3.11 seconds = 8.37 MB/sec

Die Spiegelung sorgt natürlich nicht für eine Leistungssteigerung, was in diesem Benchmark deutlich wird. Die Leseleistung liegt bei knapp 8,37 MB pro Sekunde.

Raid 0 (an einem Controller)
========================

Pluto chef # hdparm -tT /dev/md2

/dev/md2:
Timing cached reads: 624 MB in 2.00 seconds = 311.30 MB/sec
Timing buffered disk reads: 44 MB in 3.03 seconds = 14.53 MB/sec

Raid-0 sorgt dafür, dass die Leseleistung auf 14,53 MB quasi verdoppelt wird. Dieser Wert ist noch nicht optimal, da beide Festplatten an einem Controller angeschlossen wurden!

Raid 0
======
Pluto chef # hdparm -tT /dev/md2

/dev/md2:
Timing cached reads: 620 MB in 2.01 seconds = 309.22 MB/sec
Timing buffered disk reads: 72 MB in 3.05 seconds = 23.63 MB/sec

Optimale Ergebnisse erzielt man, indem man die Festplatten am Primary und Secondary Master anschließt. In diesem Fall konnte die Leseleistung auf 23,63 MB pro Sekunge gesteigert werden.