A les dues lliçons anteriors hem comptat el cost d'una fallada de pàgina en mil·lisegons i hem vist un servidor caure en hiperpaginació per culpa del disc. Ara toca mirar de cara aquest component que hem estat tractant com una caixa negra lenta. Perquè no és una caixa negra: un disc mecànic i un SSD NVMe tenen físiques completament diferents, i les decisions que el sistema operatiu pren per a l'un són contraproduents per a l'altre.

Un avís sobre l'abast: aquesta lliçó tracta l'emmagatzematge com a recurs gestionat, no com a sistema de fitxers. Aquí veuràs la física del dispositiu, quant costa un accés, com s'ordenen les peticions i com es combinen diversos discos en un volum fiable. Tot el que té a veure amb fitxers, directoris, inodes, particions i muntatge correspon al mòdul 4. La frontera és clara: aquí gestionem blocs numerats; allà se'ls dona significat.

Contingut

  1. La jerarquia d'emmagatzematge completa
  2. El disc dur mecànic per dins
  3. Càlcul del temps d'un accés a disc
  4. SSD i memòria NAND: una altra física, unes altres regles
  5. Amplificació d'escriptura, recollida d'escombraries i TRIM
  6. NVMe i per què canvia les regles
  7. LBA i l'abstracció del dispositiu de blocs
  8. Planificació de peticions de disc
  9. Els planificadors reals de Linux
  10. RAID: combinar discos per capacitat, velocitat o fiabilitat
  11. La decisió de Meteora per a /var/lib/meteora
  12. Mesura amb lsblk i iostat -x

La jerarquia d'emmagatzematge completa

A 01-01 vam veure la jerarquia de memòria fins a la RAM. Ara la completem cap avall, que és on les diferències es tornen brutals:

Nivell Latència típica Amplada de banda Capacitat Cost per GB Volàtil
Registres 0,3 ns ~1 KB
Memòria cau L1 1 ns 1 TB/s 64 KB
Memòria cau L2 4 ns 500 GB/s 1 MB
Memòria cau L3 15 ns 200 GB/s 32 MB
RAM (DDR4) 80-100 ns 20 GB/s 8 GB 4 €
SSD NVMe 20-100 µs 3.500 MB/s 1 TB 0,08 € No
SSD SATA 100-200 µs 550 MB/s 1 TB 0,06 € No
Disc dur 5-15 ms 150 MB/s 8 TB 0,02 € No
Cinta LTO-9 desenes de segons 400 MB/s 18 TB 0,008 € No

Els salts entre nivells adjacents són de 2 a 5 vegades, tret d'un:

RAM → SSD NVMe:  100 ns → 50 µs   = factor 500
RAM → disc:      100 ns → 8 ms    = factor 80.000

L'abisme és entre la RAM i l'emmagatzematge persistent, i aquest abisme és la raó de ser de la memòria cau de pàgines, de la memòria intermèdia que vam calcular a 01-06 i de la paginació per demanda de la lliçó anterior. Tot el disseny d'un sistema operatiu a la part d'E/S consisteix a evitar creuar-lo.

Una analogia en escala humana, escalant 1 ns a 1 segon:

Operació Temps real En escala humana
Accés a memòria cau L1 1 ns 1 segon
Accés a RAM 100 ns 1 minut i mig
Accés a SSD NVMe 50 µs 14 hores
Accés a disc dur 8 ms 3 mesos
Reinici del servidor 60 s 1.900 anys

Quan l'agregador provoca una fallada major, des del punt de vista de la CPU és com esperar tres mesos per una dada.

El disc dur mecànic per dins

Un HDD és l'únic component amb parts mòbils en un servidor modern, i la seva física governa tot el seu comportament.

Vista lateral:                    Vista superior d'un plat:

   ┌─────────────────┐                 ╭─────────────╮
═══╪═══ plat 0 ══════╡ ← capçal        │ ╭─────────╮ │  ← pista 0 (externa)
   │                 │                 │ │ ╭─────╮ │ │  ← pista 1
═══╪═══ plat 1 ══════╡ ← capçal        │ │ │  ·  │ │ │  ← eix
   │                 │                 │ │ ╰─────╯ │ │
═══╪═══ plat 2 ══════╡ ← capçal        │ ╰─────────╯ │
   └────────┬────────┘                 ╰─────────────╯
        braç actuador                   sector = arc de pista

El vocabulari, que cal tenir clar per als càlculs:

Terme Què és
Plat Disc magnètic giratori. Un HDD en té entre 1 i 9
Cara Cada costat d'un plat; cadascuna té el seu capçal
Pista Circumferència concèntrica en una cara
Cilindre Conjunt de pistes del mateix radi a tots els plats
Sector Unitat mínima de lectura/escriptura: 512 bytes o 4 KB
Capçal Llegeix i escriu; tots es mouen junts al braç

El cilindre és un concepte clau: com que tots els capçals es mouen solidàriament, accedir a dades del mateix cilindre no requereix moure el braç, encara que siguin en plats diferents. És pràcticament de franc.

Un accés té tres components de temps:

Component Què passa Ordre de magnitud De què depèn?
Temps de cerca (seek) Moure el braç al cilindre correcte 3-12 ms La distància recorreguda
Latència rotacional Esperar que el sector passi sota el capçal 2-8 ms Les RPM del disc
Temps de transferència Llegir les dades mentre giren 0,01-0,1 ms La mida del bloc

La latència rotacional mitjana és exactament mitja volta, perquè de mitjana el sector estarà a mig camí:

RPM Volta completa Latència rotacional mitjana
5.400 11,1 ms 5,56 ms
7.200 8,33 ms 4,17 ms
10.000 6,0 ms 3,00 ms
15.000 4,0 ms 2,00 ms

Càlcul del temps d'un accés a disc

El calcularem amb les dades del disc de meteo-01:

Disc: 7.200 RPM
Temps de cerca mitjà: 8,5 ms
Taxa de transferència sostinguda: 150 MB/s
Sector: 4 KB

Cas 1: llegir un bloc de 4 KB en una posició aleatòria.

Cerca:                 8,50 ms
Latència rotacional:   4,17 ms   (60.000 ms/min ÷ 7.200 RPM ÷ 2)
Transferència:         4 KB / 150 MB/s = 0,027 ms
                     ──────────
Total:                12,70 ms

Observa la proporció, que és el veritablement important:

Cerca + latència: 12,67 ms = 99,8 % del temps
Transferència:     0,027 ms = 0,2 % del temps

El 99,8 % del temps es dedica a posicionar-se, no a llegir. Aquesta única xifra explica tot el disseny dels sistemes d'emmagatzematge sobre disc mecànic.

Cas 2: llegir 1 MB contigu.

Cerca:                 8,50 ms
Latència rotacional:   4,17 ms
Transferència:         1 MB / 150 MB/s = 6,67 ms
                     ──────────
Total:                19,34 ms

Llegir 256 vegades més dades només costa un 52 % més de temps.

Cas 3: llegir aquest mateix 1 MB en 256 blocs de 4 KB dispersos.

256 × 12,70 ms = 3.251 ms = 3,25 segons

Comparació directa:

Patró Temps MB/s efectius
1 MB seqüencial 19,3 ms 51,8 MB/s
1 MB en 256 blocs aleatoris 3.251 ms 0,31 MB/s
Factor de diferència 168×

Un disc mecànic és 168 vegades més lent amb accés aleatori que seqüencial. D'aquí en surten tres conseqüències que dominen el disseny de sistemes:

  1. Llegir més del que s'ha demanat surt gairebé de franc (lectura anticipada, readahead): ja que has pagat la cerca, aprofita-la.
  2. Agrupar escriptures disperses en una de seqüencial compensa enormement, encara que impliqui escriure més bytes. És el fonament dels sistemes de fitxers estructurats en registre i del journaling (04-05).
  3. Reordenar les peticions per minimitzar el moviment del braç té un impacte gegantí. És el tema de l'apartat 8.

Aplicat a Meteora, amb els 17 MB diaris de /var/lib/meteora/lectures/:

Lectura seqüencial del dia:       17 MB / 150 MB/s + 12,7 ms ≈ 126 ms
Lectura en 4.250 blocs de 4 KB:   4.250 × 12,7 ms ≈ 54 segons

La mateixa dada, 428 vegades més lenta. Per això l'agregador ha de recórrer el fitxer en ordre, i per això madvise(MADV_SEQUENTIAL) de la lliçó anterior té sentit.

SSD i memòria NAND: una altra física, unes altres regles

Un SSD no té parts mòbils. Emmagatzema bits com a càrrega elèctrica atrapada en cel·les de memòria flash NAND. Això elimina cerca i latència rotacional, però introdueix restriccions noves i molt peculiars.

L'estructura interna:

SSD
 └── Canals (4-8, en paral·lel)
      └── Xips NAND
           └── Blocs d'esborrat (256 KB - 4 MB)
                └── Pàgines (4-16 KB)  ← unitat de LECTURA i ESCRIPTURA

I aquí hi ha l'asimetria que ho explica tot:

Operació Unitat Temps típic Restricció
Llegir Pàgina (4-16 KB) 25-100 µs Cap
Escriure Pàgina (4-16 KB) 200-900 µs Només en pàgines ja esborrades
Esborrar Bloc (256 KB-4 MB) 2-10 ms Afecta tot el bloc

No es pot sobreescriure una pàgina de flash. Cal esborrar-la abans, i l'esborrat només funciona sobre blocs sencers que són centenars de vegades més grans que la pàgina.

Aquesta restricció, que sembla un detall tècnic menor, té conseqüències en cascada sobre tot el comportament del dispositiu.

El problema de l'escriptura desalineada

Suposa que vols modificar 4 KB dins d'un bloc de 2 MB que és ple de dades. La seqüència ingènua seria:

1. Llegir els 2 MB del bloc a una memòria intermèdia interna  → 2 MB de lectura
2. Modificar els 4 KB a la memòria intermèdia
3. Esborrar el bloc de 2 MB                                   → 5 ms d'esborrat
4. Reescriure els 2 MB                                        → 2 MB d'escriptura

Has escrit 2 MB a la flash per modificar 4 KB. El factor d'amplificació és de 512.

Cap SSD real no fa això, precisament perquè seria inacceptable. En comptes d'això, el controlador escriu els 4 KB nous en una pàgina ja esborrada d'un altre lloc, i actualitza una taula interna que tradueix adreces lògiques a físiques. La pàgina antiga queda marcada com a invàlida, pendent de reciclatge.

Aquesta taula s'anomena FTL (Flash Translation Layer) i és, conceptualment, una taula de pàgines dins de l'SSD: el mateix mecanisme d'indirecció que vam estudiar a la lliçó anterior, aplicat a l'emmagatzematge. Ni el sistema operatiu ni tu no veieu mai les adreces físiques de la flash.

Amplificació d'escriptura, recollida d'escombraries i TRIM

Com que les pàgines invàlides s'acumulen, l'SSD necessita reciclar-les. Aquest procés és la recollida d'escombraries (garbage collection):

Bloc A (2 MB) abans:
[vàlida][invàlida][vàlida][invàlida][invàlida][vàlida][lliure][lliure]

Procés:
1. Copiar les 3 pàgines vàlides a un bloc nou
2. Esborrar el bloc A sencer
3. El bloc A queda disponible

Bloc A després: [lliure][lliure][lliure][lliure][lliure][lliure][lliure][lliure]

El cost: per alliberar espai s'han hagut de copiar dades que ja estaven escrites. Això és amplificació d'escriptura (write amplification):

WA = bytes escrits a la flash / bytes escrits pel sistema operatiu
Escenari WA típica Per què
Escriptura seqüencial, SSD buit 1,0-1,1 Els blocs s'omplen i es reciclen sencers
Escriptura aleatòria, SSD al 50 % 2-3 Cal reubicar pàgines vàlides
Escriptura aleatòria, SSD al 95 % 5-10 Amb prou feines queden blocs lliures per reciclar
Escriptura aleatòria, sense TRIM 10-20 L'SSD no sap quines dades són obsoletes

Un SSD gairebé ple es comporta molt pitjor que un amb espai lliure. I no és només qüestió de rendiment: la flash té un nombre limitat de cicles d'esborrat per cel·la.

Tipus de NAND Bits per cel·la Cicles d'esborrat Ús
SLC 1 50.000-100.000 Industrial, memòria cau
MLC 2 3.000-10.000 Empresa
TLC 3 1.000-3.000 Consum i servidor
QLC 4 300-1.000 Arxiu, lectura intensiva

Amb això es pot calcular la vida útil de l'SSD de meteo-01:

SSD TLC d'1 TB, 1.500 cicles d'esborrat
Escriptura total suportada = 1 TB × 1.500 = 1.500 TBW (terabytes escrits)

Escriptura diària de Meteora:
  Lectures: 17 MB/dia
  Registres: ~200 MB/dia
  Còpies de seguretat i temporals: ~500 MB/dia
  Total: ~720 MB/dia

Amb amplificació d'escriptura de 3:
  720 MB × 3 = 2,16 GB/dia a la flash

Vida útil = 1.500 TB / 2,16 GB/dia = 694.444 dies = 1.902 anys

La càrrega de Meteora no desgastarà mai l'SSD. Però canvia l'escenari: un servidor de base de dades que escrigui 500 GB/dia amb WA de 5 gastaria 2,5 TB/dia, i aquests mateixos 1.500 TBW durarien 600 dies. Per això el TBW és una especificació que cal mirar en comprar SSD per a servidors d'escriptura intensiva.

Anivellament de desgast

Si el controlador escrivís sempre als mateixos blocs, aquests s'esgotarien mentre la resta queda intacta. L'anivellament de desgast (wear leveling) reparteix les escriptures uniformement, i fins i tot mou dades estàtiques que fa molt temps que no canvien per alliberar-ne els blocs poc desgastats.

És una altra de les raons per les quals l'SSD necessita indirecció: la relació entre adreça lògica i ubicació física canvia constantment.

TRIM

Quan esborres un fitxer, el sistema de fitxers marca els seus blocs com a lliures a les seves pròpies estructures, però l'SSD no se n'assabenta: per a ell, aquestes dades continuen sent vàlides i les continuarà copiant durant la recollida d'escombraries.

L'ordre TRIM (discard a NVMe) comunica a l'SSD quins blocs ja no contenen dades útils:

$ sudo fstrim -av
/var/lib/meteora: 128,4 GiB (137886920704 bytes) trimmed on /dev/nvme0n1p2
/: 12,1 GiB (12992958464 bytes) trimmed on /dev/nvme0n1p1

$ systemctl status fstrim.timer
● fstrim.timer - Discard unused blocks once a week
     Loaded: loaded (/lib/systemd/system/fstrim.timer; enabled)
     Active: active (waiting) since Mon 2026-08-24 00:00:12 CEST
    Trigger: Mon 2026-09-07 00:00:00 CEST; 6 days left

Sense TRIM, l'SSD acaba creient que és ple encara que el sistema de fitxers vegi espai lliure, i l'amplificació d'escriptura es dispara. Les distribucions modernes activen fstrim.timer setmanalment, que és l'opció recomanada enfront de discard a les opcions de muntatge (aquesta última emet un TRIM per cada esborrat i pot penalitzar el rendiment).

Comparativa HDD enfront d'SSD

Característica HDD 7.200 RPM SSD SATA SSD NVMe
Latència de lectura 12,7 ms 150 µs 50 µs
IOPS aleatòries 4K ~120 ~90.000 ~600.000
Amplada de banda seqüencial 150 MB/s 550 MB/s 3.500 MB/s
Aleatori enfront de seqüencial 168× pitjor 1,2× pitjor ~1× igual
Consum 6-10 W 2-3 W 5-8 W
Cost per GB 0,02 € 0,06 € 0,08 €
Manera de fallar Progressiva, amb avisos Sobtada en esgotar cicles Sobtada

La fila més important és la quarta: en un SSD, l'accés aleatori costa pràcticament el mateix que el seqüencial. Aquesta única diferència invalida dècades d'optimitzacions dissenyades per a discos mecànics, inclosos gairebé tots els algorismes de planificació que veurem tot seguit.

NVMe i per què canvia les regles

Els primers SSD es connectaven per SATA amb el protocol AHCI, dissenyat el 2004 per a discos mecànics. Els seus supòsits ja no valien:

AHCI (SATA) NVMe
Cues de comandes 1 65.535
Comandes per cua 32 65.536
Interfície física SATA 6 Gb/s PCIe (4 GB/s per carril ×4)
Instruccions per E/S ~4 registres MMIO 2
Interrupcions Una línia compartida MSI-X, una per cua i nucli
Latència del protocol ~6 µs ~2,8 µs

La diferència estructural és la paral·lelització. Amb AHCI, una única cua significa que tots els nuclis competeixen per ella amb un forrellat compartit. NVMe dona una cua per nucli, eliminant la contenció per complet: cada CPU envia les seves peticions a la seva pròpia cua sense sincronitzar-se amb ningú.

I aquí connecta amb el que sabem: un SSD té 4-8 canals interns treballant en paral·lel. Per saturar-lo calen moltes peticions simultànies en vol. Amb una sola cua de 32 comandes és impossible; amb 65.535 cues, trivial.

$ lsblk -d -o NAME,ROTA,SIZE,MODEL
NAME    ROTA   SIZE MODEL
nvme0n1    0 931,5G Samsung SSD 980 PRO 1TB
sda        1   7,3T ST8000NM0055-1RM112

La columna ROTA (rotacional) és la que cal mirar: 1 és un disc mecànic, 0 un SSD. El nucli la fa servir per decidir la lectura anticipada, el planificador per defecte i altres polítiques. Comprovar-la és sempre el primer pas en diagnosticar rendiment de disc.

LBA i l'abstracció del dispositiu de blocs

Tot l'anterior —cilindres, capçals, canals NAND, FTL— està ocult. El sistema operatiu veu una abstracció uniforme: el dispositiu de blocs.

Dispositiu de blocs = array lineal de N blocs de mida fixa
                      numerats de 0 a N−1

Aquesta numeració és el LBA (Logical Block Addressing). Abans de 1990 es feia servir adreçament CHS (cilindre-capçal-sector), que exposava la geometria física i limitava la capacitat a 8 GB. LBA el va substituir per un número seqüencial i el microprogramari del disc fa la traducció.

$ sudo blockdev --getsize64 /dev/nvme0n1
1000204886016
$ sudo blockdev --getbsz /dev/nvme0n1
4096
$ cat /sys/block/nvme0n1/queue/logical_block_size
512
$ cat /sys/block/nvme0n1/queue/physical_block_size
512

L'abstracció dona al sistema operatiu exactament quatre operacions:

Operació Què fa
read(lba, n) Llegeix n blocs des del LBA indicat
write(lba, n, dades) Escriu n blocs
flush() Força el buidatge de la memòria cau interna del dispositiu
discard(lba, n) TRIM: aquests blocs ja no contenen dades útils

Aquesta uniformitat és el que permet que el mateix codi del nucli funcioni sobre un disquet, un SSD NVMe, un volum RAID o un disc de xarxa. És la mateixa idea de màquina estesa que vam veure a 01-01, aplicada a l'emmagatzematge. L'operació flush() és especialment important i tornarà a Assignació d'Espai, Journaling i Integritat, perquè un fsync() que no arribi fins al plat físic no garanteix res.

Planificació de peticions de disc

Amb un disc mecànic, l'ordre en què se serveixen les peticions determina quant es mou el braç, i ja sabem que allà hi ha el 99,8 % del cost. És un problema de planificació anàleg al de la CPU, però amb una mètrica diferent: el desplaçament total del capçal.

Treballarem tots els algorismes sobre la mateixa cua:

Cua de peticions (cilindres): 98, 183, 37, 122, 14, 124, 65, 67
Posició inicial del capçal: 53
Rang del disc: 0 a 199

FCFS

Se serveixen en l'ordre d'arribada.

53 → 98 → 183 → 37 → 122 → 14 → 124 → 65 → 67
Moviment Distància
53 → 98 45
98 → 183 85
183 → 37 146
37 → 122 85
122 → 14 108
14 → 124 110
124 → 65 59
65 → 67 2
Total 640

El braç creua el disc d'un extrem a l'altre diverses vegades. És just i simple, però pèssim.

SSTF (la més propera primer)

Es tria sempre la petició més propera a la posició actual.

53 → 65 → 67 → 37 → 14 → 98 → 122 → 124 → 183
Moviment Distància
53 → 65 12
65 → 67 2
67 → 37 30
37 → 14 23
14 → 98 84
98 → 122 24
122 → 124 2
124 → 183 59
Total 236

Una reducció del 63 % enfront de FCFS. Però SSTF és l'equivalent en disc de SJF, i comparteix el seu defecte: inanició. Si arriben contínuament peticions prop del cilindre 60, la del cilindre 183 pot no servir-se mai.

SCAN (l'algorisme de l'ascensor)

El capçal es mou en una direcció servint tot el que troba, arriba a l'extrem i torna. Com un ascensor.

Suposem que es mou cap a cilindres menors:

53 → 37 → 14 → 0 → 65 → 67 → 98 → 122 → 124 → 183
Moviment Distància
53 → 0 53
0 → 183 183
Total 236

Mateix total que SSTF aquí, però sense inanició: tota petició se serveix com a molt en dos recorreguts complets. Aquesta garantia és el que el fa utilitzable.

El seu defecte: les peticions just darrere del capçal esperen un recorregut sencer, mentre que les de just davant se serveixen immediatament. El temps d'espera no és uniforme.

C-SCAN (SCAN circular)

Només serveix peticions en una direcció; en arribar a l'extrem, torna al principi sense servir res en el retorn.

53 → 65 → 67 → 98 → 122 → 124 → 183 → 199 → 0 → 14 → 37
Moviment Distància
53 → 199 146
199 → 0 (retorn ràpid) 199
0 → 37 37
Total 382

Recorre més, però a canvi ofereix un temps d'espera molt més uniforme: el disc es comporta com una llista circular i cap zona no està sistemàticament afavorida. És el compromís que solen preferir els sistemes on la previsibilitat importa més que el rendiment mitjà.

LOOK i C-LOOK

Optimització òbvia de SCAN i C-SCAN: no anar fins a l'extrem físic si no hi ha peticions allà.

LOOK:

53 → 37 → 14 → 65 → 67 → 98 → 122 → 124 → 183
Moviment Distància
53 → 14 39
14 → 183 169
Total 208

C-LOOK:

53 → 65 → 67 → 98 → 122 → 124 → 183 → 14 → 37
Moviment Distància
53 → 183 130
183 → 14 (retorn) 169
14 → 37 23
Total 322

Comparació completa

Algorisme Desplaçament Enfront de FCFS Inanició Espera uniforme
FCFS 640 No
SSTF 236 −63 % No
SCAN 236 −63 % No No
C-SCAN 382 −40 % No
LOOK 208 −67,5 % No No
C-LOOK 322 −50 % No

LOOK guanya en desplaçament total i és el que històricament han fet servir els sistemes UNIX. C-SCAN i C-LOOK són preferibles quan la variància de la latència importa més que la mitjana.

I ara l'observació que cal tenir sempre present: tot aquest apartat pressuposa un capçal que es mou. En un SSD, la «distància» entre el LBA 14 i el 183 és zero: tots dos accessos costen el mateix. Reordenar peticions per a un SSD no només no ajuda, sinó que afegeix latència i consumeix CPU sense cap benefici. És exactament el que va motivar el planificador none de Linux.

Els planificadors reals de Linux

Linux permet triar el planificador d'E/S per dispositiu:

$ cat /sys/block/nvme0n1/queue/scheduler
[none] mq-deadline kyber bfq

$ cat /sys/block/sda/queue/scheduler
none [mq-deadline] kyber bfq

Els claudàtors indiquen l'actiu. Fixa't en la decisió que ha pres el nucli tot sol: none per al NVMe, mq-deadline per al disc mecànic.

Planificador Estratègia Adequat per a Sobrecost
none (noop) FIFO, sense reordenar NVMe, SSD ràpids Mínim
mq-deadline Ordena per LBA amb terminis màxims HDD, SSD SATA Baix
kyber Limita les cues segons la latència objectiu NVMe multicua amb càrrega mixta Baix
bfq Repartiment just per procés, amb pesos Escriptori, càrregues interactives Alt

none no fa res: passa les peticions al dispositiu en l'ordre d'arribada. Sona a rendició, però és l'opció correcta per a NVMe: el dispositiu té les seves pròpies cues paral·leles i el seu propi planificador intern, i en sap més que el nucli sobre la seva geometria. Qualsevol reordenació del sistema operatiu seria una suposició equivocada.

mq-deadline manté dues cues ordenades per LBA (una de lectura, una altra d'escriptura) més dues cues FIFO per termini. Serveix en ordre de LBA —cosa que dona un comportament de tipus LOOK— tret que una petició estigui a punt d'esgotar el seu termini, moment en què salta a servir-la. Els terminis per defecte són reveladors:

$ cat /sys/block/sda/queue/iosched/read_expire
500
$ cat /sys/block/sda/queue/iosched/write_expire
5000

500 ms per a lectures i 5.000 ms per a escriptures. Les lectures tenen deu vegades més prioritat, i la raó és sòlida: una lectura és gairebé sempre síncrona (hi ha un procés bloquejat esperant-la, en estat D), mentre que una escriptura sol ser asíncrona (el procés ja ha continuat, i el nucli la buidarà quan pugui). Endarrerir una lectura bloqueja algú; endarrerir una escriptura no.

bfq (Budget Fair Queueing) dona a cada procés un pressupost de sectors i reparteix l'amplada de banda de manera justa, amb pesos configurables mitjançant ionice. És el que permetia la solució del backup a la lliçó 02-02:

$ sudo ionice -c 3 -p $(pgrep -f backup-diari)
$ ionice -p 1877
best-effort: prio 4
Classe d'ionice Nom Comportament
1 Temps real Accés prioritari garantit
2 Millor esforç Prioritat 0-7, per defecte 4
3 Idle Només quan ningú més no demana disc

Canviar el planificador és immediat i no requereix reiniciar:

$ echo bfq | sudo tee /sys/block/sda/queue/scheduler
$ cat /sys/block/sda/queue/scheduler
none mq-deadline kyber [bfq]

Per fer-ho persistent es fa servir una regla d'udev, mecanisme que veurem a la propera lliçó.

Regla pràctica d'elecció:

Dispositiu i càrrega Elecció
NVMe, servidor none
SSD SATA, servidor mq-deadline
HDD, servidor mq-deadline
Qualsevol, escriptori bfq
NVMe amb càrregues de latència mixta kyber

RAID: combinar discos per capacitat, velocitat o fiabilitat

Un disc falla. La probabilitat anual de fallada d'un disc de servidor ronda l'1-2 %, cosa que sembla poc fins que en tens 100: aleshores esperes una o dues fallades l'any amb certesa pràctica.

RAID (Redundant Array of Independent Disks) combina diversos discos en un volum lògic. Els nivells es distingeixen per com reparteixen dades i redundància.

RAID 0 (divisió, striping)

Les dades es reparteixen en franges entre tots els discos. Sense redundància.

Bloc:   0    1    2    3    4    5
Disc A: [0]      [2]      [4]
Disc B:      [1]      [3]      [5]
  • Capacitat: 100 % de la suma.
  • Rendiment: multiplica per N en lectura i escriptura.
  • Tolerància a fallades: cap. Si falla un disc, es perd tot el volum.

I el parany estadístic: RAID 0 és menys fiable que un disc sol. Amb 4 discos al 2 % de fallada anual:

P(que sobrevisquin els 4) = 0,98^4 = 0,922
P(fallada del volum) = 7,8 % anual, enfront del 2 % d'un disc sol

Multipliques el risc per quatre. Només té sentit per a dades reproduïbles: memòries cau, fitxers temporals, resultats intermedis.

RAID 1 (mirall)

Cada dada s'escriu idèntica a tots els discos.

Disc A: [0][1][2][3]
Disc B: [0][1][2][3]
  • Capacitat: 50 % amb dos discos.
  • Lectura: es pot repartir entre tots dos, fins a 2× més ràpida.
  • Escriptura: la d'un disc (cal escriure als dos).
  • Tolera la fallada d'un disc sense perdre res ni degradar-se gairebé gens.

RAID 5 (paritat distribuïda)

Les dades es divideixen entre N discos i s'hi afegeix un bloc de paritat calculat amb XOR, rotant quin disc el guarda.

Disc A: [D0]  [D3]  [P2]  [D8]
Disc B: [D1]  [P1]  [D6]  [D9]
Disc C: [P0]  [D4]  [D7]  [P3]
Disc D: [D2]  [D5]  [P?]  [D10]

P0 = D0 XOR D1 XOR D2

La màgia del XOR: si es perd D1, es recupera com D1 = D0 XOR D2 XOR P0. La mateixa operació serveix per calcular i per reconstruir.

  • Capacitat: (N−1)/N. Amb 4 discos, el 75 %.
  • Tolera una fallada.
  • Penalització d'escriptura: modificar un bloc exigeix llegir la dada antiga, llegir la paritat antiga, calcular la nova i escriure dos blocs. Quatre operacions d'E/S per escriptura.

El risc seriós de RAID 5 amb discos grans és la reconstrucció. En substituir un disc de 8 TB cal llegir els altres tres sencers:

Dades a llegir: 3 × 8 TB = 24 TB
A 150 MB/s: 24.000.000 MB / 150 MB/s = 160.000 s ≈ 44 hores

Gairebé dos dies amb l'array degradat i sense redundància, sotmetent els discos supervivents —de la mateixa edat i el mateix lot— a una càrrega intensa de lectura. És exactament quan és més probable una segona fallada, i una segona fallada en RAID 5 significa pèrdua total. Per això RAID 5 està desaconsellat amb discos de més de 2 TB.

RAID 6 (doble paritat)

Com RAID 5 però amb dos blocs de paritat independents.

  • Capacitat: (N−2)/N. Amb 6 discos, el 66,7 %.
  • Tolera dues fallades simultànies.
  • Penalització d'escriptura: sis operacions per escriptura.

És la resposta al problema de reconstrucció de RAID 5: durant les 44 hores de reconstrucció encara queda un nivell de redundància.

RAID 10 (mirall + divisió)

Miralls de dos discos, units per divisió.

Franja 1: Mirall(A, B)
Franja 2: Mirall(C, D)
  • Capacitat: 50 %.
  • Sense penalització de paritat: dues operacions per escriptura.
  • Tolera una fallada per mirall; amb sort, fins a la meitat dels discos.
  • Reconstrucció rapidíssima: només cal copiar el disc mirall, no llegir tot l'array.

Amb discos de 8 TB, reconstruir és copiar 8 TB: unes 15 hores, i sense posar en risc la resta de l'array.

Taula comparativa

Amb 4 discos de 8 TB cadascun:

Nivell Capacitat útil Fallades tolerades E/S per escriptura Lectura Reconstrucció
RAID 0 32 TB (100 %) 0 1 Impossible
RAID 1 (2+2) 16 TB (50 %) 1 per mirall 2 Còpia: ràpida
RAID 5 24 TB (75 %) 1 4 Lenta i arriscada
RAID 6 16 TB (50 %) 2 6 Lenta però segura
RAID 10 16 TB (50 %) 1-2 2 Còpia: ràpida

I l'advertiment imprescindible:

RAID no és una còpia de seguretat. Protegeix de la fallada de maquinari, i de res més. No et salva d'un rm -rf accidental, de ransomware, d'una fallada del sistema de fitxers, d'un error del controlador RAID ni d'un incendi. Una còpia de seguretat és una còpia separada en el temps i en l'espai.

La decisió de Meteora per a /var/lib/meteora

Apliquem-ho tot a un cas concret. Requisits:

Requisit Valor
Volum de dades 17 MB/dia = 6,2 GB/any
Retenció 10 anys = 62 GB, més marge: 500 GB
Patró d'escriptura Seqüencial, un fitxer per dia, append continu
Patró de lectura Seqüencial (agregador), aleatori lleuger (meteo-api)
Criticitat Alta: les lectures perdudes no es recuperen
Pressupost Moderat

Anàlisi d'opcions:

Opció Capacitat Valoració
Un sol SSD 1 TB Descartada: una fallada perd 10 anys de dades
RAID 0 (2 SSD) 2 TB Descartada: duplica el risc sense necessitar la velocitat
RAID 5 (4 HDD 8 TB) 24 TB Descartada: 24 TB per a 500 GB, i reconstrucció de 44 h
RAID 6 (6 discos) Descartada: excés de cost i de penalització d'escriptura
RAID 1 (2 SSD 1 TB) 1 TB Escollida

Justificació de RAID 1 amb dos SSD:

  1. El volum és petit. 500 GB projectats a 10 anys caben de sobres en 1 TB. Optimitzar capacitat no aporta res aquí, i aquest és precisament l'argument de RAID 5 i 6.
  2. L'escriptura és contínua i en append. RAID 5 penalitza amb 4 operacions d'E/S per escriptura; RAID 1 només amb 2. Amb l'ingestor escrivint constantment, aquesta diferència importa més que la capacitat.
  3. La reconstrucció és una simple còpia. Substituir un SSD implica copiar com a molt 500 GB, uns 15 minuts a 550 MB/s, sense exposar les dades com faria RAID 5.
  4. La lectura millora: agregador i meteo-api poden llegir dels dos discos en paral·lel.
  5. Simplicitat. RAID 1 és el nivell més fàcil d'entendre, muntar i recuperar. En una emergència a les tres de la matinada, això val més que un 25 % de capacitat extra.

Configuració:

# Crear l'array
$ sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 \
    /dev/nvme0n1p2 /dev/nvme1n1p2

# Comprovar l'estat
$ cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 nvme1n1p2[1] nvme0n1p2[0]
      976630464 blocks super 1.2 [2/2] [UU]

# Planificador: none, perquè són NVMe
$ echo none | sudo tee /sys/block/nvme0n1/queue/scheduler
$ echo none | sudo tee /sys/block/nvme1n1/queue/scheduler

La línia [2/2] [UU] és la que cal vigilar: dos discos de dos actius, tots dos U (up). Si hi veiessis [2/1] [U_], l'array estaria degradat i caldria substituir un disc amb urgència.

I la part que RAID no cobreix: una còpia diària a un altre servidor, en una altra ubicació física. RAID 1 protegeix de la fallada d'un SSD; només la còpia protegeix d'un rm accidental o d'un incendi al rack.

Mesura amb lsblk i iostat -x

$ lsblk -o NAME,ROTA,SIZE,TYPE,MOUNTPOINT,SCHED
NAME        ROTA   SIZE TYPE  MOUNTPOINT          SCHED
nvme0n1        0 931,5G disk                      none
├─nvme0n1p1    0   512M part  /boot/efi           none
└─nvme0n1p2    0   931G part                      none
  └─md0        0   931G raid1 /var/lib/meteora
nvme1n1        0 931,5G disk                      none
└─nvme1n1p2    0   931G part                      none
  └─md0        0   931G raid1 /var/lib/meteora
sda            1   7,3T disk                      mq-deadline
└─sda1         1   7,3T part  /backup             mq-deadline

D'un cop d'ull tens la topologia completa: dos NVMe formant md0 muntat a /var/lib/meteora, un disc mecànic de 7,3 TB per a /backup, i el planificador correcte a cadascun.

iostat -x és l'eina de diagnòstic principal:

$ iostat -x 2 2
Device  r/s     w/s     rkB/s    wkB/s   rrqm/s wrqm/s  r_await w_await aqu-sz  %util
nvme0n1 142,50  388,00  4104,00  9820,00   0,00  12,50    0,08    0,12   0,04   3,20
nvme1n1 138,00  388,00  4020,00  9820,00   0,00  12,50    0,09    0,12   0,04   3,15
md0     280,50  388,00  8124,00  9820,00   0,00   0,00    0,00    0,00   0,00   0,00
sda       2,00  118,50    64,00 18204,00   0,00  84,00   11,20   28,40   3,44  92,10

Columna a columna, amb el que significa cadascuna:

Columna Què mesura Quan preocupa
r/s, w/s Operacions per segon (IOPS) Comparar amb el màxim del dispositiu
rkB/s, wkB/s Amplada de banda Comparar amb el màxim
rrqm/s, wrqm/s Peticions fusionades pel nucli Alt = accés seqüencial (bo)
r_await, w_await Latència mitjana en ms, inclosa la cua La mètrica clau
aqu-sz Longitud mitjana de la cua > 1 sostingut = saturació
%util % de temps amb almenys una petició en curs Enganyosa en NVMe

Lectura d'aquestes dades concretes:

  • nvme0n1 i nvme1n1 tenen xifres gairebé idèntiques, com ha de ser en RAID 1: mateixes escriptures a tots dos, lectures repartides.
  • md0 suma les lectures (280,5 = 142,5 + 138) però no duplica les escriptures (388), que és exactament el comportament esperat del mirall.
  • r_await de 0,08 ms als NVMe. Excel·lent, dins del que és esperable.
  • sda és el problema: w_await de 28,4 ms, aqu-sz de 3,44 i %util del 92,1 %. El disc de backup està saturat escrivint 18 MB/s. Com que és un disc mecànic amb escriptura intensiva, és el seu comportament normal, però convé que el backup no competeixi amb res crític (d'aquí el ionice -c 3).
  • wrqm/s de 84 a sda: el nucli està fusionant moltes peticions contigües abans d'enviar-les, senyal d'escriptura seqüencial. És el que es vol en un disc mecànic.

Un avís important sobre %util: en discos mecànics és fiable (només poden servir una petició alhora, així que el 100 % significa saturació). En NVMe és enganyosa: el dispositiu serveix desenes de peticions en paral·lel, així que pot marcar el 100 % estant al 5 % de la seva capacitat real. En SSD, la mètrica de referència és await, no %util.

$ iostat -x 1 | awk '/^(nvme|sd|md)/ {printf "%-8s await_r=%6.2f await_w=%6.2f cua=%5.2f\n", $1, $10, $11, $21}'

I per mesurar la capacitat real del dispositiu abans de posar res en producció:

$ sudo fio --name=aleatori4k --filename=/var/lib/meteora/prova \
    --rw=randread --bs=4k --iodepth=32 --numjobs=4 \
    --size=1G --runtime=30 --group_reporting

read: IOPS=487k, BW=1903MiB/s (1995MB/s)
     lat (usec): min=8, avg=64.21, max=1842

487.000 IOPS aleatòries de 4 KB amb 64 µs de latència mitjana. Compara-ho amb les ~120 IOPS d'un disc mecànic: un factor de 4.000.

Errors Habituals i Consells

Aplicar la intuïció del disc mecànic a l'SSD. Desfragmentar un SSD no serveix de res i consumeix cicles d'escriptura. Reordenar peticions tampoc: a la flash no hi ha distància. El primer en analitzar rendiment és mirar lsblk -o NAME,ROTA i saber amb què estàs tractant.

Confiar en %util per a SSD. Un NVMe al 100 % de %util pot estar completament ociós en termes reals. Fes servir await i aqu-sz.

Omplir un SSD al màxim. Per sobre del 90 % d'ocupació, la recollida d'escombraries perd eficàcia i l'amplificació d'escriptura es dispara de 2 a 10. Deixa sempre un 10-20 % lliure; molts SSD de servidor el reserven de fàbrica (over-provisioning).

Fer servir RAID 5 amb discos grans. Amb discos de 8 TB, una reconstrucció de 44 hores sense redundància és un risc real de perdre-ho tot. Per a discos de més de 2 TB, RAID 6 o RAID 10.

Confondre RAID amb còpia de seguretat. RAID protegeix de la fallada d'un disc. No protegeix d'esborrats accidentals, corrupció lògica, ransomware ni desastres físics. Són problemes diferents amb solucions diferents.

Oblidar el TRIM. Sense fstrim.timer actiu, un SSD acaba amb el rendiment d'escriptura degradat sense causa aparent. Comprova-ho amb systemctl status fstrim.timer.

Canviar el planificador d'E/S sense mesurar. El valor per defecte que tria el nucli sol ser correcte. Si el vols canviar, mesura abans i després amb fio o amb la càrrega real; molts canvis «d'optimització» empitjoren les coses.

Consell de diagnòstic: davant d'una sospita de problema de disc, aquest és l'ordre que funciona: lsblk -o NAME,ROTA,SCHED (què tens), iostat -x 2 (mirar await i aqu-sz), iotop -o (quin procés està fent E/S) i cat /proc/mdstat si hi ha RAID (està degradat?). I recorda mirar també la columna b de vmstat: si hi ha processos en estat D, ja saps de la lliçó 02-01 que estan encallats esperant exactament això.

Exercicis

Exercici 1: calcular temps d'accés a disc

meteo-01 té un disc de backup amb aquestes característiques:

Velocitat: 7.200 RPM
Temps de cerca mitjà: 9,0 ms
Taxa de transferència: 160 MB/s
Sector: 4 KB
  1. Calcula el temps de llegir un bloc de 4 KB aleatori.
  2. Calcula el temps de llegir els 17 MB de 2026-08-31.dat de manera seqüencial.
  3. Calcula el temps de llegir aquests mateixos 17 MB en blocs de 4 KB dispersos pel disc.
  4. Quantes IOPS aleatòries de 4 KB ofereix aquest disc? Compara-ho amb les 487.000 del NVMe.
  5. Si l'agregador triga 90 segons a processar el dia llegint el fitxer seqüencialment, quina proporció del temps és CPU i quina proporció és disc?

Exercici 2: planificació de peticions de disc

Un disc de 0 a 4.999 cilindres té el capçal al 2.150 i aquesta cua de peticions:

2069, 1212, 2296, 2800, 544, 1618, 356, 1523, 4965, 3681
  1. Calcula el desplaçament total del capçal amb FCFS, SSTF, SCAN (cap amunt), C-SCAN (cap amunt), LOOK (cap amunt) i C-LOOK (cap amunt).
  2. Ordena'ls de millor a pitjor.
  3. Quin triaries si el requisit fos que cap petició no esperés més de 2 recorreguts complets? I si fos minimitzar el temps total?
  4. Si aquest dispositiu fos un SSD NVMe, quina seria la teva resposta i per què?

Exercici 3: decidir una configuració RAID

Meteora vol ampliar l'emmagatzematge. Tens 6 discos de 4 TB i aquests requisits:

  • Dades de lectures (/var/lib/meteora): 500 GB, crítiques, escriptura seqüencial contínua, lectura intensiva.
  • Registres i temporals (/var/log, /tmp): 200 GB, reproduïbles, escriptura intensiva.
  • Arxiu històric (/arxiu): 8 TB, s'escriu una vegada i es llegeix rarament, important però no crític.
  1. Proposa una configuració RAID per a cadascun dels tres usos, indicant quants discos hi assignes.
  2. Calcula la capacitat útil de cada volum.
  3. Justifica cada elecció amb els criteris de la lliçó.
  4. Calcula el temps de reconstrucció de cada volum si falla un disc (suposa 180 MB/s).
  5. Què queda sense cobrir per RAID i què hi faries?

Solucions

Solució 1

1. Bloc de 4 KB aleatori.

Temps de cerca:          9,000 ms
Latència rotacional:     (60.000 ms/min ÷ 7.200 RPM) ÷ 2 = 8,33 ÷ 2 = 4,167 ms
Transferència:           4 KB ÷ 160 MB/s = 0,0244 ms
                       ─────────
Total:                  13,191 ms

Repartiment del temps:

Posicionament:   13,167 ms = 99,8 %
Transferència:    0,024 ms =  0,2 %

2. Els 17 MB seqüencialment.

Cerca inicial:           9,000 ms
Latència rotacional:     4,167 ms
Transferència:           17 MB ÷ 160 MB/s = 106,25 ms
                       ─────────
Total:                  119,42 ms

A la pràctica un fitxer de 17 MB no està perfectament contigu, així que hi hauria alguna cerca addicional, però l'ordre de magnitud és correcte: uns 120 ms.

3. Els mateixos 17 MB en blocs dispersos.

Nombre de blocs: 17.000.000 ÷ 4.096 = 4.150 blocs
Temps: 4.150 × 13,191 ms = 54.743 ms = 54,7 segons
Patró Temps MB/s efectius Factor
Seqüencial 0,119 s 143 MB/s
Aleatori 54,7 s 0,31 MB/s 459× pitjor

La mateixa dada, 459 vegades més lenta. És la diferència entre que l'agregador acabi abans de prendre un cafè o trigui gairebé un minut només a llegir.

4. IOPS aleatòries.

IOPS = 1.000 ms/s ÷ 13,191 ms = 75,8 IOPS

Comparació:

Dispositiu IOPS 4K aleatòries Factor
HDD 7.200 RPM 76
SSD SATA ~90.000 1.184×
SSD NVMe 487.000 6.408×

Aquest factor de 6.408 és una de les xifres més importants de la informàtica de l'última dècada. Explica per què bases de dades que eren inviables van passar a ser trivials, i per què moltes optimitzacions de programari dissenyades per minimitzar E/S aleatòria van deixar de tenir sentit.

Una lectura complementària de la dada: 76 IOPS significa que aquest disc no pot servir ni 76 peticions aleatòries per segon. Si meteo-api rep 40 peticions/segon i cadascuna provoca 2 lectures aleatòries, aquest disc ja és al límit.

5. Repartiment CPU/disc en els 90 segons.

Temps de disc (lectura seqüencial): 0,119 s
Temps total:                       90,000 s
Proporció de disc: 0,119 / 90 = 0,13 %
Proporció de CPU:  99,87 %

L'agregador està limitat per CPU, no per disc. Això confirma quantitativament el que vam deduir a 02-02 a partir dels seus canvis de context (proporció de 63 a 1 entre voluntaris i involuntaris, molt inferior a la dels altres processos).

La conseqüència pràctica és important: canviar el disc de backup per un NVMe no acceleraria gens l'agregador. Estalviaries 0,1 segons de 90. Per accelerar-lo cal optimitzar el càlcul, paral·lelitzar-lo o donar-li més CPU. És el tipus de conclusió que evita gastar diners en el component equivocat, i per això es mesura abans de comprar.

Nota: aquest càlcul canviaria completament si l'agregador llegís de manera aleatòria. En aquest cas serien 54,7 s de disc enfront de 90 s totals, un 61 % de disc, i la conclusió s'invertiria.

Solució 2

Cua: 2069, 1212, 2296, 2800, 544, 1618, 356, 1523, 4965, 3681. Capçal al 2150. Disc de 0 a 4999.

Ordenades: 356, 544, 1212, 1523, 1618, 2069, | 2150 | , 2296, 2800, 3681, 4965

FCFS:

Moviment Distància
2150 → 2069 81
2069 → 1212 857
1212 → 2296 1084
2296 → 2800 504
2800 → 544 2256
544 → 1618 1074
1618 → 356 1262
356 → 1523 1167
1523 → 4965 3442
4965 → 3681 1284
Total 13.011

SSTF:

Pas Des de Més propera Distància
1 2150 2069 (81) enfront de 2296 (146) 81
2 2069 2296 (227) enfront de 1618 (451) 227
3 2296 2800 (504) enfront de 1618 (678) 504
4 2800 3681 (881) enfront de 1618 (1182) 881
5 3681 4965 (1284) enfront de 1618 (2063) 1284
6 4965 1618 3347
7 1618 1523 95
8 1523 1212 311
9 1212 544 668
10 544 356 188
Total 7.586

SCAN (cap amunt, fins a 4999):

2150 → 2296 → 2800 → 3681 → 4965 → 4999 → 2069 → 1618 → 1523 → 1212 → 544 → 356
Tram Distància
2150 → 4999 2849
4999 → 356 4643
Total 7.492

C-SCAN (cap amunt, salt de 4999 a 0):

2150 → ... → 4965 → 4999 → [salt a 0] → 356 → ... → 2069
Tram Distància
2150 → 4999 2849
4999 → 0 (retorn) 4999
0 → 2069 2069
Total 9.917

LOOK (cap amunt, sense arribar a l'extrem):

2150 → 2296 → 2800 → 3681 → 4965 → 2069 → 1618 → 1523 → 1212 → 544 → 356
Tram Distància
2150 → 4965 2815
4965 → 356 4609
Total 7.424

C-LOOK:

2150 → ... → 4965 → [salt a 356] → 356 → ... → 2069
Tram Distància
2150 → 4965 2815
4965 → 356 (retorn) 4609
356 → 2069 1713
Total 9.137

2. Classificació:

Lloc Algorisme Desplaçament Enfront de FCFS
1 LOOK 7.424 −43 %
2 SCAN 7.492 −42 %
3 SSTF 7.586 −42 %
4 C-LOOK 9.137 −30 %
5 C-SCAN 9.917 −24 %
6 FCFS 13.011

3. Elecció segons el requisit.

Si cap petició no ha d'esperar més de dos recorreguts complets: SCAN, C-SCAN, LOOK o C-LOOK, tots vàlids. El determinant és descartar SSTF, que no ofereix aquesta garantia: si arribessin contínuament peticions prop del 2150, la del 4965 podria no servir-se mai. Que en aquest cas concret SSTF doni bon resultat no canvia res; la garantia és sobre el pitjor cas, no sobre un exemple. Entre els quatre vàlids, C-LOOK és la millor opció si a més es vol que l'espera sigui uniforme, perquè no afavoreix sistemàticament cap zona del disc.

Si l'objectiu és minimitzar el temps total: LOOK, amb 7.424 cilindres. Guanya perquè no malbarata moviment anant a extrems buits (34 cilindres de més a SCAN) ni fent el retorn improductiu de les variants circulars.

Nota metodològica: la diferència entre LOOK (7.424) i SSTF (7.586) és només del 2,1 %. Amb una altra cua SSTF podria guanyar. L'avantatge sòlid de LOOK no és el 2 %, sinó la garantia de no inanició al mateix preu.

4. Si fos un SSD NVMe: none, i cap d'aquests algorismes.

El raonament complet:

  • La mètrica perd el sentit. «Desplaçament total del capçal» mesura moviment físic d'un braç. A la flash no hi ha braç. Accedir al LBA 356 i al 4965 costa exactament el mateix: uns 50 µs.
  • Reordenar és contraproduent. Ordenar peticions consumeix CPU i afegeix latència a la cua del nucli, a canvi d'un benefici que és zero. Estàs pagant per no obtenir res.
  • El dispositiu en sap més. L'SSD té la seva pròpia FTL, els seus 4-8 canals paral·lels i el seu propi planificador intern, que coneix la ubicació física real —invisible per al nucli a causa de l'anivellament de desgast—. Qualsevol ordre que imposi el sistema operatiu es basa en una geometria que no existeix.
  • NVMe vol paral·lelisme, no ordre. Amb 65.535 cues, l'òptim és enviar les 10 peticions alhora i deixar que el dispositiu les serveixi en paral·lel pels seus diferents canals. Serialitzar-les en un ordre «òptim» destrueix precisament l'avantatge del NVMe.
$ echo none | sudo tee /sys/block/nvme0n1/queue/scheduler

Estimació del resultat: les 10 peticions, enviades en paral·lel amb una latència de ~50 µs cadascuna i prou paral·lelisme intern, es completarien en aproximadament 50-100 µs en total. Amb el disc mecànic i LOOK, 7.424 cilindres de desplaçament suposen de l'ordre de 150-200 ms. Un factor d'unes 2.000 vegades, obtingut no per planificar millor sinó per deixar de planificar.

Solució 3

1 i 2. Configuració proposada.

Ús Discos Nivell RAID Capacitat útil Necessita
/var/lib/meteora 2 × 4 TB RAID 1 4 TB 500 GB
/var/log, /tmp (compartit amb l'anterior) 200 GB
/arxiu 4 × 4 TB RAID 5 12 TB 8 TB

Detall dels càlculs:

RAID 1 amb 2 discos:  4 TB × 1 = 4 TB útils (50 % de 8 TB)
RAID 5 amb 4 discos:  4 TB × (4−1) = 12 TB útils (75 % de 16 TB)
Total útil: 16 TB de 24 TB bruts (66,7 %)

Les dades crítiques (500 GB) i les reproduïbles (200 GB) caben juntes al RAID 1 de 4 TB amb marge de sobres, en subvolums o particions lògiques diferents. Dedicar discos a part a /var/log seria malbaratar dos discos de 4 TB per a 200 GB.

3. Justificació de cada elecció.

/var/lib/meteora en RAID 1:

  • Criticitat màxima. Les lectures perdudes són irrecuperables, així que la redundància és innegociable.
  • Escriptura seqüencial contínua. RAID 1 costa 2 operacions d'E/S per escriptura; RAID 5 en costa 4 (llegir dada, llegir paritat, escriure dada, escriure paritat). Amb l'ingestor escrivint sense parar, aquesta diferència es paga cada segon.
  • Lectura intensiva. RAID 1 permet servir lectures des dels dos discos en paral·lel, cosa que beneficia directament l'agregador i meteo-api.
  • La capacitat sobra. 500 GB de necessitat enfront de 4 TB disponibles: no hi ha cap argument per sacrificar rendiment o simplicitat a canvi de més espai.

/var/log i /tmp al mateix RAID 1:

  • Són reproduïbles, així que tècnicament RAID 0 n'hi hauria prou. Però dedicar-los discos propis seria malgastar 8 TB bruts per a 200 GB.
  • Conviure amb les dades crítiques els dona redundància de franc, cosa que és un extra benvingut: perdre els registres justament quan estàs diagnosticant una fallada de disc és exactament el pitjor moment possible.
  • Precaució necessària: /var/log creixent sense control podria omplir el volum i bloquejar l'escriptura de lectures. Cal posar-li límit amb logrotate i journald (SystemMaxUse=), o aïllar-lo en un subvolum amb quota.

/arxiu en RAID 5:

  • Aquí sí que mana la capacitat: 8 TB necessaris de 12 TB útils. RAID 10 amb els mateixos 4 discos donaria només 8 TB, just al límit i sense marge de creixement.
  • S'escriu una vegada i es llegeix rarament. La penalització d'escriptura de RAID 5 és irrellevant en una càrrega que gairebé no escriu: és precisament l'escenari per al qual RAID 5 va ser dissenyat.
  • És important però no crític: si es perdés, seria recuperable des de les còpies de seguretat i des del reprocessament de les dades originals.
  • Els discos són de 4 TB, no de 8, cosa que situa la reconstrucció en un rang acceptable, com veurem al punt següent.

4. Temps de reconstrucció a 180 MB/s.

RAID 1 (4 TB):

Dades a copiar: 4 TB = 4.000.000 MB
Temps = 4.000.000 / 180 = 22.222 s = 6,2 hores

I amb només 700 GB de dades reals, moltes implementacions (mdadm amb bitmap, o ZFS/btrfs) copien únicament els blocs usats:

700.000 MB / 180 MB/s = 3.889 s = 1,1 hores

Durant la reconstrucció, el disc supervivent continua servint peticions amb normalitat.

RAID 5 (4 discos de 4 TB):

Cal llegir els 3 discos supervivents sencers: 3 × 4 TB = 12 TB
Temps = 12.000.000 MB / 180 MB/s = 66.667 s = 18,5 hores

Comparació i risc:

Volum Reconstrucció Redundància durant ella Risc
RAID 1 1,1 - 6,2 h Cap (queda 1 disc) Baix: finestra curta
RAID 5 18,5 h Cap (tolera 0 fallades més) Moderat: finestra llarga amb 3 discos sota càrrega intensa

Les 18,5 hores de RAID 5 són acceptables —molt lluny de les 44 hores del cas de 8 TB que vèiem a la lliçó— però mereixen dues precaucions concretes:

# 1. Limitar la velocitat de reconstrucció per no saturar l'array
$ echo 100000 | sudo tee /proc/sys/dev/raid/speed_limit_min

# 2. Comprovació setmanal d'integritat per detectar sectors
#    il·legibles ABANS que calguin en una reconstrucció
$ sudo systemctl enable --now mdcheck_start.timer

# 3. Vigilància SMART per anticipar fallades
$ sudo smartctl -a /dev/sda | grep -E 'Reallocated|Pending|Uncorrectable'

La comprovació periòdica és la més important de les tres: l'escenari que mata RAID 5 és descobrir un sector il·legible al disc B justament durant la reconstrucció del disc A. Llegir tot l'array cada setmana detecta aquests sectors mentre encara hi ha redundància per reparar-los.

5. El que RAID no cobreix.

RAID protegeix exclusivament de la fallada física d'un disc. Queda fora:

Amenaça RAID hi protegeix? Què cal
Fallada d'un disc RAID 1 / 5
rm -rf accidental No Còpia amb historial
Ransomware No Còpia immutable o desconnectada
Corrupció del sistema de fitxers No Còpia + suma de verificació
Fallada del controlador RAID No Còpia en un altre sistema
Incendi, robatori, inundació No Còpia fora de la ubicació
Error a l'ingestor que escriu escombraries No Còpia amb historial

La regla de referència és 3-2-1: tres còpies de les dades, en dos mitjans diferents, amb una fora de l'emplaçament.

Còpia 1: RAID 1 a meteo-01                                (producció)
Còpia 2: /arxiu al RAID 5, amb instantànies diàries       (mateix edifici, altre volum)
Còpia 3: sincronització nocturna a emmagatzematge remot   (una altra ubicació)
# Còpia diària incremental amb historial i verificació
$ rsync -avz --link-dest=/backup/anterior \
    /var/lib/meteora/lectures/ backup@remot:/backup/meteora/$(date +%F)/

--link-dest crea enllaços durs cap a la còpia anterior, de manera que cada dia ocupa només el que ha canviat però es veu com una còpia completa i independent. Amb 17 MB diaris, un any d'historial diari ocupa uns 6,2 GB en lloc de 6,2 TB.

I una última peça que sempre s'oblida: una còpia de seguretat que no s'ha restaurat mai no és una còpia de seguretat, és una esperança. Cal programar una restauració de prova periòdica i verificar que les dades recuperades són llegibles i correctes.

Conclusió

L'emmagatzematge és el nivell de la jerarquia on apareix l'abisme: de la RAM a l'SSD hi ha un factor de 500, i al disc mecànic de 80.000. Tot el disseny del subsistema d'E/S consisteix a evitar creuar-lo.

Un disc mecànic gasta el 99,8 % del temps posicionant-se —cerca més latència rotacional— i només el 0,2 % transferint, cosa que el fa 168 vegades més lent en accés aleatori que seqüencial. D'aquí surten la lectura anticipada, l'agrupació d'escriptures i tota la planificació de peticions. Un SSD inverteix les regles: sense parts mòbils, l'accés aleatori costa el mateix que el seqüencial, però introdueix restriccions pròpies —no es pot sobreescriure sense esborrar el bloc sencer— que obliguen a una FTL, a la recollida d'escombraries, a l'anivellament de desgast i a TRIM, i que fan que un SSD gairebé ple es comporti molt pitjor que un amb espai. NVMe no és només un connector més ràpid: substitueix una cua per 65.535 i elimina la contenció entre nuclis.

Sobre aquesta física, el sistema operatiu aixeca l'abstracció del dispositiu de blocs adreçat per LBA, amb només quatre operacions, que és el que permet que el mateix codi serveixi per a un disquet i per a un array RAID. La planificació de peticions —FCFS, SSTF, SCAN, C-SCAN, LOOK, C-LOOK— redueix el desplaçament fins a un 67 %, però només té sentit si hi ha un capçal per moure: en NVMe l'elecció correcta és none, és a dir, no planificar. Els planificadors reals de Linux reflecteixen exactament això, i mq-deadline incorpora a més una asimetria molt raonada: les lectures tenen un termini deu vegades més curt que les escriptures, perquè darrere d'una lectura gairebé sempre hi ha un procés bloquejat en estat D.

RAID combina discos per capacitat, velocitat o fiabilitat, i l'elecció depèn del patró: RAID 1 per a dades crítiques amb escriptura contínua i volum petit —el cas de /var/lib/meteora—, RAID 5 només amb discos moderats i escriptura escassa, RAID 6 o 10 quan la reconstrucció seria llarga. I l'advertiment que mai no sobra: RAID no és una còpia de seguretat. Finalment, lsblk et diu què tens i iostat -x com es comporta, amb await com a mètrica de referència i %util com a parany en SSD.

Fins aquí hem tractat el disc com el dispositiu. Però un servidor té targetes de xarxa, terminals, rellotges, sensors i controladors de tota mena, i el sistema operatiu ha d'oferir una interfície coherent per a tots ells sense conèixer els detalls de cap. Com ho aconsegueix —la classificació en dispositius de bloc, caràcter i xarxa, el principi que tot és un fitxer, /dev i udev, i les tres maneres que té la CPU de parlar amb un dispositiu— és el que veurem a Gestió de Dispositius.

Fonaments de Sistemes Operatius

Mòdul 1: Introducció als Sistemes Operatius

Mòdul 2: Gestió de Recursos

Mòdul 3: Concurrència

Mòdul 4: Estructures de Fitxers

Mòdul 5: Protecció i Seguretat del Sistema

Mòdul 6: Virtualització i Contenidors

Mòdul 7: Administració i Diagnòstic a la Pràctica

© Copyright 2026. Tots els drets reservats