RAID opnieuw bekeken
In de tijd dat ik een beginnend servicetechnicus was en nauwelijks iets van systeembeheer afwist, was een van de weinige onderwerpen waarvan altijd werd verwacht dat we het door en door kenden RAID – Redundant Array of Inexpensive Disks. Het was het antwoord op al onze opslagproblemen. Met RAID konden we onze bestandssystemen groter schalen, betere doorvoer behalen en zelfs redundantie toevoegen, waardoor we het verlies van een schijf konden overleven, wat, zeker in die tijd, vrij regelmatig gebeurde. Met de opkomst van NAS- en SAN-opslagapparaten verdwijnt de vaardigheid om door te dringen tot het fysieke opslagniveau en dit aan te passen aan de behoeften van het betreffende systeem snel. Dit is geen goede zaak. Het feit dat we opslag verplaatsen naar externe apparaten verandert niets aan het feit dat we onze opslag fundamenteel moeten begrijpen en deze moeten configureren om aan de specifieke behoeften van onze systemen te voldoen.
Een misvatting die de afgelopen vijf tot tien jaar in het vakgebied lijkt te zijn ontstaan, is de overtuiging dat RAID op de een of andere manier een systeemback-up vertegenwoordigt. Dat is niet zo. RAID is een vorm van fouttolerantie. Back-up en fouttolerantie zijn conceptueel zeer verschillend. Back-up is ontworpen om je in staat te stellen te herstellen nadat een ramp heeft plaatsgevonden. Fouttolerantie is ontworpen om de kans op een ramp in de eerste plaats te verkleinen. Beschouw fouttolerantie als het bouwen van een hek aan de rand van een klif en back-up als het bouwen van een ziekenhuis aan de voet ervan. Je wilt eigenlijk nooit in een situatie terechtkomen zonder zowel een hek als een ziekenhuis, maar het zijn beslist verschillende dingen.
Zodra we RAID implementeren voor onze schijven, of deze nu lokaal zijn aangesloten of zich op een extern apparaat zoals een SAN bevinden, hebben we vandaag de dag vier belangrijke RAID-oplossingen om uit te kiezen voor bedrijven: RAID 1 (mirroring), RAID 5 (striping met pariteit), RAID 6 (striping met dubbele pariteit) en RAID 10 (mirroring met striping). Er zijn andere, zoals RAID 0, die alleen in zeldzame omstandigheden gebruikt zouden moeten worden, wanneer je je behoeften aan het schijfsubsysteem werkelijk begrijpt. RAID 50 en 51 worden eveneens gebruikt, maar veel minder vaak en zijn lang niet zo effectief. Tien jaar geleden waren RAID 1 en RAID 5 gangbaar, maar tegenwoordig hebben we meer opties.
Laten we de opties doornemen en enkele basisgetallen bespreken. In onze voorbeelden zullen we n gebruiken om het aantal schijven in onze array weer te geven en zullen we s gebruiken om de grootte van een individuele schijf weer te geven. Hiermee kunnen we de bruikbare opslagruimte van een array uitdrukken, waardoor vergelijkingen in termen van opslagcapaciteit eenvoudig worden.
RAID 1: Bij dit RAID-type worden schijven gemirrord. Je hebt twee schijven en ze doen alles tegelijkertijd samen, vandaar “mirroring”. Mirroring is uiterst stabiel omdat het proces zo eenvoudig is, maar het vereist dat je twee keer zoveel schijven aanschaft als je nodig zou hebben als je helemaal geen RAID zou gebruiken, aangezien je tweede schijf is gewijd aan redundantie. Het voordeel is dat je de zekerheid hebt dat elke bit die je naar schijf wegschrijft tweemaal wordt weggeschreven, voor jouw bescherming. Dus met RAID 1 wordt onze capaciteit berekend als (n*s/2). RAID 1 heeft als nadeel dat het minimale prestatiewinst biedt ten opzichte van schijven zonder RAID. De schrijfsnelheden zijn gelijk aan die van een systeem zonder RAID, terwijl de leessnelheden in de meeste situaties bijna twee keer zo snel zijn, aangezien de schijven tijdens leesbewerkingen parallel toegankelijk zijn om de doorvoer te verhogen. RAID 1 is beperkt tot sets van twee schijven.
RAID 5: Striping met enkele pariteit; bij dit RAID-type worden gegevens in een complexe stripe over alle schijven in de array weggeschreven, met een gedistribueerd pariteitsblok dat zich over alle schijven uitstrekt. Hierdoor is RAID 5 in staat een array van willekeurige grootte van drie of meer schijven te gebruiken en verliest het alleen de opslagcapaciteit die gelijk is aan één schijf aan pariteit, hoewel de pariteit gedistribueerd is en zich niet uitsluitend op één fysieke schijf bevindt. RAID 5 wordt vaak gebruikt vanwege de kostenefficiëntie, dankzij het ontbreken van verlies aan opslagcapaciteit in grote arrays. Anders dan bij mirroring vereist striping met pariteit dat er voor elke schrijf-stripe over de schijven een berekening wordt uitgevoerd, en dit veroorzaakt enige overhead. Daarom is de doorvoer niet altijd een vanzelfsprekende berekening en is deze sterk afhankelijk van de rekenkracht van het systeem dat de pariteitsberekening uitvoert. Het berekenen van de RAID 5-capaciteit is vrij eenvoudig, aangezien het simpelweg ((n-1)*s) is. Een RAID 5-array kan het verlies van een willekeurige enkele schijf in de array overleven.
RAID 6: Redundante striping met dubbele pariteit. RAID 6 is vrijwel identiek aan RAID 5, maar gebruikt twee pariteitsblokken per stripe in plaats van één, om aanvullende bescherming tegen schijfuitval mogelijk te maken. RAID 6 is een nieuwer lid van de RAID-familie en werd verscheidene jaren na de standaardisering van de andere niveaus toegevoegd. RAID 6 is bijzonder doordat het de uitval van twee willekeurige schijven binnen een array toelaat zonder gegevensverlies te lijden. Maar om dit extra niveau van redundantie te accommoderen, verliest een RAID 6-array de opslagcapaciteit die gelijk is aan twee schijven in de array en vereist het minimaal vier schijven. We kunnen de capaciteit van een RAID 6-array berekenen met ((n-2)*s).
RAID 10: Mirroring plus striping. Technisch gezien is RAID 10 een hybride RAID-type dat een set RAID 1-mirrors omvat die bestaan in een stripe zonder pariteit (RAID 0). Veel leveranciers gebruiken de term RAID 10 (of RAID 1+0) wanneer zij spreken over slechts twee schijven in een array, maar technisch gezien is dat RAID 1, aangezien striping pas kan plaatsvinden wanneer er minimaal vier schijven in de array zijn. Bij RAID 10 moeten schijven in paren worden toegevoegd, zodat er slechts een even aantal schijven in een array kan bestaan. RAID 10 kan het verlies van maximaal de helft van de totale set schijven overleven, maar met een maximaal verlies van één schijf uit elk paar. RAID 10 omvat geen pariteitsberekening, wat het een prestatievoordeel geeft ten opzichte van RAID 5 of RAID 6 en minder rekenkracht vereist om de array aan te sturen. RAID 10 levert de hoogste leesprestaties van elk gangbaar RAID-type, aangezien alle schijven in de array gelijktijdig kunnen worden gebruikt bij leesbewerkingen, hoewel de schrijfprestaties veel lager zijn. De capaciteitsberekening van RAID 10 is identiek aan die van RAID 1, (n*s/2).
In de hedendaagse onderneming is het zeldzaam dat een IT-afdeling een serieuze noodzaak heeft om een schijfconfiguratie buiten de hier genoemde vier te overwegen, ongeacht of software- dan wel hardware-RAID wordt geïmplementeerd. Traditioneel was de grootste zorg bij een beslissing over een RAID-array gebaseerd op de bruikbare capaciteit. Dit kwam doordat schijven duur en klein waren. Tegenwoordig zijn schijven zo groot dat opslagcapaciteit zelden een probleem is, althans niet zoals nog maar een paar jaar geleden, en zijn de kosten zodanig gedaald dat de aanschaf van de extra schijven die nodig zijn voor betere schijfredundantie over het algemeen van ondergeschikt belang is. Wanneer capaciteit schaars is, is RAID 5 een populaire keuze omdat het de minste opslagcapaciteit verliest in vergelijking met andere arraytypes, en in grote arrays is het opslagverlies verwaarloosbaar.
Tegenwoordig hebben we over het algemeen andere zorgen, voornamelijk gegevensveiligheid en prestaties. Een beetje extra uitgeven om gegevensbescherming te waarborgen zou een vanzelfsprekende keuze moeten zijn. RAID 5 heeft als nadeel dat het slechts één enkele schijf kan verliezen. In een array van slechts drie leden is dit slechts iets gevaarlijker dan de bescherming die RAID 1 biedt. We zouden het verlies van een willekeurige schijf van de drie kunnen overleven. Niet al te beangstigend in vergelijking met het verliezen van een van twee schijven. Maar hoe zit het met een grote array, bijvoorbeeld zestien schijven? Het feit dat we slechts één van de zestien schijven veilig kunnen verliezen, zou ons ertoe moeten brengen onze betrouwbaarheid wat grondiger in twijfel te trekken.
Dit is waar RAID 6 op de proppen kwam om het gat op te vullen. RAID 6, wanneer gebruikt in een grote array, introduceert een zeer klein verlies aan opslagcapaciteit en prestaties, terwijl het de zekerheid biedt dat twee willekeurige schijven verloren kunnen gaan. Voorstanders van het kamp van striping met pariteit zullen deze cijfers vaak aanhalen om het management gerust te stellen dat RAID 5/6 voldoende “waar voor zijn geld” kan bieden in opslagsubsystemen, maar er spelen andere factoren mee.
Vrijwel volledig over het hoofd gezien in discussies over RAID-betrouwbaarheid – een veel te zelden besproken onderwerp, dat het is – is de kwestie van de betrouwbaarheid van de pariteitsberekening. Bij RAID 1 of RAID 10 wordt er geen “berekening” uitgevoerd om een stripe met pariteit te creëren. Gegevens worden eenvoudigweg op een stabiele manier weggeschreven. Wanneer een schijf uitvalt, neemt zijn partner de last over en worden de schijfprestaties licht verminderd totdat de partner is vervangen. Er is geen herstelproces dat invloed heeft op de bestaande schijfleden. Dat is niet het geval bij pariteits-stripes.
RAID-arrays met pariteit hebben bewerkingen waarbij wordt berekend wat er op de schijven staat en wat er zou moeten staan. Hoewel deze berekening zeer eenvoudig is, biedt zij een gelegenheid voor zaken om mis te gaan. Een arraycontroller die uitvalt bij RAID 1 of RAID 10 zou in theorie slechte gegevens over de inhoud van de schijven kunnen wegschrijven, maar er is geen proces waarmee de controller op eigen houtje wijzigingen op de schijf aanbrengt, dus dit is uiterst onwaarschijnlijk dat het ooit zal gebeuren, aangezien er nooit een “herstel”proces is, behalve bij het aanmaken van een mirror.
Wanneer arrays met pariteit een herstelbewerking uitvoeren, voeren zij een complex proces uit waarbij zij de gehele inhoud van de array doorlopen en ontbrekende gegevens terugschrijven naar de vervangen schijf. Op zichzelf is dit relatief eenvoudig en zou het geen reden tot zorg moeten zijn. Wat ik en anderen uit eerste hand hebben gezien, is een enigszins ander scenario waarbij schijven betrokken zijn die de verbinding hebben verloren als gevolg van losse aansluitingen op de array. Schijven kunnen vaak in de loop van de tijd losschudden terwijl ze in een server zitten, vooral na verscheidene jaren dienst in een systeem dat altijd aanstaat.
Wat er in extreme scenario's kan gebeuren, is dat goede gegevens op schijven overschreven kunnen worden door slechte pariteitsgegevens wanneer een arraycontroller meent dat een of meer schijven achtereenvolgens zijn uitgevallen en weer online zijn gebracht voor herstel. In dit geval zijn de schijven zelf niet uitgevallen en is er geen gegevensverlies. Het enige wat in theorie nodig is, is dat de schijven opnieuw worden aangesloten. Bij hot-swap-systemen verloopt het beheer van het herstellen van schijven vaak automatisch, op basis van het verwijderen en vervangen van een uitgevallen schijf. Dit proces van het verliezen en vervangen van een schijf kan dus plaatsvinden zonder enige menselijke tussenkomst – en er kan een herstelproces op gang komen. Tijdens dit proces loopt het schijfsysteem risico, en mocht dit zelfde voorval opnieuw plaatsvinden, dan kan de schijf-array, afhankelijk van de status van de schijven, beginnen met het stripen van slechte gegevens over de schijven, waarbij het goede bestandssysteem wordt overschreven. Het is een van de meest deprimerende aanblikken voor een serverbeheerder wanneer een systeem zonder uitgevallen schijven een gehele array verliest als gevolg van een onnodige herstelbewerking.
In theorie zou dit soort situatie zich niet moeten voordoen en zijn er waarborgen aanwezig om hiertegen te beschermen, maar de bepaling door een schijfcontroller op laag niveau van de huidige en voorgaande status van een schijf en de kwaliteit van de gegevens die zich op die schijf bevinden, is niet zo eenvoudig als het lijkt, en het is mogelijk dat er fouten optreden. Hoewel deze situatie onwaarschijnlijk is, komt zij voor en voegt zij een vrijwel onmogelijk te berekenen risico toe aan RAID 5- en RAID 6-systemen. We moeten het risico van pariteitsfalen overwegen, naast het traditionele risico dat wordt berekend op basis van het aantal schijfverliezen dat een array uit een pool kan overleven. Naarmate schijven betrouwbaarder worden, wordt het belang van het risicogebeurtenis van pariteitsfalen groter.
Daarnaast introduceren RAID 5- en RAID 6-pariteit systeemoverhead als gevolg van de pariteitsberekening, die vaak wordt afgehandeld door middel van speciale RAID-hardware. Deze berekening introduceert latentie in het schijfsubsysteem die dramatisch varieert per implementatie, zowel in hardware als in software, waardoor het onmogelijk is om prestatiecijfers van RAID-niveaus ten opzichte van elkaar te noemen, aangezien elke implementatie uniek zal zijn.
Mogelijk het grootste probleem met RAID-keuzes vandaag de dag is dat het gemak waarmee metrieken voor opslagefficiëntie en overleefbaarheid van schijfverlies kunnen worden verkregen, het grote geheel van betrouwbaarheid en prestaties maskeert, aangezien die statistieken vrijwel volledig onbeschikbaar zijn. Een van de gevaren van metrieken is dat mensen zich zullen richten op factoren die eenvoudig te meten zijn en die negeren die niet eenvoudig te meten zijn, ongeacht hun potentiële impact.
Hoewel alle moderne RAID-niveaus hun plaats hebben, is het cruciaal dat zij binnen hun context worden beschouwd en met begrip voor de gehele omvang van de risico's. We zouden hard moeten werken om onze branche te verschuiven van een standaard van RAID 5 naar een standaard van RAID 10. Schijven zijn goedkoop en gegevensverlies is duur.
[Redactionele noot: In de jaren sinds dit oorspronkelijk werd geschreven, heeft de opkomst van URE-risico's (Unrecoverable Read Errors) tijdens een herstelbewerking de voornaamste risico's verschoven van de hierboven genoemde naar URE-gerelateerde risico's voor pariteitsarrays.]
