När ingen redundans är mer tillförlitlig – Myten om redundans
Risk är ett svårt begrepp och det kräver mycket utbildning, eftertanke och analys för att korrekt bedöma givna scenarier. Ofta, eftersom riskbedömningar är så svåra, ersätter vi riskanalys med att helt enkelt lägga till grundläggande redundans och anta att vi har mildrat risken på ett lämpligt sätt. Men mycket ofta är detta inte fallet. Införandet av komplexitet eller ytterligare felmoder åtföljer ofta tillägget av redundans, och dessa nya former av fel har potentialen att tillföra mer risk än vad den tillagda redundansen avlägsnar. Lagringssystem är särskilt benägna att utsättas för dessa beslutsprocesser, vilket är olyckligt eftersom få, om ens några, system är så mottagliga för fel och viktigare att skydda.
RAID är ett utmärkt exempel på var en brist på helhetstänkande kring risk kan leda till en del märkligt beslutsfattande. Om vi tittar på ett inte ovanligt scenario kommer vi att se var målet att skydda mot diskhaveri faktiskt kan leda till en ökad risk även när ytterligare redundans tillämpas. I detta scenario kommer vi att jämföra en array med tolv diskar bestående av tolv SATA-hårddiskar på tre terabyte vardera i en enda array. Det är inte ovanligt att höra om folk som väljer RAID 5 för detta scenario för att få “maximal kapacitet och prestanda” samtidigt som de har “adekvat skydd mot haveri.”
Tanken här är att RAID 5 skyddar mot förlust av en enda disk som kan ersättas, och arrayen kommer att återuppbygga sig själv innan en andra disk havererar. Det är utmärkt i teorin, men de verkliga riskerna med en array av denna storlek, trettiosex terabyte diskkapacitet, kommer inte från flera diskhaverier som folk generellt misstänker utan från en oförmåga att tillförlitligt återuppbygga arrayen efter ett enda diskhaveri, eller från ett haveri av själva arrayen utan att några enskilda diskar havererar. Risken för att en andra disk havererar är låg, inte obefintlig, men ganska låg. Diskar är i dag mycket tillförlitliga. När en disk väl havererar ökar det sannolikheten för att en andra disk havererar, vilket är väl dokumenterat, men jag vill inte att denna risk ska vilseleda oss från att titta på de verkliga riskerna – risken för en misslyckad resilver-operation.
Det som händer som skrämmer oss under en RAID 5-resilver-operation är att ett oåterställbart läsfel (URE) kan inträffa. När det gör det stannar resilver-operationen och arrayen lämnas i ett oanvändbart tillstånd – all data på arrayen går förlorad. På vanliga SATA-diskar är URE-frekvensen 10^14, eller en gång var tolfte terabyte av läsoperationer. Det betyder att en array på sex terabyte som resilvras har ungefär femtio procents chans att träffa på ett URE och misslyckas. Femtio procents risk att misslyckas är vansinnigt högt. Tänk dig om din bil hade femtio procents chans att hjulen föll av varje gång du körde den. Så med en liten (enligt dagens mått) RAID 5-array på sex terabyte med SATA-diskar med 10^14 URE, om vi skulle förlora en enda disk, har vi bara femtio procents chans att arrayen återhämtar sig, förutsatt att disken ersätts omedelbart. Det inkluderar inte risken för att en andra disk havererar, endast risken för ett URE-haveri. Det förutsätter också att disken är helt inaktiv förutom resilver-operationen. Om diskarna samtidigt används flitigt för andra uppgifter börjar chanserna för att något dåligt ska hända, antingen ett URE eller ett andra diskhaveri, öka dramatiskt.
Med en array på tolv terabyte börjar chanserna för fullständig dataförlust under en resilver-operation närma sig hundra procent – vilket betyder att RAID 5 inte har någon som helst funktionalitet i det fallet. Det finns alltid en chans att överleva, men den är mycket låg. Vid sex terabyte kan du jämföra en resilver-operation med en omgång rysk roulett med en kula och sex kammare, och du måste trycka av tre gånger. Med tolv terabyte måste du trycka av sex gånger! Det är inte goda odds.
Men vi talar inte om en array på tolv terabyte. Vi talar om en array på trettiosex terabyte – vilket låter stort, men detta är en storlek som någon lätt skulle kunna ha hemma i dag, för att inte tala om i ett företag. Varje större servertillverkare, liksom nästan alla lågkostnadsleverantörer av lagring, gör lagringssystem under 10 000 dollar i detta kapacitetsspann i dag. Att resilvra en RAID 5-array med ett enda diskhaveri på en array på trettiosex terabyte är som att spela rysk roulett, en kula, sex kammare och trycka av arton gånger! Din data har inte mycket av en chans. Lägg till detta den otroliga mängd tid som behövs för att resilvra en array av den storleken och risken för att en andra disk havererar under det resilver-fönstret börjar bli ett ganska betydande hot. Jag har sett uppskattningar av resilver-tider som klättrar upp i veckor eller månader på vissa system. Det är en lång tid att köra utan att kunna förlora ytterligare en disk. När vi talar om timmar eller dagar är riskerna ganska låga, men ändå närvarande. När vi talar om veckor eller månader av kontinuerlig misshandel, eftersom resilver-operationer är extremt diskintensiva, klättrar felfrekvenserna dramatiskt.
Med en array av denna storlek kan vi i praktiken anta att förlusten av en enda disk innebär förlusten av hela arrayen, vilket lämnar oss helt utan skydd mot diskhaveri. Om vi nu tittar på en disk med samma eller bättre prestanda och med samma eller bättre kapacitet under RAID 0, som också saknar skydd mot diskförlust, behöver vi bara använda elva av samma diskar som vi behövde tolv av för vår RAID 5-array. Vad detta betyder är att i stället för tolv hårddiskar, som var och en har ungefär tre procents chans till årligt haveri, har vi bara elva. Enbart det gör vår RAID 0-array mer tillförlitlig eftersom det finns färre diskar som kan haverera. Inte nog med att vi har färre diskar, det finns heller inget behov av att skriva paritetsblocket eller hoppa över paritetsblock vid återläsning, vilket, om än ytterst marginellt, sänker det mekaniska slitaget på RAID 0-arrayen för samma användning och ger den en mycket liten ytterligare tillförlitlighetsfördel. RAID 0-arrayen med elva diskar kommer att vara identisk i kapacitet med RAID 5-arrayen med tolv diskar men kommer att ha något bättre genomströmning och latens. En vinst rakt igenom. Plus kostnadsbesparingen av att inte behöva en ytterligare disk.
Så vad vi ser här är att i stora arrayer (stora i kapacitet, inte i antal spindlar) passerar RAID 0 faktiskt RAID 5 i vissa scenarier. När man använder vanliga SATA-diskar inträffar detta vid kapaciteter som upplevs även av avancerade hemanvändare och av många små företag. Om vi går över till enterprise-SATA-diskar eller SAS-diskar blir den kapacitetssiffra där detta inträffar mycket hög och är inget bekymmer i dag, men kommer att vara det om bara några år när diskkapaciteterna blir större ännu. Men detta belyser hur farligt RAID 5 är i de storlekar som vi ser i dag. Alla förstår de otroliga riskerna med RAID 0, men det kan vara svårt att sätta i perspektiv att RAID 5:s problem är så extrema att det faktiskt kan vara mindre tillförlitligt än RAID 0.
Att RAID 5 kan vara mindre tillförlitligt än RAID 0 i en array av denna storlek, baserat enbart på resilver-operationer, är bara början. I en massiv array som denna kan resilver-tiden ta så lång tid och kräva en sådan tribut av diskarna att ett andra diskhaveri också börjar bli en mätbar risk. Och sedan finns det ytterligare risker orsakade av fel i arraykontrollern som kan utnyttja resilver-algoritmer för att förstöra en hel array även när inget diskhaveri har inträffat. Eftersom RAID 0 (eller RAID 1 eller RAID 10) inte har några resilver-algoritmer lider de inte av denna ytterligare risk. Dessa är svåra risker att kvantifiera, men det som är viktigt är att de är ytterligare risker som ackumuleras när man använder ett mer komplext system, när ett enklare system, utan redundansen, var mer tillförlitligt från första början.
Nu när vi har fastställt att RAID 5 kan vara mindre tillförlitligt än RAID 0 ska jag peka på de uppenbara farorna med RAID 0. RAID i allmänhet används för att mildra risken för att en enda, ensam hårddisk havererar. Vi fruktar alla att en enda disk helt enkelt havererar och all data går förlorad. RAID 0, som är en stor stripe av diskar utan någon form av redundans, tar risken för dataförlust vid haveri av en enda disk och multiplicerar den över ett antal diskar där haveri av vilken disk som helst orsakar total förlust av data till alla diskar. Så i vårt exempel med elva diskar ovan: om någon av de elva diskarna havererar går allt förlorat. Det är tydligt att se var detta är dramatiskt farligare än att bara använda en enda disk, alldeles ensam.
Det jag försöker peka på här är att redundans inte betyder tillförlitlighet. Bara för att något är redundant, som RAID 5, ger det ingen garanti för att det alltid kommer att vara mer tillförlitligt än något som inte är redundant.
Min favoritanalogi här är att titta på hus i en tornado. I ett scenario bygger vi ett hus av tegel och murbruk. I det andra scenariot bygger vi två redundanta hus, vardera av halm (våra byggare är grisar, tydligen.) När tornadon (eller den stygga vargen) kommer, vilket är mer sannolikt att lämna oss med ett hus som står kvar? Det är tydligt att ett hus av tegel och murbruk har vissa betydande tillförlitlighetsfördelar framför redundanta halmhus. Redundansen spelade ingen roll, tillförlitligheten spelade roll i slutändan.
Redundans är ofta vilseledande eftersom det är lätt att kvantifiera men svårt att kvalificera. Redundans är en svart eller vit fråga: Är det redundant? Ja eller nej. Enkelt. Tillförlitlighet är inte så enkelt. Tillförlitlighet handlar om felfrekvenser och sannolikheter. Det handlar om statistik och analys. Eftersom det är svårt att kvantifiera tillförlitlighet på ett meningsfullt sätt, särskilt när man säljer in ett projekt till affärsfolket, blir redundans ofta en enkel ersättning för detta komplexa begrepp.
Konceptet att använda redundans för att avleda frågor om tillförlitlighet slutar också med att tillämpas på delsystem på mycket invecklade sätt. I stället för att göra ett “system” redundant har det blivit vanligt att göra ett mycket tillförlitligt, och billigt, delsystem redundant och behandla delsystemets redundans som om den gällde hela systemet. Det vanligaste exemplet på detta är RAID-kontrollers i SAN-produkter. I stället för att ha ett redundant SAN (vilket betyder två SAN) gör tillverkarna ofta den enda komponent som inte ofta är redundant i normala servrar redundant och kallar sedan SAN:et redundant – vilket betyder ett SAN som innehåller redundans, vilket inte alls är samma sak.
En bra analogi här vore att jämföra att ha redundanta bilar, vilket betyder två kompletta, fungerande bilar, med att ha en enda bil med en reservvattenpump i bagageutrymmet i fall den huvudsakliga skulle gå sönder. Det är tydligt att en reservvattenpump inte är något dåligt. Men det är också ett trivialt skydd mot bilhaveri jämfört med att ha en andra bil redo att köra. I det ena fallet är hela systemet redundant, inklusive chassit. I det andra gör vi bara en enda, mycket tillförlitlig komponent redundant inuti chassit. Det är inte ens i nivå med att ha ett reservdäck vilket, åtminstone, är en bilkomponent med en högre sannolikhet för haveri.
Precis som myten om RAID 5:s tillförlitlighet och om system/delsystems tillförlitlighet, behandlas delade lagringstekniker som SAN och NAS ofta på samma sätt, särskilt med avseende på virtualisering. Det finns ett vanligt scenario där ett virtualiseringsprojekt genomförs och folk instinktivt får panik eftersom en enda virtualiseringsvärd representerar en enskild felpunkt där, om den havererar, många system kommer att haverera samtidigt.
Att använda termen “enskild felpunkt” framkallar en panikkänsla och är ett utmärkt sätt att styra en konversation. Men en SPOF, som vi gärna kallar det, även om det är något vi gärna avlägsnar när det är möjligt, kanske inte är världens undergång. Tänk på vårt tegelhus. Det är en SPOF. Våra två halmhus är det inte. Ändå tar en enda vindpust ut våra redundanta lösningar snabbare än vår tillförlitliga SPOF. Att leta efter SPOF:ar är ett utmärkt sätt att hitta punkter av skörhet i ett system, men känn inte att varje SPOF måste göras redundant i varje scenario. De flesta företag kommer att finna sitt bästa värde i att ha många SPOF:ar på plats. Vårt verkliga mål är tillförlitlighet till lämplig kostnad; redundans är, som vi har sett, ingen ersättning för tillförlitlighet, det är helt enkelt ett verktyg som vi kan använda för att uppnå tillförlitlighet.
Teorin som många följer vid virtualisering är att de tar sin virtualiseringsvärd och säger “Den här värden är en SPOF, så jag måste ha två av dem och använda High Availability-funktioner för att möjliggöra transparent failover!” Detta sporras av att den ledande virtualiseringsleverantören tjänar sina pengar dels på att sälja dyra HA-tilläggsprodukter och dels på att vara ägd av en stor lagringsleverantör – så att sälja onödig eller till och med farlig ytterligare delad lagring är en stor monetär vinst för dem och kan lätt vara anledningen till att de har förespråkat virtualiseringsområdet från första början. Redundanta virtualiseringsvärdar med delad lagring låter utmärkt men kan vara extremt missriktat av flera skäl.
Det första skälet är att avlägsnandet av den ursprungliga SPOF:en, virtualiseringsvärden, ersätts med en ny SPOF, den delade lagringen. Detta åstadkommer ingenting. Förutsatt att vi använder servrar och delad lagring av jämförbar kvalitet är allt vi har gjort att flytta var risken finns, inte att förändra hur stor den är. Sannolikheten för att lagringssystemet havererar är ungefär lika med sannolikheten för att den ursprungliga servern havererar. Men utöver att flytta runt SPOF:en som i ett bondfångarspel har vi också gjort något långt, långt värre – vi har infört kedjade eller kaskaderande felberoenden.
I vårt ursprungliga scenario hade vi en enda server. Om servern fortsatte att fungera var vi väl, om den havererade var vi det inte. Enkelt. Nu har vi två virtualiseringsvärdar, en enda lagringsserver (SAN, NAS, vad det än är) och ett nätverk som kopplar samman dem. Vi har redan fastställt att risken för att den delade lagringen havererar är ungefär lika med vår totala systemrisk i det ursprungliga scenariot. Men nu har vi de ytterligare beroendena av nätverket och de två frontend-virtualiseringsnoderna. Var och en av dessa komponenter är mer tillförlitlig än den sköra delade lagringen (allt med mekaniska diskar kommer att vara skört), men att de utgör en lägre risk är inte problemet, problemet är att riskerna är kombinatoriska.
Om någon av dessa tre komponenter (lagring, nätverk eller frontend-noderna) havererar så havererar allt. Lösningen på detta är att göra den delade lagringen redundant för sig och att göra nätverket redundant för sig. Med tillräckligt mycket arbete kan vi övervinna den skörhet och risk som vi införde genom att lägga till delad lagring, men den delade lagringen är i sig inte en form av riskmildring utan är en risk i sig som måste mildras. Komplexitetens spiral börjar och kostnaden förknippad med att få upp detta nya system i nivå med tillförlitligheten hos det ursprungliga, enskilda serversystemet kan vara astronomisk.
Nu när vi har all denna redundans har vi ytterligare en risk att oroa oss för. Att hantera all denna redundans, alla dessa rörliga delar, kräver mycket mer kunskap, skicklighet och förberedelse än vad det gör att hantera en enkel, enskild server. Vi har gått från en enkel lösning till en mycket komplex. Enligt min egen anekdotiska erfarenhet kommer de verkliga farorna med lösningar som denna inte från att hårdvaran havererar utan från mänskliga misstag. Inte nog med att lite har gjorts för att undvika att mänskliga misstag får detta nya system att haverera, vi har dessutom lagt till otaliga punkter där en människa av misstag kan ta ner hela systemet, redundans och allt, rakt ner. Jag har sett det med egna ögon; jag har hört skräckhistorierna. Ju mer komplext systemet är, desto mer sannolikt är det att en människa av misstag kommer att förstöra allt.
Det är avgörande att vi som IT-professionella tar ett steg tillbaka och betraktar kompletta system och överväger tillförlitlighet och risk, och tänker på redundans helt enkelt som ett verktyg att använda i strävan efter tillförlitlighet. Redundans i sig är inget universalmedel. Det är inte enkelhet heller. Tillförlitlighet är ett komplext problem att ta sig an. Att undvika förenklade ersättningar är ett viktigt första steg i att gå från att dölja tillförlitlighetsproblem till att möta och lösa dem.
