Een NAS of homeserver is een populaire oplossing om je bestanden vanaf alle apparaten in je thuisnetwerk te benaderen. Uiteraard wil je jezelf zo goed mogelijk beschermen tegen dataverlies. Met RAID kan je de impact van schijfdefecten minimaliseren.

RAID is een technologie die al tientallen jaren bestaat en zijn oorsprong vindt in de bedrijfswereld. Betrouwbare schijven waren vroeger erg duur, en  ging men op zoek naar meer betaalbare oplossingen. Zo kwam men op het idee om verschillende goedkope schijven te combineren tot een enkele schijf. Dit leidde tot de naam Redundant Array of Inexpensive Disks, ofwel RAID.  De individuele schijven gingen sneller stuk, maar een defecte schijf kon eenvoudig vervangen worden, zonder dat dit dataverlies tot gevolg had. Er was immers een kopie van de verloren data beschikbaar op minstens één van de andere schijven in de RAID-array. RAID is een overkoepelende term voor erg uiteenlopende schijfconfiguraties, ook wel RAID-levels genoemd. Het doel van de verschillende RAID-levels is echter steeds hetzelfde: de beschikbaarheid en/of de prestaties van een opslagapparaat verbeteren. Vroeger had je een extra hardware controller nodig om met RAID aan de slag te gaan, maar intussen bestaan er ook verschillende software-implementaties, zoals Linux’ md (multiple device) device driver. Het gebruik van software-RAID heeft wel een impact op de systeemprestaties. Een hardware RAID-controller heeft dat probleem niet, want die beschikt over een eigen cpu. Anderzijds is de overhead van software-RAID met de huidige multicore-processors gelukkig erg klein geworden. Voor thuisgebruik voldoet software-RAID tegenwoordig dus prima.

RAID-levels
In dit artikel focussen we op RAID-configuraties die een goede bescherming bieden tegen schijfdefecten. Niet alle door Linux ondersteunde RAID-levels komen daarvoor in aanmerking. Zo is RAID0 – ook wel striping genoemd – uitsluitend bedoeld om de schijfprestaties te verhogen. Schrijf je bijvoorbeeld een bestand van 2GB weg naar een RAID0-array met twee schijven, dan wordt er op iedere schijf 1GB bewaard. Omdat Linux voor elke lees- of schrijfactie twee schijven tegelijk kan gebruiken, verdubbelen de doorvoersnelheden bijna. Maar ook de kans op dataverlies verdubbelt: zodra één schijf defect is, ben je immers al je data kwijt. RAID0 is eigenlijk niet zo interessant voor thuisgebruik: als bootschijf raden we je absoluut aan om een SSD te gebruiken. Dat is veel betrouwbaarder én sneller dan een RAID0- array ooit.

RAID1 of mirroring biedt de beste beveiliging tegen schijfdefecten. In een RAID1-array wordt alle data immers volledig weggeschreven op elke schijf. Bij een schijfdefect verlies je dus geen data, aangezien de tweede schijf een identieke kopie ervan bevat. De schrijfsnelheden veranderen niet: de doorvoersnelheid van één schijf blijft immers de bottleneck. Maar net als bij RAID0 verdubbelen de leessnelheden, aangezien de data van twee schijven tegelijk kan ingelezen worden. Het grootste nadeel? Door het mirroring-principe wordt de beschikbare schijfruimte effectief gehalveerd. Op twee schijven van 2TB kan je dus alleen 2TB aan data opslaan, en dus geen 4TB.

Grotere arrays

RAID5 positioneert zich qua functionaliteit tussen RAID0 en RAID1 en heeft minstens drie schijven nodig. De data wordt verdeeld over de eerste twee schijven (net als bij RAID0) en de derde schijf bevat een pariteitsbit. Met die bit kan de ontbrekende data van de eerste óf de tweede schijf opnieuw berekend worden, mocht één van de schijven stukgaan. De pariteits-bit wordt trouwens afwisselend op elke schijf bewaard (zie afbeelding 1), zodat er geen bottlenecks ontstaan. RAID5 is een goedkopere oplossing dan RAID1: per array (ongeacht de grootte) wordt slechts één schijf voor redundantie gebruikt. In een array met 7 schijven van 2TB kun je dus 12TB effectief gebruiken. Door de striping zijn de leessnelheden erg goed, maar de schrijfsnelheden liggen merkelijk lager dan bij RAID0. De pariteits-bit berekenen is immers redelijk processorintensief.

Let wel op als je een grote RAID5-array wil maken zoals in het voorbeeld hierboven. Tijdens het herstellen van zo’n array na een schijfdefect moet alle data op de schijven immers volledig ingelezen worden. Dat duurt niet alleen erg lang, de kans is ook reëel dat je tijdens die rebuild een Unrecoverable Read Error – URE – tegenkomt. In dat geval ben je mogelijk de volledige RAID-array kwijt, omdat de md-driver van Linux nu denkt dat er twee schijven tegelijk kapot zijn. Om dat risico te vermijden is RAID6 een betere keuze. Die RAID-configuratie werkt met twee pariteits-bits. In een RAID6-array van 7 schijven kun je dan maar 5 schijven effectief gebruiken, maar die array overleeft wel een URE tijdens een rebuild.

Geen back-up
Belangrijk om te weten: RAID is géén alternatief voor back-ups! Heb je een bestand op een RAID1- array per ongeluk gewist of overschreven? Dan kun je beter een goede back-up bij de hand hebben, want anders is dat bestand reddeloos verloren! Heb je slechts een beperkt budget om er schijven bij te kopen? Koop dan liever een extra schijf die je gebruikt om back-ups op te slaan alvorens in een RAID-array te investeren. Van alle RAID-setups is RAID1 de beste keuze voor data die je absoluut niet mag verliezen. Zonder RAID1 kun je immers nog steeds data verliezen in de periode tussen twee back-ups. RAID5 en RAID-6 zijn economisch interessantere alternatieven om grote hoeveelheden data te bewaren. Is die data niet onmisbaar –(bijvoorbeeld als er downloads of rips van je cd- en dvd-collectie op staan – dan kun je zelfs overwegen om ze niet te back-uppen. De RAID-array biedt voldoende bescherming tegen schijfdefecten. Wis je per ongeluk een bestand, dan kun je die – in geval van audio – altijd opnieuw rippen of eventueel downloaden.

Aan de slag

Mogelijk moet je nog een extra pakket installeren om de software-RAID van Linux te gebruiken: in de meeste distributies wordt dat ‘mdadm’ genoemd. Dat is meteen ook het commando waarmee je RAID-arrays beheert. Je hebt natuurlijk schijven nodig om RAID-arrays aan te maken. Het is belangrijk dat alle schijven even groot zijn. Ook kun je het best eerst een partitie van het type ‘fd’ aanmaken (zie listing 1). Dat hoeft in principe niet, maar zo zie je tenminste in de fdisk-output dat de schijf deel uitmaakt van een RAID-array.

 

# fdisk /dev/sdb

Command (m for help): n

Partition type:

   p   primary (0 primary, 0 extended, 4 free)

   e   extended

Select (default p): p

Partition number (1-4, default 1): 1

First sector (2048-16777215, default 2048):

Using default value 2048

Last sector, +sectors or +size{K,M,G} (2048-16777215, default 16777215):

Using default value 16777215

Command (m for help): t

Selected partition 1

Hex code (type L to list codes): fd

Command (m for help): w

The partition table has been altered!

 

We beginnen met een RAID1-array. In ons voorbeeld gebruiken we virtuele schijven van 8GB, maar dat maakt voor de rest niets uit. mdadm kent verschillende commando’s: gebruik mdadm –help voor een overzicht of mdadm –<commando> –help voor meer uitleg over een specifiek commando. Een array aanmaken doe je met het create-commando, waarbij je de gewenste RAID-level en de individuele devices opgeeft. In listing 2 zie je hoe we een RAID1 array /dev/md0 aanmaken met de partities /dev/sdb1 en /dev/sdc1. De status van alle arrays vind je in het bestand /proc/mdstat. Meer details over een specifieke array krijg je met het commando mdadm –detail <arraynaam>. Heb je de array nog maar net aangemaakt, dan moeten de schijven nog gesynchroniseerd worden. Je kan de RAID-array nu gebruiken door een bestandsysteem aan te maken op /dev/md0 en dat te mounten.

 

# mdadm –create /dev/md0 –level=1 –raid-devices=2 /dev/sdb1 /dev/sdc1

mdadm: array /dev/md0 started.

# cat /proc/mdstat

Personalities : [raid1]

md0 : active raid1 sdc1[1] sdb1[0]

      8383424 blocks super 1.2 [2/2] [UU]

      [=>……………….]  resync =  9.5% (800000/8383424) finish=0.6min speed=200000K/sec

# mkfs.ext4 /dev/md0

# mkdir /mnt/storage

# mount /dev/md0 /mnt/storage/

 

Op de meeste distributies worden RAID-arrays automatisch opgestart bij het booten. Is dat niet het geval, dan moet je de output van het commando ‘mdadm -Es’ toevoegen aan het bestand /etc/mdadm/mdadm.conf. Problemen met de RAID-array zoals een defecte schijf, worden trouwens via e-mail gerapporteerd. Het is dus erg belangrijk dat de mailserver op je systeem zo geconfigureerd is, dat e-mails voor de root-gebruiker worden doorgestuurd naar jouw e-mailadres. Raadpleeg de documentatie van je distributie als je niet weet hoe je dit moet doen. Ter volledigheid vermelden we ook nog even hoe je een RAID-array manueel start, stopt en verwijdert (zie listing 3). Die commando’s komen wellicht van pas als je gaat experimenteren met verschillende types RAID-array.

 

# mdadm –assemble –scan

mdadm: /dev/md/0 has been started with 2 drives.

# mdadm –stop /dev/md0

mdadm: stopped /dev/md0

# mdadm –remove /dev/md0

# mdadm –zero-superblock /dev/sd[bc]1

 

RAID1-beheer

Op een dag zal één van de schijven in je RAID1-array kapot gaan. Wil je niet wachten tot die dag om de herstelprocedure uit te proberen, dan kun je een schijf manueel als ‘failed’ markeren met mdadm. In de output van /proc/mdstat komt er dan een (F) achter de schijfnaam te staan. De array is nu degraded, wat aangeduid wordt met [2/1] [_U] in plaats van [2/2] [UU] op de regel eronder. De array herstellen doe je door een nieuwe schijf toe te voegen aan de array en de oude schijf te verwijderen (zie listing 4). Net zoals bij het aanmaken van de array moet de nieuwe schijf nog even gesynchroniseerd worden en klaar is kees.

 

# mdadm –fail /dev/md0 /dev/sdb1

mdadm: set /dev/sdb1 faulty in /dev/md0

# cat /proc/mdstat

md0 : active raid1 sdc1[1] sdb1[0](F)

      8383424 blocks super 1.2 [2/1] [_U]

# mdadm –add /dev/md0 /dev/sdd1

mdadm: added /dev/sdd1

# mdadm –remove /dev/md0 /dev/sdb1

mdadm: hot removed /dev/sdb1 from /dev/md0

# cat /proc/mdstat

md0 : active raid1 sdd1[2] sdc1[1]

      8383424 blocks super 1.2 [2/2] [UU]

 

Wat als je array te klein wordt? Extra schijven toevoegen heeft geen zin, want dat resulteert gewoon in meer kopieën van je data. Een eerste optie is om twee grotere schijven toe te voegen en de oorspronkelijke schijven nadien te verwijderen. Dat is een prima strategie om een array met bijvoorbeeld 1TB-schijven te upgraden naar 2TB-schijven. De precieze procedure vind je in listing 5. Wacht wel tot de array volledig gesynchroniseerd is voordat je de oude schijven verwijdert! Een andere optie is de RAID1-array om te zetten naar een RAID5-array en extra schijven van dezelfde grootte toe te voegen. Zo kan je de beschikbare ruimte naar wens uitbreiden, al moet je de nadelen van RAID5 er dan ook bijnemen. De beste oplossing is ongetwijfeld om meerdere RAID1-arrays via LVM te combineren tot één groot bestandssysteem. De verschillende arrays hoeven ook niet even groot te zijn: een oude 1TB-array uitbreiden met een nieuwe 2TB-array is perfect mogelijk. Op LVM komen we terug in het volgende nummer van Linux Magazine.

 

# mdadm –grow –raid-devices=4 /dev/md0 -a /dev/sde1 -a /dev/sdf1 

mdadm: added /dev/sde1

mdadm: added /dev/sdf1

raid_disks for /dev/md0 set to 4

# cat /proc/mdstat

md0 : active raid1 sdf1[4] sde1[3] sdd1[2] sdc1[1]

      8383424 blocks super 1.2 [4/4] [UUUU]

# mdadm –fail /dev/md0 /dev/sdc1 /dev/sdd1

mdadm: set /dev/sdc1 faulty in /dev/md0

mdadm: set /dev/sdd1 faulty in /dev/md0

# mdadm –remove /dev/md0 /dev/sdc1 /dev/sdd1

mdadm: hot removed /dev/sdc1 from /dev/md0

mdadm: hot removed /dev/sdd1 from /dev/md0

# cat /proc/mdstat

md0 : active raid1 sdf1[4] sde1[3]

      8383424 blocks super 1.2 [4/2] [__UU]

# mdadm –grow /dev/md0 –raid-devices=2

raid_disks for /dev/md0 set to 2

# mdadm –grow /dev/md0 –size=max

mdadm: component size of /dev/md0 has been set to 16772096K

# cat /proc/mdstat | grep blocks

      16772096 blocks super 1.2 [2/2] [UU]

# resize2fs /dev/md0

RAID5

Het beheer van een RAID5-array lijkt erg op dat van een RAID1-array. Het opvallendste verschil is dat je minstens drie schijven nodig hebt om te starten, al is dat strikt gezien niet verplicht. mdadm laat je immers ook een degraded RAID5-array aanmaken met slechts twee schijven. De array is natuurlijk pas redundant zodra je een derde schijf toevoegt. Zoals te zien is in listing 6 is het rebuilden van een RAID5-array een behoorlijk zware taak. Voor twee schijven van 8GB duurde dit al gauw 10 minuten in onze virtuele machine, terwijl dit voor een RAID1-array met twee schijven binnen de minuut gepiept was. Upgraden naar grotere schijven zoals in listing 5 is ook mogelijk voor RAID5. Maar het is natuurlijk gemakkelijker om gewoon extra schijven toe te voegen. Vergeet niet dat je voor erg grote arrays beter RAID6 kunt gebruiken. Gelukkig kun je met mdadm een bestaande RAID5-array omzetten naar RAID6. In listing 7 zie je een kort voorbeeld daarvan (voor meer informatie over de –back-up-file-optie verwijzen we je naar de mdadm-manpage).

# mdadm –create /dev/md0 –level=5 –raid-devices 3 /dev/sdb1 /dev/sdc1 missing

# cat /proc/mdstat

md0 : active (auto-read-only) raid5 sdc1[1] sdb1[0]

      16765952 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/2] [UU_]

# mdadm –add /dev/md0 /dev/sdd1

mdadm: added /dev/sdd1

# cat /proc/mdstat

md0 : active raid5 sdd1[3] sdc1[1] sdb1[0]

      16765952 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/2] [UU_]

      [=>……………….]  recovery =  8.1% (687244/8382976) finish=7.9min speed=16036K/sec

 

 

 

# mdadm –grow /dev/md0 –raid-devices=4 -a /dev/sde1

# cat /proc/mdstat

md0 : active raid5 sde1[4] sdd1[3] sdc1[1] sdb1[0]

      25148928 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU]

# mdadm –grow /dev/md0 –level=6 –raid-devices=5 -a /dev/sdf1 –back-up-file=/tmp/back-up

# cat /proc/mdstat

md0 : active raid6 sdf1[5] sde1[4] sdd1[3] sdc1[1] sdb1[0]

      25148928 blocks super 1.2 level 6, 512k chunk, algorithm 2 [5/5] [UUUUU]

 

We hopen dat je met bovenstaande voorbeelden goed op weg bent geholpen om je eigen RAID-array op te bouwen. Maar welke RAID-level je ook kiest, vergeet nooit om back-ups te maken van je data. RAID biedt immers alleen bescherming tegen defecte schijven, niét tegen menselijke fouten!