[GUIDA] Il raid 5 ed il mistero della parità

Discussioni sulle funzioni di RAID0/ RAID1/ Q-RAID1/RAID5/ dei NAS.
Rispondi
FFFAB
Messaggi: 4475
Iscritto il: 06 gen 2016, 19:44

[GUIDA] Il raid 5 ed il mistero della parità

Messaggio da FFFAB »

E' da un po' che volevo scriverla: se ho sbagliato qualcosa o se avete domande, partecipate alla discussione.
Un saluto a tutti, FFFAB.
-----------------------------

Il raid 5 ed il mistero della parità

Ho scritto questa breve guida che spero possa aiutare chi è un po’ acerbo in merito a temi informatici legati ai sistemi raid, cosa sono e come funzionano, ed anche a cosa NON servono.
Premetto che è una guida semplice, rivolta ai poco esperti e che, volutamente, è una visione limitata e molto sintetica del mondo raid.

Per la parte introduttiva vi rimando a wikipedia: inutile ripetere le stesse cose che trovate là…

https://it.wikipedia.org/wiki/RAID

Il raid 5 (ed anche il suo fratello maggiore raid 6) usa un sistema di memorizzazione su disco che è simile al raid 0 non concatenato (detto anche striping), a cui però si aggiunge l’importante concetto della parità (non presente nel raid 0).

Lo striping è un concetto abbastanza semplice: il dato che devo scrivere su disco (per semplicità supponiamo un file MP3) viene letteralmente spezzato in un numero di parti UGUALI, pari al numero dei dischi presenti nell’array (l’array è l’insieme di dischi che fa parte di uno stesso raid, qualunque tipologia esso sia).
Quindi se, ad esempio, ho un array formato da 4 dischi in stripe fra loro, il file MP3 viene spezzato in 4 parti uguali ed ogni parte viene scritta su un disco. Già in questa prima fase, possiamo vedere che, per definizione, in nessun disco sarà presente un file intero, ma saranno presenti solo i 25% di ogni singolo file presente nell’array.

Devo fare una premessa importante: creando un array, si perde totalmente la visione dei dischi sottostanti, cioè non esiste più un legame 1:1 fra il drive fisico e il drive logico. Il drive logico (quello che l’utente vede all’esterno del sistema) coincidere con l’array stesso.

La premessa è fondamentale per capire ad esempio qual è lo spazio totale che viene messo a disposizione dall’array: sopra ho scritto che il file MP3 viene spezzato in 4 parti uguali e che quindi ogni disco contiene solo ¼ del file. E’ facile capire che, nell’intero array, potrò memorizzare 4 volte il numero di files MP3 che potrei memorizzare in ogni singolo disco.
Cioè, in altre parole, lo spazio totale dell’array sarà la somma dello spazio messo a disposizione da ogni disco.

Questo è sempre vero?? No, assolutamente no: è vero SOLO se i 4 dischi hanno la stessa capacità.

Se hanno capacità diverse sorge un problema facilmente rilevabile: avendo capacità diverse fra loro, ce n’è almeno uno che è più piccolo di almeno uno degli altri.
Questo disco più piccolo potrà essere sì riempito totalmente, ma quando proverò a scrivere altri file nell’array (ricordo che TUTTI i files vengono spaccati in 4 parti uguali) non avrò più spazio per scrivere il 25% del file che dovrei scrivere su tale disco, banalmente perché questo è già pieno.

Esempio: Ho 4 dischi di capacità diverse (500, 1000, 3000, 3000 GB). In striping arrivo senza problemi a riempire 500 GB per ogni disco (in totale avrà scritto 500 + 500 + 500 + 500 GB), ma quando provo a scrivere un ulteriore file, non avrò più spazio nel primo disco (sebbene ce ne sia ancora negli altri tre).

In striping, il disco di capacità inferiore è quello che determina lo spazio disponibile nell’array: la capacità totale sarà pari a NumeroDischi * CapacitàDiscoPiccolo (nell’esempio, 4*500 = 2000 GB).
Lo spazio restante (500 nel secondo disco, e 2500+2500 nel terzo e nel quarto) non è indirizzabile ed è perso.

Semplifichiamo: i dischi è meglio che siano della stessa capacità (non avrò spazio sprecato).

Tutto quanto detto finora avviene in scrittura, ma in lettura cosa succede??

Semplice: il controller che gestisce l’array legge i 4 pezzi (uno per ogni disco e nel giusto ordine) ed è così in grado di ricreare il file MP3 di partenza.

Una delle caratteristiche importanti è che sia la scrittura che la lettura dei 4 pezzi, sono eseguite contemporaneamente sui 4 dischi: in pratica leggo (o scrivo) l’intero file (25%+25%+25%+25%) in un solo accesso ai dischi, simultaneo e parallelo.
Questo implica anche che il file MP3 viene scritto (o letto) in un tempo pari ad un quarto di quello che impiegherei a scriverlo (o leggerlo) su un solo disco: questo perché devo scrivere (o leggere) su ogni disco solo un quarto del file.

Esempio: Ho un file MP3 di 8 MB da memorizzare nell’array. Viene prima spezzato in 4 parti uguali (2+2+2+2) ed ognuna di queste viene scritta (contemporaneamente alle altre tre) su ogni disco. La quantità di dati da scrivere nell’unità di tempo passa da 8 a 2, e quindi, in altre parole, la velocità di scrittura (ed anche di lettura) è quadruplicata.

Finora negli esempi, per semplificare, ho parlato di file, ma il concetto è errato: il termine striping deriva da stripe che significa striscia.
I dischi dell’array vengono scritti “a strisce”: se immaginiamo i 4 dischi come dei grandi contenitori verticali affiancati fra loro, scrivere a strisce significa scrivere in modo orizzontale, cioè andare a scrivere il dato alla stessa “profondità” per ogni contenitore (disco). La capacità di questa striscia dipende chiaramente dal numero dei dischi (più contenitori verticali ho, più sarà lunga la striscia orizzontale complessiva) ma dipende anche da quanto è grande ogni pezzo di striscia che memorizzo in ogni disco.
Senza entrare troppo nelle tecniche di indirizzamento dei dischi, queste strisce sono troppo piccole per contenere un file intero (l’MP3 di prima), che, in generale, occuperà più strisce.

Tralasciando quindi il concetto di file, mi soffermo sulla singola striscia, facendo un esempio concreto (che utilizzerò fra poco anche per spiegare la questione della parità).

Supponiamo che la striscia memorizzata nell’array sia composta da 24 bit: restando con l’esempio di 4 dischi, avrò quindi memorizzato 6 bit per ogni disco, ad esempio:

Disco 1: 001010
Disco 2: 011100
Disco 3: 110010
Disco 4: 100111

La striscia è: 001010011100110010100111

NOTA: I 24 bit sono una conseguenza del fatto che le stripe elementari di ogni disco contengono 6 bit e che i dischi sono 4. E’ in base a queste due caratteristiche che determino la striscia da 24 bit, e non il contrario!!! Se i dischi avessero stripe da 8 bit, la striscia sarebbe da 32 bit (4*8), o se i dischi fossero 5 sarebbe da 30 bit (40 bit nel caso di stripe da 8 bit). Ecc ecc ecc...

Fin qua tutto molto bello: ho quadruplicato le velocità di lettura e di scrittura, ho un singolo volume logico (array) molto grande e non ho sprecato spazio (perché ho supposto che i 4 dischi siano di uguale capacità).

E il lato negativo, se c’è, dove sta??

Il problema è che ho “intimamente” unito questi 4 dischi: la rottura di uno qualunque renderebbe inutilizzabili i dati contenuti negli altri 3.

Nell’esempio della stripe a 24 bit, la perdita di un qualunque disco implicherebbe la perdita di 6 bit e, conseguentemente, non sarei in grado di ricostruire interamente la striscia originaria (in altre parole, dei 18 bit rimanenti non ci faccio alcunché…).
TUTTO il contenuto dell’array è inutilizzabile!!!

Questo enorme problema è però superabile con una “magia”: l’utilizzo della fantomatica PARITA’.

Come funziona??

Lo spiego usando l’esempio (e vi assicuro che è più facile da capire che da spiegare).

La parità è un dato calcolato dal controller dischi ed è grande esattamente come una micro-striscia di ogni disco (6 bit nel nostro esempio).

Si parte dai dati che devo scrivere disco per disco (quindi le 4 parti da 6 bit ciascuna) e valuto se, posizione per posizione, ho un numero pari o dispari di valori “1”.
Se ho un numero pari, in quella posizione della parità metto uno “0”, mentre se ho un numero dispari metto un “1”: rifacendomi alla tabellina di prima, avrò la parità uguale a 000011.

Vediamo in dettaglio: riscrivo la tabella evidenziando meglio colonna per colonna:

Disco 1: 0 0 1 0 1 0
Disco 2: 0 1 1 1 0 0
Disco 3: 1 1 0 0 1 0
Disco 4: 1 0 0 1 1 1

Nella prima colonna gli “1” sono due.
Nella seconda colonna gli “1” sono ancora due.
Nella terza e quarta colonna gli “1” sono sempre due (...che fantasia…).
Nella quinta colonna gli “1” sono tre.
Nella sesta colonna di “1” ce n’è uno solo.

Perciò avrò un numero di “1” che è pari – pari – pari – pari – dispari – dispari che, tradotto in bit con la convenzione di cui sopra, diventa 000011.

La parità è tutta qua!!!

Evidenzio una cosa importante: la dimensione della parità è legata solo a quante sono lunghe le micro-strisce di ogni disco (blocchi elementari di memorizzazione), ma è indipendente dal numero dei dischi!!!

Se nell’esempio avessi un quinto disco:

Disco 5: 1 1 0 1 0 1

La parità cambierebbe in:

1 1 0 1 1 0

ma sarebbe grande sempre 6 bit.

Ma a cosa diavolo serve???

Serve a ricreare il dato iniziale (la stripe da 24 bit) nel caso in cui si rompa un disco.

Supponiamo che si rompa il disco 3 e che tutti i dati in esso contenuti siano irrecuperabili: la tabella, volendo comunque rappresentarla, diventerebbe:

Disco 1: 0 0 1 0 1 0
Disco 2: 0 1 1 1 0 0
Disco 3: - - - - - -
Disco 4: 1 0 0 1 1 1

Questo mi rende impossibile ricostruire la stripe di partenza da 24 bit.

Grazie alla parità (memorizzata da qualche parte in precedenza) però posso ricostruire il dato mancante perché so cosa dovrebbe esserci, posizione per posizione, nella micro-stripe del disco 3.

La parità abbiamo detto essere 000011.

Nella prima colonna della tabella gli “1” devono essere pari (perché ho uno “0” nella parità) quindi siccome c’è già un “1” alla prima posizione della stripe disco 4, nella prima posizione della stripe disco 3 c’era sicuramente un “1”.
Nella seconda colonna gli “1” devono essere di nuovo pari: per lo stesso motivo di prima (c’è un “1” nella seconda posizione della stripe disco 2) c’era sicuramente un “1” nella seconda posizione.
Nella terza colonna, gli “1” devono essere ancora pari: ci sono già (disco 1 e disco 2) quindi nel disco 3 c’era di certo uno “0” (se ci fosse stato un “1”, gli “1” sarebbero stati dispari…).
E così via…
Ho ricostruito il dato 110010 che era presente nel disco 3 e, di conseguenza, ho ricostruito la striscia da 24 bit, sebbene ci sia un disco rotto nell’array.
Ho scelto a caso il disco 3, ma avrei potuto scegliere qualunque altro disco (provare per credere).

Quindi, riassumendo, utilizzando uno spazio per ogni stripe pari alla dimensione di ogni blocco di memorizzazione elementare di ciascun disco (6 bit), sono in grado di ricreare la stripe stessa nel caso si rompa UNO QUALUNQUE dei dischi che compongono l’array e INDIPENDENTEMENTE DAL NUMERO dei dischi medesimi.

Questo, in altre parole, significa che la stripe possiamo immaginarla lunga 24+6 = 30 bit (stripe + sua parità), sapendo che gli ultimi 6 bit non sono dato “significativo” ma che sono la parità dei 24 bit precedenti.

Siccome questa considerazione vale per tutte le stripe, è facile vedere che serve esattamente un disco in più per contenere tutte le parità di tutte le stripe: nel nostro esempio, i dischi passano quindi da 4 a 5, dove il quinto non contiene altro che parità.

Ma allora, se ho introdotto un altro disco, devo ragionare nuovamente sui possibili casi di rottura?? E se si rompe proprio il disco delle parità??

Beh, poco male: se si rompe il disco 5, non ho perso assolutamente nulla e non devo ricreare alcunché. I dati significativi (cioè le stripe da 24 bit) sono solo nei primi 4 dischi, e quindi immediatamente leggibili. Basterà sostituire il disco 5 con uno nuovo, ed il controller tornerà a riempirlo, calcolando nuovamente tutte le parità, striscia per striscia.

In realtà quello che vi ho descritto è il vecchio raid 4, in cui veniva dedicato un intero disco alle parità: il raid 5 (ed anche il 6) prevede che le parità vegano distribuite, stripe per stripe, su tutti i dischi.

Così facendo però si introduce un grosso problema: come faccio a sapere in quale disco è contenuta la parità di quella specifica stripe???

Leggo 30 bit sui 5 dischi simultaneamente: chi mi dice dove sta la parità??
Potrebbe essere 6/6/6/6/P oppure 6/6/P/6/6 oppure ancora 6/P/6/6/6…. Qual è la corretta combinazione??

Semplice: il numero che identifica quella particolare stripe mi dice anche dove sta la parità!!!

Esempio:

D1 D2 D3 D4 D5
*****
*****
23457: 6 P 6 6 6
23458: 6 6 P 6 6
23459: 6 6 6 P 6
23460: 6 6 6 6 P
23461: P 6 6 6 6
23462: 6 P 6 6 6
*****
*****


Nella tabella, la prima colonna indica il numero della stripe: quel numero rappresenta l’indirizzo per raggiungere ognuna di esse. Si parte dal numero 0 e si arriva ad un numero che dipende dalla capacità dei dischi facenti parte l’array (banalmente un disco da 2TB conterrà esattamente la metà di stripe rispetto ad un disco da 4TB).
Come vedete, le parità P sono distribuite con regolarità su tutti i dischi.
Il numero di indirizzo mi dirà dove si trovano i 6 bit di parità e, quindi, anche dove si trovano i 24 bit di dato significativo.
In questo esempio, se l’indirizzo termina con 1 o 6, la parità è SEMPRE nei primi 6 bit dei 30 che compongono la stripe.
Se termina con 2 o 7, la parità è SEMPRE nel secondo gruppo da 6.
Se termina con 3 o 8, è SEMPRE nel terzo gruppo.
E così via…

Perciò quando leggerò la stripe numero 837819 (ad es. 001010011100110010000011100111), saprò che la parità è nel quarto gruppo (6/6/6/P/6), e quindi avrò:

Stripe letta: 001010011100110010000011100111

Composta da:

dato significativo: 001010011100110010100111
sua parità: 000011

In generale si prende il numero identificativo della stripe (il suo indirizzo) e lo si divide per il numero dei dischi che compongono l’array: la divisione genera un quoziente con un resto; il resto indicherà in quale gruppo è stata memorizzata la parità.

Esempio:

Ho 3 dischi in raid 5 e leggo la stripe numero 18535 e ottengo 011010001001110010011.
Qual è la parità??
Vedo che stripe è lunga 21 bit: spalmati su 3 dischi, significa che ogni disco avrà blocchi elementari di memorizzazione lunghi 7 bit e quindi, per forza di cose, la parità è lunga 7 bit.
Il numero 18535 diviso per 3 (numero dischi) fa 6178 con resto 1.
Possiamo ipotizzare che con resto uguale a 0 ci si riferisca al primo gruppo di 7 bit, con resto uguale a 1 al secondo, e con resto uguale a 2 al terzo (il resto assume valori da 0 a NumeroDischi-1).

La parità perciò sarà nel secondo gruppo, e quindi:

dato significativo: 01101000010011 (primo e terzo gruppo da 7 bit)
sua parità: 0100111 (secondo gruppo da 7 bit)

NOTA: Verificate che la parità sia davvero quella dei 14 bit del dato significativo!!!

Appare evidente che le convenzioni ritenute valide per tutti (meglio chiamarli standard) sono di estrema importanza: se in quest’ultimo esempio ritenessi che con resto 0 ci si riferisce al terzo, con resto 1 al secondo, e con resto 2 al primo, tutto crollerebbe perché l’array è stato riempito in un modo e letto in un altro.

Gli esempi che ho fatto in queste pagine non sono reali, ma li ho inventati per spiegare in modo semplice (spero) calcoli che altrimenti sarebbero troppo lunghi e difficilmente comprensibili: la base del ragionamento è esattamente questa, ma poi, quando viene applicata al caso concreto, il tutto si complica parecchio…

Nelle prossime puntate (se ci saranno… : Chessygrin : ) vedremo che la parità non è solo "una bella invenzione", ma cela alcune insidie non immediatamente evidenti.
: Walkman : TS-453A 8Gb Kingston HyperX Impact CL9 (Seagate ST10000NM0086 + ST10000NE0008 : Thumbup : )
teo.abs
Messaggi: 13
Iscritto il: 03 ott 2019, 14:14

Re: [GUIDA] Il raid 5 ed il mistero della parità

Messaggio da teo.abs »

Intanto grazie! : Thumbup :
Poi con calma lo leggerò : Wink :
antoniomanca
Messaggi: 1
Iscritto il: 24 giu 2010, 09:07

Re: [GUIDA] Il raid 5 ed il mistero della parità

Messaggio da antoniomanca »

Una bellissima spiegazione, fruibile anche da persone non addette ai lavori (come il sottoscritto): è richiesto soltanto il giusto interesse verso una materia concettualmente accessibile ma operativamente un po' difficile. Bravo, FFFAB...e grazie mille!

Mi piacerebbe che pubblicassi anche la "seconda puntata" cui accennavi...
FFFAB
Messaggi: 4475
Iscritto il: 06 gen 2016, 19:44

Re: [GUIDA] Il raid 5 ed il mistero della parità

Messaggio da FFFAB »

Prego,
in questi giorni di "tempo libero forzato" sto sistemando un paio di vecchie pagine sui problemi legati alla parità. Arriveranno : Thumbup :
: Walkman : TS-453A 8Gb Kingston HyperX Impact CL9 (Seagate ST10000NM0086 + ST10000NE0008 : Thumbup : )
Hermann77
Messaggi: 92
Iscritto il: 21 set 2009, 11:50

Re: [GUIDA] Il raid 5 ed il mistero della parità

Messaggio da Hermann77 »

Interessantissimo.... l'ho letto molto volentieri. Grazie.
giammar
Messaggi: 5
Iscritto il: 22 ott 2020, 12:28

Re: [GUIDA] Il raid 5 ed il mistero della parità

Messaggio da giammar »

Moolto interessante!!
Grazie intanto, ma il seguito?
Se metto in RAID5 risolvo tutti i problemi di sicurezza? o no?
gianmar
FFFAB
Messaggi: 4475
Iscritto il: 06 gen 2016, 19:44

Re: [GUIDA] Il raid 5 ed il mistero della parità

Messaggio da FFFAB »

giammar ha scritto: 22 ott 2020, 18:24 Se metto in RAID5 risolvo tutti i problemi di sicurezza? o no?
No!!!
: Walkman : TS-453A 8Gb Kingston HyperX Impact CL9 (Seagate ST10000NM0086 + ST10000NE0008 : Thumbup : )
Rispondi