Module 4 · Unit 11 · Lesson 6 of 7
RAID
Lesson 11.5 presented the disk scheduler and the single device's performance. This lesson presents the technique that combines several devices into one logical unit: RAID (Redundant Array of Inexpensive/Independent Disks). RAID's purpose is twofold — to improve the storage system's performance by using several devices in parallel, and to improve its reliability by adding redundancy so that the system survives a device's failure. The two purposes pull in different directions, and the RAID levels are the different balances that the designers have chosen. RAID is one of the storage stack's most consequential abstractions, and its design shapes the file system's and the application's expectations of the storage's performance and its failure behaviour.
01 Introduction
Lesson 11.5 presented the disk scheduler and the single device's performance: the seek, the rotational delay, the transfer, and the scheduling algorithms that order the requests. This lesson presents the technique that combines several devices into one logical unit: RAID. The acronym stands for Redundant Array of Inexpensive Disks (or, in the modern usage, Independent Disks), and it was introduced by Patterson, Gibson, and Katz in 1988 in a paper that proposed using several cheap disks in place of one expensive one. The paper's insight was that the several disks could be used not only to improve the storage system's performance (by using them in parallel) but also to improve its reliability (by adding redundancy so that the system survives a disk's failure).
RAID's purpose is therefore twofold, and the two purposes pull in different directions. On the one hand, the several disks can be used in parallel to increase the throughput (the striping technique: the data is spread across the disks, and the requests are served concurrently). On the other hand, the several disks can be used to store redundant information so that the system survives a disk's failure (the mirroring technique: the data is stored on two or more disks, and the system can read from any of them; or the parity technique: an additional piece of data is computed and stored so that a missing piece can be reconstructed). The two techniques can be combined, and the different combinations are the RAID levels.
The RAID levels are the different balances that the designers have chosen. RAID 0 uses the striping alone: it maximizes the performance but provides no redundancy. RAID 1 uses the mirroring: it provides the strongest redundancy at the cost of the storage capacity. RAID 5 uses the striping plus a single parity: it provides the redundancy with a smaller capacity cost, at the price of a more complex write path. RAID 6 uses the striping plus two parities: it survives two disks' failures at the price of a still more complex write path. RAID 10 combines the mirroring and the striping: it provides the strong redundancy and the strong performance at the cost of half the storage capacity.
This lesson presents RAID. It defines the RAID's
motivations — the reliability, the availability, and
the redundancy — and the storage system's failure
model. It presents the three techniques — the
striping, the mirroring, and the parity — and the
RAID levels that combine them. It presents the RAID
levels' performance analysis: the read and write
throughput, the small-write problem, and the
write-hole. It presents the hardware and software
implementations (the RAID controllers, the
mdadm, the LVM's RAID targets, the
Btrfs's and ZFS's integrated RAID). It presents the
rebuild process and its vulnerabilities (the rebuild
time, the second failure's risk, the
RAID 5 write hole). It presents the RAID's
interaction with the solid-state drives (the
different failure modes, the write amplification),
and it closes with the RAID's design trade-offs and
the modern storage systems' choices.
Prerequisites
This lesson builds on Lessons 11.1 through 11.5.
The hard disk's performance characteristics (the
seek, the rotational delay, and the transfer), the
DMA machinery, the device driver and the block
layer's request queue, and the disk scheduling
algorithms are all assumed. The file system's
allocation and its journaling (Lessons 10.5 and
10.6) are the context for the discussion of the
RAID's interaction with the file system, and the
checksums (Lesson 10.6) are the context for the
discussion of the RAID's data integrity. No new
operating-system concepts are introduced; the
lesson is about the RAID's techniques and their
trade-offs. Familiarity with the Linux command
line from Lesson 2.2 is helpful, since the
interactive activity uses mdadm and
the LVM tools.
02 Learning objectives
By the end of this lesson you will be able to
- Define the reliability, the availability, and the redundancy, and explain the storage system's failure model.
- Describe the three RAID techniques (striping, mirroring, and parity) and explain how they combine into the RAID levels.
- Describe the RAID levels (0, 1, 5, 6, 10) and their historical predecessors (2, 3, 4), with their performance, their capacity, and their reliability characteristics.
- Explain the small-write problem and the write-hole problem, and describe the techniques (the read-modify-write, the reconstruct-write, the battery-backed write cache, the journal) that address them.
- Compare the hardware and software RAID implementations (the RAID controllers,
mdadm, LVM, ZFS, Btrfs). - Describe the RAID rebuild process and its vulnerabilities, and explain how the modern storage systems (with SSDs, checksums, and erasure coding) address them.
This lesson contributes to U11.6 and U11.7, and to course learning outcomes CLO1, CLO5, and CLO7.
03 Required reading
- Operating System Concepts — Chapter 11, Mass-Storage Structure, Section 11.8, RAID Structure. The standard treatment of the RAID levels, their performance, and their reliability.
- OSTEP — Chapter 38, Redundant Arrays of Inexpensive Disks (RAIDs). OSTEP's treatment of the RAID levels, their evaluation, and their trade-offs is the clearest available account, and it is the basis for the worked example in this lesson.
- Tanenbaum & Bos — Modern Operating Systems, Chapter 5, Section 5.4.3, RAID. A complementary treatment that develops the RAID levels from first principles and compares them systematically.
- Patterson, D. A., Gibson, G., & Katz, R. H. — A Case for Redundant Arrays of Inexpensive Disks (RAID). ACM SIGMOD Conference, 1988. The paper that introduced the RAID terminology and the levels 1 through 5.
- Chen, P. M., Lee, E. K., Gibson, G. A., Katz, R. H., & Patterson, D. A. — RAID: High-Performance, Reliable Secondary Storage. ACM Computing Surveys, 1994. The comprehensive survey of the RAID levels, their performance, and their reliability.
- Leventhal, A. — Triple-Parity RAID and Reed-Solomon Coding. The extensions of the parity technique beyond the RAID 6's two parities (the erasure codes).
-
Linux man pages:
man 8 mdadm,man 4 md,man 7 md,man 8 lvm,man 8 pvcreate,man 8 vgcreate,man 8 lvcreate,man 5 mdadm.conf,man 8 mkfs.ext4,man 8 mkfs.xfs,man 8 mkfs.btrfs,man 8 zpool(if ZFS is installed),man 1 dmesg,man 8 smartctl,man 1 lsblk.
Reading strategy
Read the OSTEP chapter first. It develops the RAID
levels from a concrete example — a workload with a
sequence of logical block requests — and shows
step by step how each level handles a read and a
write. The chapter's analysis of the RAID 0, 1, 4,
and 5's performance for the sequential and the
random workloads is the basis for this lesson's
performance discussion, and its discussion of the
RAID 5's small-write problem is the basis for the
write-hole's discussion. Then read the Silberschatz
section for the formal terminology and the
comprehensive treatment of the RAID levels 0
through 6. The Patterson et al. paper is the
historical source, and it is worth reading for the
original motivation and the levels 1 through 5's
definitions. The Chen et al. survey is the
comprehensive reference, and it is worth
consulting for the detailed performance and
reliability analysis. The Linux man pages are the
practical tools: mdadm is the Linux
software RAID's management tool, and the
md and mdadm.conf pages
document the kernel's RAID device and its
configuration. Pay particular attention to the
distinction between the reliability (the
system's ability to survive a failure) and the
availability (the system's ability to
continue serving the requests while a failure is
being repaired). The two are related but not
identical: a system can be reliable (its data is
not lost) but unavailable (it cannot serve the
requests while the repair is in progress), and the
RAID levels' differences are the different
balances between the two.
04 Core content
4.1 Reliability, availability, and redundancy
The RAID's motivation is the storage system's failure and the user's need to survive it. The three concepts are related but distinct:
- Reliability
- The probability that the storage system delivers the correct data over a specified period, without losing or corrupting it. A reliable system's data is preserved across the failures of its components, and the system's design must account for the failure modes — the disks' mechanical failures, the controllers' electronics failures, the cables' disconnections, and the power supply's outages. The reliability's measure is the mean time to data loss (MTTDL), the expected time between the failures that lose the data.
- Availability
- The fraction of the time that the storage system is able to serve the requests. An available system continues to serve the requests even when a component fails, either by using the redundant components or by degrading gracefully. The availability's measure is the uptime percentage: a system with 99.9% availability is unavailable for about 8.76 hours per year, and a system with 99.999% availability is unavailable for about 5.26 minutes per year. The RAID levels improve the availability by allowing the system to continue serving the requests while a failed disk is being repaired.
- Redundancy
- The storage system's technique for surviving a component's failure: the additional data (the mirror's copy or the parity's reconstruction information) that the system stores so that it can reconstruct a failed component's data. The redundancy is the mechanism, and the reliability and the availability are the properties that it provides. The redundancy's measure is the redundancy factor: the ratio of the total storage capacity to the usable capacity (a 2-disk mirror has a redundancy factor of 2; a 5-disk RAID 5 has a redundancy factor of 5/4 = 1.25).
The redundancy's design has three questions: what granularity (the disk's failure, the block's failure, or the byte's failure), what technique (the mirroring, the parity, or the erasure coding), and what layout (the data's and the redundancy's placement across the disks). The RAID levels are the different answers, and their differences are the lesson's subject.
4.2 The three RAID techniques
RAID combines three techniques, each with its own characteristics:
- Striping
- The data is divided into stripes (small units, typically 4 KB to 1 MB), and the stripes are distributed across the disks in a round-robin order. A logical block's physical location is determined by its logical address: block i is on disk i mod N (for N disks), at the appropriate offset. The striping's purpose is the parallelism: the requests that target different disks are served concurrently, so the system's throughput is the sum of the disks' throughputs. The striping's disadvantage is the reliability: a single disk's failure destroys the entire array's data (the failed disk's stripes are lost, and the array has no way to reconstruct them). The striping's granularity is a design parameter: a fine-grained stripe (a few KB) distributes each request across several disks, so a large request's throughput is high but a small request's latency is low; a coarse-grained stripe (a few hundred KB) keeps each request on one disk, so the small requests' latency is low but the large requests' parallelism is reduced.
- Mirroring
- The data is stored on two or more disks, and the copies are identical. A write updates all the copies; a read can be served by any of the copies (typically the one whose disk is closest, or the one that is least busy). The mirroring's purpose is the reliability: a single disk's failure leaves the other copies intact, and the system can continue serving the requests from the surviving copies. The mirroring's disadvantage is the capacity cost: a 2-disk mirror uses half the raw capacity for the redundancy, so the usable capacity is half the raw capacity. The mirroring's read performance is the sum of the disks' read throughputs (the reads can be distributed across the copies); its write performance is the minimum of the disks' write throughputs (a write must update all the copies, so the write is as slow as the slowest disk). The mirroring's n-way variant (RAID 1 with three or more copies) provides a stronger reliability at a still higher capacity cost.
- Parity
- The data is striped across the disks, and an additional parity block is computed and stored for each stripe. The parity is the exclusive-or (XOR) of the stripe's data blocks: P = D1 ⊕ D2 ⊕ … ⊕ DN−1. The parity's purpose is the reliability with a smaller capacity cost than the mirroring's: a single parity block can reconstruct a single failed data block, so the array survives a single disk's failure. The reconstruction is straightforward: the failed block Di = P ⊕ D1 ⊕ … ⊕ Di−1 ⊕ Di+1 ⊕ … ⊕ DN−1. The parity's cost is the write amplification: a single data block's update requires the parity block's update as well, and the parity's update requires reading the old data and the old parity (the read-modify-write) or reading the stripe's other data blocks (the reconstruct-write). The parity's design is the source of the RAID 5's small-write problem, which the lesson addresses in section 4.4.
4.3 The RAID levels
The RAID levels combine the three techniques, and each level's design is a different balance. The classical levels (0 through 6) are:
- RAID 0 (striping, no redundancy)
- The data is striped across N disks with no redundancy. The usable capacity is the sum of the disks' capacities, the read and the write throughputs are N times a single disk's, and the reliability is worse than a single disk's: any disk's failure destroys the entire array's data. RAID 0 is used for the workloads where the performance matters and the data is either replaceable (the scratch space, the build caches) or protected by another mechanism (the application-level replication, the periodic backups).
- RAID 1 (mirroring)
- The data is stored on two (or more) disks, and the copies are identical. The usable capacity is half the raw capacity (for the 2-disk case), the read throughput is the sum of the disks' (the reads can be distributed), the write throughput is a single disk's (the writes must update both copies), and the reliability is strong: the array survives a single disk's failure. RAID 1 is used for the workloads where the reliability matters and the capacity cost is acceptable (the boot volumes, the database's redo logs, the small high-value datasets).
- RAID 2 (bit-level striping with the Hamming code)
- A historical level that stripes the data at the bit level and uses the Hamming code for the error correction. RAID 2 is not used in practice (the bit-level striping requires the disks to be synchronized, and the modern disks have their own error correction), and it is mentioned only for completeness.
- RAID 3 (byte-level striping with a dedicated parity)
- A historical level that stripes the data at the byte level and dedicates a single disk to the parity. RAID 3's design assumes that the requests are large (so the byte-level striping's parallelism is useful) and that the disks are synchronized (so the parity's computation is straightforward). The modern workloads' requests are usually small and the modern disks are not synchronized, so RAID 3 is not used in practice.
- RAID 4 (block-level striping with a dedicated parity)
- The data is striped at the block level, and a single disk is dedicated to the parity. A read can be served by the data disk that holds the requested block, and a large read can use the parallelism across the data disks. A write requires the parity's update, and the parity disk is the bottleneck: every write to any data disk requires a write to the parity disk, so the parity disk's throughput limits the array's write throughput. The observation is the reason RAID 4 was replaced by RAID 5, which distributes the parity across the disks.
- RAID 5 (block-level striping with a distributed parity)
- The data is striped at the block level, and the parity is distributed across the disks: for each stripe, one of the disks holds the parity, and the parity's disk rotates from stripe to stripe. The distribution eliminates the RAID 4's parity bottleneck: the writes' parity updates are spread across the disks, so the array's write throughput is higher. The usable capacity is the raw capacity minus one disk's (the parity's overhead: N−1 disks' worth for N disks). The read throughput is N−1 times a single disk's (the data's disks), and the write throughput is reduced by the parity's updates. The reliability is strong for a single disk's failure, and it is the reason RAID 5 is the most common RAID level for the general-purpose storage. The write path's complexity (the read-modify-write or the reconstruct-write) is RAID 5's principal disadvantage, and the RAID 5 write hole (section 4.4) is its most subtle failure mode.
- RAID 6 (block-level striping with two parities)
- The data is striped at the block level, and two parities are computed and stored for each stripe. The second parity (typically the Reed-Solomon code or the P+Q scheme) allows the array to survive two disks' failures, which is important for the large arrays (the rebuild time for a large array is long, and the second failure's risk is significant during the rebuild). The usable capacity is the raw capacity minus two disks', the write throughput is lower than the RAID 5's (the two parities' updates), and the reliability is the strongest of the classical levels. RAID 6 is used for the large arrays (the storage servers, the backup systems) where the double failure's risk matters.
- RAID 10 (a stripe of mirrors)
- The disks are grouped into the mirrored pairs (the RAID 1's sets), and the pairs are striped (the RAID 0's arrangement). A write updates both disks of the target pair, and the pairs are used in parallel. The usable capacity is half the raw capacity, the read throughput is the sum of the pairs' (the reads can be distributed across the pairs and within each pair), the write throughput is the sum of the pairs' (the writes to different pairs are concurrent), and the reliability is strong: the array survives a single disk's failure, and (in the common configurations) it can survive several failures as long as no two failures hit the same pair. RAID 10 is used for the workloads where both the performance and the reliability matter (the databases, the transaction-processing systems), and its disadvantage is the capacity cost (half the raw capacity).
The levels' comparison is summarized in the following table. The table's "usable capacity" column assumes N disks of equal size, and the "fault tolerance" column gives the number of the disks' failures that the array survives.
| Level | Technique | Usable capacity | Read throughput | Write throughput | Fault tolerance |
|---|---|---|---|---|---|
| RAID 0 | Striping | N disks | N× | N× | 0 failures |
| RAID 1 | Mirroring | N/2 disks | N× | 1× | N/2 failures (one per pair) |
| RAID 4 | Striping + dedicated parity | N−1 disks | N−1× | Low (parity bottleneck) | 1 failure |
| RAID 5 | Striping + distributed parity | N−1 disks | N−1× | Reduced (parity updates) | 1 failure |
| RAID 6 | Striping + two parities | N−2 disks | N−2× | More reduced (two parities) | 2 failures |
| RAID 10 | Striping + mirroring | N/2 disks | N× | N/2× | N/2 failures (one per pair) |
4.4 The small-write problem and the write hole
The RAID 5's parity is the source of its most important performance problem: the small-write problem. When an application updates a single data block in a RAID 5 array, the array must update the corresponding parity block as well, and the parity's update requires the old data and the old parity (or the stripe's other data blocks). There are two strategies:
- Read-modify-write (RMW). The array reads the old data block and the old parity block, computes the new parity (the old parity XOR the old data XOR the new data), and writes the new data and the new parity. The strategy requires two reads and two writes — four I/O operations for a single logical write. The strategy is efficient when the block's disk is idle, because the reads can be issued in parallel with the writes.
- Reconstruct-write (RCW). The array reads the stripe's other data blocks, computes the new parity (the XOR of the other data blocks and the new data), and writes the new data and the new parity. The strategy requires N−1 reads and two writes — one read for each of the stripe's other data blocks. The strategy is efficient when the stripe's other blocks are in the cache (or when the write's data is enough to justify the reads), and it is the preferred strategy for the large writes (the writes that span the whole stripe).
The two strategies' cost is the small-write problem: a single logical write requires several physical operations, and the array's write throughput is reduced. The problem is the reason the RAID 5's write throughput is lower than its read throughput, and it is the reason the RAID 5 is not the right choice for the write-heavy workloads (the databases' transaction logs, the write-intensive applications).
The write hole is a subtler problem. Consider a RAID 5 array with the battery-backed write cache (or the disk's own cache) and a power failure in the middle of a stripe's update. The array's data and its parity are inconsistent: the data block is the new value, but the parity block is the old value (or vice versa), and the array's reconstruction of a failed disk's block would be wrong. The problem is the write hole: the window during which the data and the parity are inconsistent, and the window is closed only when the update completes. The write-hole is the reason the RAID 5's reliability is not perfect: a disk's failure during the window (a power failure followed by a disk's failure, or a crash during the rebuild) can corrupt the array's data.
The write-hole's solutions are:
- The battery-backed write cache. The RAID controller's cache has a battery (or a capacitor), so the cache's contents survive a power failure and the controller can complete the pending updates when the power is restored. The battery-backed cache is the classical solution, and it is the reason the hardware RAID controllers include the battery.
-
The journal (the write-intent log).
The array writes the update's intent to a
journal (a small log on a separate device
or on the array itself) before it applies the
update, so a crash's recovery can replay the
journal and complete the update. The journal is
the software RAID's solution, and it is the reason
mdadm's RAID 5 has the--write-journaloption. - The copy-on-write (the Btrfs's and ZFS's approach). The file system never overwrites a block in place; every modification writes a new block and updates the tree's root pointer atomically. The copy-on-write avoids the write-hole entirely, because the old data and the old parity remain consistent until the new tree is committed. The approach is the modern storage systems' preferred solution, and it is the reason the Btrfs's and ZFS's RAID implementations are more robust than the classical RAID's.
4.5 The RAID's performance analysis
The RAID levels' performance depends on the workload's access pattern. The following analysis assumes N disks with the same performance characteristics, and it gives the read and write throughputs in the units of a single disk's throughput:
| Level | Sequential read | Sequential write | Random read | Random write |
|---|---|---|---|---|
| RAID 0 | N× | N× | N× | N× |
| RAID 1 | N× | 1× | N× | 1× |
| RAID 5 | N−1× | N−1× | N−1× | Low (2 reads + 2 writes) |
| RAID 6 | N−2× | N−2× | N−2× | Lower (more parity's work) |
| RAID 10 | N× | N/2× | N× | N/2× |
The table's pattern shows the levels' trade-offs. The RAID 0 is the fastest but the least reliable; the RAID 1 and the RAID 10 are the strongest for the reads but the weakest for the writes (the writes must update all the copies); the RAID 5 and the RAID 6 are the balanced choices for the general-purpose workloads, and their weakness is the random writes' parity's overhead.
The analysis is idealized; the real systems' performance depends on the workload's access pattern, the stripe's size, the cache's size, and the controller's design. The key insight is that the RAID levels' performance is not a single number but a function of the workload's characteristics: a level that is fast for the sequential reads may be slow for the random writes, and the system's design must match the level to the workload.
4.6 Hardware and software RAID
The RAID can be implemented in hardware or in software, and the two implementations have different characteristics:
- Hardware RAID
- A dedicated controller (a RAID card) performs the RAID's operations: it presents the array to the operating system as a single logical device, and it performs the striping, the mirroring, and the parity's computation in its own hardware. The hardware RAID's advantages are the operating system's simplicity (the OS sees a single device, with no RAID's awareness), the controller's capabilities (the battery-backed cache, the dedicated parity's computation, the hot-swap support), and the performance (the controller's hardware offloads the parity's computation from the host's processor). The hardware RAID's disadvantages are the cost (the controllers are expensive), the vendor lock-in (a failed controller must be replaced with the same model, or the array's metadata must be recovered), and the obsolescence (an old controller's firmware may not be supported by the new operating systems).
- Software RAID
-
The host's processor performs the RAID's
operations. The Linux kernel's
md(multiple device) driver is the classical implementation, andmdadmis its management tool. The software RAID's advantages are the cost (no additional hardware), the portability (the array's metadata is stored on the member disks, so the array can be moved between the systems), and the flexibility (the array's parameters can be changed at runtime, and the modern kernels support the online resizing and the reshaping). The software RAID's disadvantages are the host's processor's overhead (the parity's computation consumes the processor's cycles, which can be significant on the write-heavy workloads) and the host's memory's overhead (the RAID's metadata and its cache consume the memory). The modern processors' performance has reduced the overhead's significance: a modern multi-core processor can perform the RAID 5's parity's computation at the storage device's full throughput, and the software RAID's performance is close to the hardware RAID's for the general-purpose workloads.
The modern storage systems provide additional implementations:
-
LVM (Logical Volume Manager). The
LVM's RAID targets (the
raid0,raid1,raid5,raid6, andraid10targets) provide the RAID's functionality within the LVM's framework. The LVM's RAID is a software implementation that uses the kernel'sdm-raidtarget, and its advantage is the integration with the LVM's other features (the snapshots, the thin provisioning, the online resizing). -
Btrfs's integrated RAID. The Btrfs
file system provides the RAID's functionality as a
first-class feature: the administrator specifies
the RAID's profile (the
single, theraid0, theraid1, theraid10, theraid5, or theraid6), and the file system's allocation policy places the data and the metadata accordingly. The Btrfs's RAID is the copy-on-write's implementation: the data's placement is part of the file system's metadata, and the checksums' verification is the RAID's integrity mechanism. The Btrfs's RAID is more robust than the classical RAID's (the write-hole is avoided by the copy-on-write), and its disadvantage is its maturity (the RAID 5/6 support has had the stability problems). - ZFS's integrated RAID. The ZFS file system provides the RAID's functionality through its storage pools: the administrator creates a pool from the devices, and the pool's redundancy is configured with the mirrors or the RAID-Z (the RAID 5-like and the RAID 6-like schemes). The ZFS's RAID is the copy-on-write's implementation, with the checksums and the self-healing: the file system detects the corruption (the checksums) and repairs it from the redundant copy (the mirror or the RAID-Z's parity). The ZFS's RAID is the modern storage systems' most thorough implementation, and its disadvantage is its memory's requirements and its licensing (the CDDL is incompatible with the GPL).
- The cloud storage's erasure coding. The distributed storage systems (the Ceph, the Swift, the HDFS) use the erasure coding rather than the classical RAID: the data is divided into the fragments, and the additional fragments (the parity-like codes) are computed and distributed across the storage nodes. The erasure coding's advantage is the flexibility: the administrator can choose the number of the data's fragments (k) and the total fragments (n), and the scheme's fault tolerance is n−k fragments' failures. The erasure coding is the cloud storage's standard because it provides the strong reliability at a small capacity cost, and its implementation's complexity is hidden in the storage system's software.
4.7 The RAID's rebuild and its vulnerabilities
When a disk in a RAID array fails, the array must be rebuilt: the failed disk is replaced, and the array reconstructs the failed disk's data from the surviving disks' data and parity (the RAID 5 and the RAID 6) or from the mirror (the RAID 1 and the RAID 10). The rebuild is a critical period for the array's reliability:
- The rebuild's duration. The rebuild reads the surviving disks' data and writes the reconstructed data to the replacement disk. The rebuild's duration depends on the array's size and the disks' speed: a 4 TB array at 100 MB/s takes about 11 hours, and a 20 TB array takes over 2 days. During the rebuild, the array is vulnerable: the disks are under the heavy load (the rebuild's reads and writes), and the remaining disks' failure would destroy the array's data.
- The second failure's risk. The mean time to failure (MTTF) of the modern disks is typically 1 to 5 million hours, but the annualized failure rate (AFR) is higher, because the disks' failures are not uniformly distributed: the infant mortality and the wear-out effects make the failures cluster. The bit error rate (the probability that a read returns the wrong data without detecting the error) is typically 10−14 to 10−15, and it is significant for the large arrays: a 12 TB disk's full read is 1013 bits, so the expected number of the undetected errors is about 0.1 to 1 per full read. The error rate's significance is the reason the large arrays use the RAID 6 or the RAID 10 rather than the RAID 5: the second failure's risk during the long rebuild is real.
- The rebuild's interference. The rebuild's reads and writes compete with the applications' I/O, so the array's performance degrades during the rebuild. The degradation is significant for the RAID 5 and the RAID 6 (the rebuild's reads are the whole array's), and it is smaller for the RAID 1 and the RAID 10 (the rebuild's reads are the surviving mirror's).
- The silent data corruption. A disk can return the wrong data without reporting an error (the silent data corruption, or the bit rot), and the RAID's parity's reconstruction cannot detect it: if the disk returns the wrong data, the array's reconstruction uses the wrong data, and the corrupted block is propagated to the replacement disk. The silent corruption's defence is the checksums (Lesson 10.6): the file system's or the array's checksums detect the corruption, and (in the RAID 6, the RAID 10, or the RAID-Z) the surviving copies allow the correction. The checksums' necessity is the reason the modern storage systems (ZFS, Btrfs) integrate them with the RAID.
The rebuild's vulnerabilities are the reason the modern storage systems' designs have changed:
- The RAID 6 and the erasure coding. The RAID 6's two parities allow the array to survive a second disk's failure during the rebuild, and the erasure coding's higher redundancy (n−k fragments) allows the larger arrays to survive more failures.
- The larger arrays' RAID 10. The RAID 10's mirroring allows the array to survive a disk's failure in each mirror, and the rebuild's duration is shorter (the rebuild reads only the surviving mirror, not the whole array).
- The checksums and the self-healing. The ZFS's and Btrfs's checksums detect the silent corruption, and their redundant copies allow the correction. The self-healing is the modern storage systems' most important reliability feature, and it is the reason the modern systems' RAID is more robust than the classical RAID.
- The proactive maintenance. The modern systems' monitoring (the SMART's attributes, the error counters) allows the administrator to replace a disk before it fails, so the array's rebuild is planned and the failure's risk is reduced. The proactive maintenance is the operational defence, and it complements the technical defences.
4.8 RAID and solid-state drives
The solid-state drives' characteristics change the RAID's design in several ways:
- The failure modes. The SSDs' failures are different from the hard disks': the SSDs tend to fail suddenly (the controller's failure, the firmware's bug, the flash's wear-out), rather than the gradual degradation that the hard disks exhibit. The sudden failures make the proactive maintenance less effective, and they make the array's redundancy more important.
- The write amplification. The SSDs' flash translation layer performs the read-modify-erase-write cycles, and the RAID's parity's updates add to the amplification: the RAID 5's small write requires the additional reads and writes, and the SSD's internal garbage collection's work is increased. The observation is the reason the SSD-based arrays prefer the RAID 1, the RAID 10, and the RAID-Z (the mirroring's designs) over the RAID 5: the mirroring's writes do not require the parity's read-modify-write, so the amplification is smaller.
- The rebuild's speed. The SSDs' rebuild is faster than the hard disks' (the SSDs' random reads are nearly as fast as their sequential reads), so the rebuild's window is shorter and the second failure's risk is smaller. The observation is the reason the SSD arrays can use the RAID 5 more safely than the hard disk arrays.
-
The TRIM's propagation. The
modern SSDs use the TRIM command to inform the
drive which blocks are free, so the drive's
garbage collection can reclaim them. The RAID
array's TRIM's propagation is a design challenge:
the array's logical blocks are the stripes, and
the TRIM's information must be translated to the
member disks' blocks. The modern Linux kernels
support the RAID's TRIM's propagation (the
mdadm's--discardoption), but the support's performance and correctness vary.
The SSDs' characteristics' implications are the reason the modern storage systems' designs differ for the SSD and the hard disk arrays:
- The SSD arrays often use the mirroring (the RAID 1, the RAID 10, or the RAID-Z's equivalents) rather than the parity, because the mirroring's writes are simpler and the amplification is smaller.
- The SSD arrays use the higher-level integrity (the checksums, the end-to-end protection) to detect the silent corruption, and they rely on the redundant copies to correct it.
- The SSD arrays' controllers (the NVMe devices' internal parallelism, the RAID controllers' SSD-awareness) perform the device-level scheduling and the wear leveling, and the array's design must cooperate with them rather than fight them.
4.9 Common misconceptions
"RAID is a backup."
RAID is not a backup. RAID protects against the disk's failure, but it does not protect against the accidental deletion, the application's bug, the malware, the fire, the flood, or the theft. A RAID array's data can be lost by any of these, and the backup (the separate copy, on the separate medium, at the separate location) is the only defence. The RAID's redundancy and the backup's copy are complementary, and both are necessary.
"RAID 5 is always safe."
The RAID 5's safety depends on the array's size and the disks' characteristics. The large arrays (the tens of terabytes) and the high-capacity disks (the multi-terabyte) make the rebuild's duration long, and the second failure's risk (including the silent corruption's undetected error) is significant. The modern guidance is to use the RAID 6, the RAID 10, or the erasure coding for the large arrays, and to reserve the RAID 5 for the small arrays or the SSD-based arrays (whose rebuild is faster).
"RAID 0 is always faster."
The RAID 0's throughput is the sum of the disks' for the large requests (which the striping's parallelism serves), but its small requests' latency is the minimum of the disks' (a small request is served by one disk, and the array's latency is that disk's). The RAID 0's advantage is the throughput, not the latency, and the RAID 1's or the RAID 10's read latency can be lower (the reads can be distributed, and the least-busy disk can serve the request).
"The hardware RAID is always better than the software RAID."
The hardware and the software RAIDs have different trade-offs. The hardware RAID's advantages are the operating system's simplicity, the battery-backed cache, and the dedicated parity's computation. The software RAID's advantages are the cost, the portability, and the flexibility. The modern processors' performance has reduced the software RAID's overhead's significance, and the modern distributions' software RAID (the mdadm, the LVM's RAID, the Btrfs's and ZFS's integrated RAID) is the appropriate choice for the general-purpose workloads.
"The RAID's parity is a checksum."
The RAID's parity is the XOR of the stripe's data blocks, and it is not a checksum: it does not detect the corruption, it only allows the reconstruction of a missing block. If a disk returns the wrong data (the silent corruption), the RAID's reconstruction propagates the wrong data, and the parity does not detect it. The checksums are the corruption's detection mechanism, and the modern storage systems (ZFS, Btrfs) integrate them with the RAID.
"The RAID's stripe's size does not matter."
The stripe's size determines the parallelism's granularity: a fine-grained stripe (a few KB) distributes each request across the several disks, so the large requests' throughput is higher but the small requests' latency is higher (the request spans the several disks, and the array waits for all of them). A coarse-grained stripe (a few hundred KB) keeps each request on one disk, so the small requests' latency is lower but the large requests' parallelism is reduced. The stripe's size is a tunable parameter, and the array's design must match it to the workload.
"The RAID's rebuild is just a copy."
The rebuild is not a simple copy: for the RAID 5 and the RAID 6, the rebuild computes the failed disk's data from the surviving disks' data and parity, so the rebuild's reads are the whole array's and the reconstruction's computation is significant. The rebuild's duration and its interference with the applications' I/O are the reasons the large arrays' rebuild is a critical period, and the modern systems' designs (the RAID 6, the RAID 10, the erasure coding) are shaped by the rebuild's constraints.
"The RAID's level is a permanent choice."
The RAID's level can be changed (the
mdadm's --grow --level=
option, the LVM's lvconvert, the
Btrfs's and ZFS's balance), but the
change is an offline operation (the array's data
must be reorganized), and its duration is
proportional to the array's size. The level's
choice is therefore a consequential decision,
and the administrator should make it
deliberately, with the array's workload and its
growth's expectations in mind.
05 Worked example
The following example traces a RAID 5 array's read and write, computes the throughput and the capacity for a concrete configuration, and shows the rebuild's behaviour and its effect on the array's reliability.
A RAID 5 array's read and write
Consider a RAID 5 array with four disks (the N = 4), each 4 TB, and a stripe's size of 64 KB. The array's usable capacity is (N−1) × 4 TB = 12 TB, and the array presents itself as a single 12 TB block device.
The data's and the parity's placement is the stripe's rotation: for the stripe 0, the disks 0, 1, and 2 hold the data and the disk 3 holds the parity; for the stripe 1, the disks 0, 1, and 3 hold the data and the disk 2 holds the parity; and so on. The rotation distributes the parity's writes across the disks, so the parity's disk is not the bottleneck.
A large sequential read. An
application reads 256 KB from the array. The
array's stripe's size is 64 KB, so the read spans
four stripes. The array's controller (or the
kernel's md driver) splits the read
into the four stripes' requests, and the requests
are issued to the disks concurrently: the stripe
0's data is read from the disks 0, 1, and 2 (and
the disk 3's parity is not read, because
the read does not need it), the stripe 1's data
is read from the disks 0, 1, and 3, and so on. The
array's read throughput is the sum of the three
data disks' (about 3× a single disk's), and the
read's latency is the slowest disk's.
A small random write. An application writes 4 KB to the array. The write targets a single data block in a single stripe, and the array must update the corresponding parity block. The array uses the read-modify-write strategy:
- Read the old data. The array reads the 4 KB block from the target disk (the disk that holds the block), so the old data's value is known.
- Read the old parity. The array reads the stripe's parity block from the parity's disk.
- Compute the new parity. The array computes the new parity = the old parity XOR the old data XOR the new data. The computation is a few XOR operations, and it is fast.
- Write the new data and the new parity. The array writes the 4 KB block to the target disk and the new parity to the parity's disk. The two writes are issued concurrently.
The write requires two reads and two writes — four I/O operations for a single logical write. The array's write throughput for the small random writes is therefore about half a single disk's (the four operations' total throughput divided by the four operations' count), and the write's latency is the sum of the operations' latencies. The observation is the small-write problem's concrete cost.
A large sequential write. An application writes 256 KB to the array. The write spans four stripes, and it covers each stripe's data completely. The array uses the reconstruct-write strategy:
- Compute the new parity. The array computes the new parity = the new data's blocks XOR (the XOR of the stripe's other data blocks). Because the write covers the whole stripe, the other data blocks are the ones being written, so no reads are needed: the parity is computed from the write's data alone.
- Write the new data and the new parity. The array writes the four stripes' data and the four parities to the disks concurrently.
The write requires no reads, and its throughput is about the array's write throughput for the sequential writes (the sum of the data disks' throughputs minus the parity's overhead). The observation is the reason the RAID 5's sequential writes are fast and its random writes are slow: the strategy's choice depends on the write's size relative to the stripe's size.
The array's capacity and its cost
The array's usable capacity is 12 TB, and its raw capacity is 16 TB. The redundancy's cost is 4 TB (25% of the raw capacity), and the array's redundancy factor is 16/12 = 1.33. The comparison with the other levels for the same four disks is:
| Level | Usable capacity | Redundancy cost | Fault tolerance |
|---|---|---|---|
| RAID 0 | 16 TB | 0 TB (0%) | 0 failures |
| RAID 1 (2+2) | 8 TB | 8 TB (50%) | 1 failure per pair |
| RAID 5 | 12 TB | 4 TB (25%) | 1 failure |
| RAID 6 | 8 TB | 8 TB (50%) | 2 failures |
| RAID 10 | 8 TB | 8 TB (50%) | 1 failure per pair |
The table's pattern shows the RAID 5's capacity's advantage (the 25% cost, versus the 50% cost of the mirroring's designs) and its fault tolerance's limitation (the single failure, versus the RAID 6's two and the RAID 10's per-pair). The RAID 5's balance is the reason it is the most common level for the general-purpose storage, and its limitation is the reason the large arrays use the RAID 6 or the RAID 10.
The rebuild's duration and the second failure's risk
Suppose one of the array's disks fails. The array is degraded (the reads and the writes continue, but the performance is reduced and the array's fault tolerance is zero). The administrator replaces the failed disk, and the array begins the rebuild.
The rebuild reads the surviving disks' data and reconstructs the failed disk's data. For the RAID 5, the reconstruction reads the three surviving disks' data and parity, and it writes the reconstructed data to the replacement disk. The rebuild's I/O's total is the array's data's size (12 TB), and the rebuild's duration at the surviving disks' read throughput (say, 150 MB/s per disk, with the three disks' parallelism) is:
Rebuild time = 12 TB ÷ (3 disks × 150 MB/s)
= 12 × 10^12 ÷ (450 × 10^6) s
≈ 26,667 s
≈ 7.4 hours
The rebuild takes about 7.4 hours, and during that window the array has no fault tolerance: a second disk's failure would destroy the array's data. The probability of the second failure depends on the disks' failure rate:
Probability of a second failure in 7.4 hours
= (7.4 hours ÷ (24 × 365 hours/year)) × AFR
= (7.4 ÷ 8,760) × AFR
≈ 8.4 × 10⁻⁴ × AFR
With an AFR of 2% (0.02), the probability is about 1.7 × 10−5, or about 1 in 59,000. The probability seems small, but it is not negligible for a large data center with thousands of arrays, and it is the reason the RAID 5's use for the large arrays is discouraged. The RAID 6's two parities reduce the probability of the data loss to the probability of the third failure (the second failure during the rebuild is survivable, and the third is the data loss), which is far smaller. The observation is the RAID 6's justification, and it is the reason the large arrays use it.
The silent corruption's probability is a separate concern. A disk's full read of the 4 TB is 3.2 × 1013 bits, and with the bit error rate of 10−14, the expected number of the undetected errors is 0.32 per full read. The probability that a read encounters at least one undetected error is therefore about 1 − e−0.32 ≈ 27%. The probability is significant, and it is the reason the RAID 5's rebuild can fail even without a disk's failure: the rebuild reads the whole array, and if any read encounters an undetected error, the reconstructed data is wrong. The checksums' defence is essential: with the checksums, the silent corruption is detected, and the RAID 6's or the RAID 10's redundant copy allows the correction.
Inspecting a RAID array on a live system
The Linux tools let an administrator inspect a software RAID array's state, its members, and its rebuild's progress.
# Show the array's state
cat /proc/mdstat
# The output shows the array's level (raid5), its
# members (sda1, sdb1, sdc1, sdd1), its state
# ([UUUU] for all members up, [_UUU] for one member
# down), and its rebuild's progress (if any).
# Show the array's details
sudo mdadm --detail /dev/md0
# The output shows the array's level, its chunk size,
# its layout, its members, and its state.
# Show the array's members' SMART status
for disk in sda sdb sdc sdd; do
echo "=== /dev/$disk ==="
sudo smartctl -H /dev/$disk 2>/dev/null | tail -2
done
# Show the rebuild's progress
watch -n 5 cat /proc/mdstat
# The rebuild's progress is shown in the mdstat's output
# as the "recovery" or "resync" percentage.
The commands' outputs show the array's state and
its members' health. The /proc/mdstat
output is the array's live view: the array's level,
its members, and its state. The
mdadm --detail output is the array's
configuration: its chunk size, its layout, and its
members. The smartctl output is the
members' health: the disks' reallocated sectors,
their pending sectors, and their temperature. The
three together are the administrator's monitoring
tools, and their regular inspection is the
proactive maintenance's basis.
06 Interactive activity
Activity · explore RAID on a live system
The goal of this activity is to use the Linux command line to create a software RAID array, to inspect its state, to simulate a disk's failure, and to observe the rebuild. Work through the steps in your course VM. The activity uses the loop devices (the files that the kernel presents as block devices), so it does not require the additional disks.
-
Create the member devices.
Create four loop devices to use as the array's
members.
Did the loop devices set up correctly? How large is each? What would the array's usable capacity be for each RAID level?# Create the member files mkdir -p /tmp/raid-demo cd /tmp/raid-demo for i in 1 2 3 4; do dd if=/dev/zero of=disk$i.img bs=1M count=200 2>/dev/null done # Set up the loop devices sudo losetup -f 2>/dev/null for i in 1 2 3 4; do sudo losetup /dev/loop$i /tmp/raid-demo/disk$i.img done # Verify the loop devices lsblk | grep loop -
Create the RAID 5 array.
Use
mdadmto create a RAID 5 array from the four loop devices.
Did the array create successfully? What is the array's level, its members, and its state? How long did the initial resync take? Why does a RAID 5 array need an initial resync?# Create the RAID 5 array sudo mdadm --create /dev/md0 --level=5 --raid-devices=4 \ /dev/loop1 /dev/loop2 /dev/loop3 /dev/loop4 # Wait for the initial resync to complete watch -n 2 cat /proc/mdstat # (Wait until the resync's progress reaches 100%, # then press Ctrl-C.) -
Create a file system on the array and
test it.
Create an ext4 file system on the array, mount
it, and write some data.
Did the file system create successfully? Did the write work? What is the file's checksum? Write down the checksum for the later comparison.# Create the file system sudo mkfs.ext4 /dev/md0 # Mount it sudo mkdir -p /mnt/raid-test sudo mount /dev/md0 /mnt/raid-test # Write some data sudo dd if=/dev/urandom of=/mnt/raid-test/test.bin bs=1M count=50 2>/dev/null ls -lh /mnt/raid-test/test.bin # Compute the file's checksum md5sum /mnt/raid-test/test.bin -
Simulate a disk's failure.
Mark one of the array's members as failed, and
observe the array's degraded state.
Is the array degraded? Can the data still be read? Does the checksum match the previous one? What does the# Mark a member as failed sudo mdadm /dev/md0 --fail /dev/loop1 # Observe the array's state cat /proc/mdstat sudo mdadm --detail /dev/md0 # Verify the data is still accessible md5sum /mnt/raid-test/test.bin cat /mnt/raid-test/test.bin > /dev/null && echo "Read OK"[U_UU](or similar) state mean? Explain the degraded state's performance and reliability implications. -
Replace the failed member and rebuild.
Remove the failed member, add a new one, and
observe the rebuild.
Did the rebuild start automatically? How long did it take? What was the array's state during the rebuild? After the rebuild, is the array back to its healthy state?# Remove the failed member sudo mdadm /dev/md0 --remove /dev/loop1 # Create a new member and add it dd if=/dev/zero of=/tmp/raid-demo/disk1-new.img bs=1M count=200 2>/dev/null sudo losetup /dev/loop5 /tmp/raid-demo/disk1-new.img sudo mdadm /dev/md0 --add /dev/loop5 # Observe the rebuild's progress watch -n 2 cat /proc/mdstat # (Wait until the rebuild completes, then press Ctrl-C.) -
Verify the data after the rebuild.
Verify that the data survived the failure and
the rebuild.
Does the checksum match? What does the result tell you about the RAID 5's reconstruction's correctness? What would have happened if the second disk had failed during the rebuild?# Verify the data's checksum md5sum /mnt/raid-test/test.bin # Compare with the checksum recorded earlier. # They should match, because the data was # reconstructed correctly. # Show the array's final state cat /proc/mdstat sudo mdadm --detail /dev/md0 -
Compare the RAID levels' performance.
If you have time, create the arrays of the
different levels and compare their write
throughputs.
Which level's write throughput is highest? Which is lowest? Does the result match the lesson's performance analysis? Explain the difference in terms of the small-write problem.# (After cleaning up the previous array.) # Create a RAID 0 array and measure its write throughput sudo mdadm --create /dev/md1 --level=0 --raid-devices=4 \ /dev/loop1 /dev/loop2 /dev/loop3 /dev/loop4 sudo mkfs.ext4 /dev/md1 sudo mount /dev/md1 /mnt/raid-test time sudo dd if=/dev/zero of=/mnt/raid-test/write.bin bs=1M count=100 2>&1 | tail -1 # Repeat for the RAID 5, the RAID 6, and the RAID 10. # Compare the write throughputs. # Clean up sudo umount /mnt/raid-test sudo mdadm --stop /dev/md1 -
Read the man pages.
Read the man pages that document the RAID's
management.
For each, write a sentence describing its main contribution to your understanding of RAID. Theman 8 mdadm man 4 md man 7 md man 5 mdadm.conf man 8 lvm man 8 lvcreate man 8 pvcreate man 8 vgcreateman 8 mdadmpage documents the Linux software RAID's management tool; theman 7 mdpage documents the kernel's multiple-device driver; theman 8 lvcreatepage documents the LVM's RAID targets.
Reflect: RAID is one of the storage stack's foundational abstractions, and its design is a study in trade-offs. The RAID levels are the different balances between the performance, the capacity, and the reliability, and the balance's choice depends on the workload's characteristics and the system's requirements. The modern storage systems have moved beyond the classical RAID: the erasure coding, the copy-on-write, and the checksums' integration have made the systems more robust and more flexible. Which of the RAID's techniques matter most for the systems you use? What would you change about the RAID's design if you could? How would you explain the difference between the redundancy and the backup to someone who has never thought about it? What is the right balance between the classical RAID's simplicity and the modern systems' robustness?
07 Knowledge check
Check your understanding
Question 1
Define the reliability, the availability, and the redundancy. How do they relate, and why does the RAID improve all three?
Show answer
Question 2
Describe the three RAID techniques (striping, mirroring, and parity). What is each technique's purpose, and what are its advantages and its disadvantages?
Show answer
Question 3
Describe the RAID levels 0, 1, 5, 6, and 10. What is each level's technique, its usable capacity, its performance, and its fault tolerance?
Show answer
Question 4
Explain the small-write problem and the write hole. What are the techniques that address them?
Show answer
Question 5
Describe the RAID rebuild's vulnerabilities and the modern storage systems' responses. Why is the RAID 6 preferred for the large arrays?
Show answer
08 Unit discussion
Discussion prompt
RAID is one of the storage stack's foundational abstractions, and its history is a history of trade-offs. The original RAID paper (Patterson, Gibson, and Katz, 1988) proposed using the several cheap disks in place of one expensive one, and it defined the levels 1 through 5 as the different balances between the performance, the capacity, and the reliability. The levels were the 1980s' answers to the 1980s' constraints: the disks were expensive, the capacity was limited, and the failures were the dominant risk. The levels' designs assumed that the disks' failures were independent and that the rebuild's duration was short, and the levels' trade-offs were the straightforward arithmetic of the redundancy's cost versus its benefit.
The modern storage systems have moved beyond the classical RAID. The disks' capacities have grown (the multi-terabyte disks are common), so the rebuild's duration has grown (the days-long rebuilds are common), and the second failure's risk during the rebuild has become significant. The disks' error rates have not improved as fast as their capacities, so the silent corruption's probability during the rebuild has grown. The modern systems' responses — the RAID 6, the erasure coding, the checksums and the self-healing, the copy-on-write — are the recognition that the classical RAID's assumptions no longer hold, and the systems' designs are the new balances.
The trend is toward integration and end-to-end integrity. The classical RAID was a separate layer below the file system: the RAID controller presented a single device, and the file system was unaware of the array's structure. The modern systems (ZFS, Btrfs) integrate the RAID with the file system: the redundancy is part of the file system's metadata, the checksums detect the corruption, and the self-healing repairs it. The integration's advantages are the stronger integrity (the file system's checksums cover the data, not just the disk's blocks) and the more flexible redundancy (the erasure coding's arbitrary n and k, the per-file's redundancy policies). Its disadvantages are the complexity and the vendor lock-in (the integrated systems' formats are often incompatible).
Where should the redundancy live: in a separate RAID layer, in the file system, or in the application? Should the redundancy's mechanism be the RAID's parity, the erasure coding, or something else? What is the right balance between the classical RAID's simplicity and the modern systems' integrity? Post your response to the Unit 11 discussion forum and reply to at least two classmates. Supports CLO1, CLO5, and CLO7.
09 Practice exercise
This ungraded exercise consolidates the lesson and prepares you for Lesson 11.7. Aim to spend 60–90 minutes on it.
-
Compare the RAID levels.
A storage system has six 4 TB disks. Compute the
usable capacity, the redundancy cost, and the
fault tolerance for each of the following
configurations:
- RAID 0
- RAID 1 (three mirrored pairs)
- RAID 5
- RAID 6
- RAID 10 (three mirrored pairs, striped)
-
Trace a RAID 5 write.
A RAID 5 array has four disks and a stripe size
of 64 KB. An application writes 8 KB to a
logical block that maps to the disk 1, the
stripe 2. Trace the write's operations,
showing:
- The old data's read.
- The old parity's read.
- The new parity's computation.
- The new data's and the new parity's writes.
-
Compute the rebuild's probability.
A RAID 5 array has eight 8 TB disks. The rebuild
reads the seven surviving disks' data at an
aggregate 800 MB/s, and the disks' AFR is 1.5%.
Compute:
- The array's usable capacity.
- The rebuild's duration.
- The probability of a second disk's failure during the rebuild.
- The probability of the silent corruption during the rebuild (assume a bit error rate of 10−14).
-
Create and test a software RAID.
Use the loop devices and
mdadmto create a RAID 5 array, test its behaviour under a disk's failure, and observe the rebuild. (The interactive activity has the detailed steps.)
Record the array's state at each step. Did the data survive the failure? How long did the rebuild take? What would have happened if a second disk had failed during the rebuild?# Create the loop devices for i in 1 2 3 4; do dd if=/dev/zero of=/tmp/raid$i.img bs=1M count=200 2>/dev/null sudo losetup /dev/loop$i /tmp/raid$i.img done # Create the RAID 5 array sudo mdadm --create /dev/md0 --level=5 --raid-devices=4 \ /dev/loop1 /dev/loop2 /dev/loop3 /dev/loop4 # Wait for the resync, then create a file system and # write some data, then fail a disk and observe the # rebuild. cat /proc/mdstat -
Compare the RAID levels' throughput.
Using the loop devices, create a RAID 0, a
RAID 1, a RAID 5, and a RAID 10 array, and
measure each array's write throughput for a
large sequential write and a small random write.
Which level's large sequential write is fastest? Which level's small random write is fastest? Does the result match the lesson's performance analysis? Explain the difference in terms of the small-write problem.# For each level: sudo mdadm --create /dev/md0 --level=<level> \ --raid-devices=<n> /dev/loop* sudo mkfs.ext4 /dev/md0 sudo mount /dev/md0 /mnt/raid-test # Large sequential write time sudo dd if=/dev/zero of=/mnt/raid-test/seq.bin bs=1M count=100 2>&1 | tail -1 # Small random write sudo fio --name=randwrite --filename=/mnt/raid-test/rand.bin \ --size=50M --rw=randwrite --bs=4k --direct=1 \ --ioengine=libaio --iodepth=4 --runtime=5 2>/dev/null | grep -E 'IOPS|bw' # Clean up sudo umount /mnt/raid-test sudo mdadm --stop /dev/md0 -
Investigate the write-hole.
Research the RAID 5's write-hole and the modern
systems' solutions. Write a short paragraph
(200–250 words) explaining:
- What the write-hole is and why it occurs.
- The classical solutions (the battery-backed cache, the journal).
- The modern solution (the copy-on-write's approach).
- The Btrfs's and ZFS's implementations.
-
Design a storage configuration.
A company is building a storage server for its
engineering team. The server will hold 100 TB of
data, including the source code, the build
artifacts, the design documents, and the test
results. The data is critical (the company's
intellectual property) and the server's
availability matters (the team's productivity
depends on it). The server has 24 8 TB hard
disks and 4 1 TB NVMe SSDs. Design the storage
configuration:
- Which RAID levels would you use for the data's different classes (the source code, the build artifacts, the test results)?
- How would you use the SSDs (the cache, the metadata, the fast storage)?
- How would you configure the backups?
- How would you monitor the disks' health and the arrays' state?
- How would you handle the disks' failures?
- Reflect. In your own words, explain why the RAID is necessary and describe the three techniques and the main levels. Then describe one situation in your own experience — a system you have administered or a service you have used — where the RAID's design affected the system's reliability or its performance. What was the configuration, and how would a different design have changed the outcome?
10 Summary
- RAID (Redundant Array of Inexpensive/Independent Disks) combines several devices into one logical unit to improve the storage system's performance and its reliability. Its motivation is the storage system's failure and the user's need to survive it, and the three concepts — the reliability (the data's preservation), the availability (the system's ability to serve the requests), and the redundancy (the mechanism that provides both) — are the design's goals.
- The three RAID techniques are the striping (the data's division into the stripes and their distribution across the disks, for the parallelism), the mirroring (the data's storage on two or more disks, for the reliability), and the parity (the XOR of the stripe's data blocks, for the reliability with a smaller capacity cost). The RAID levels are the different combinations.
- The RAID levels are the RAID 0 (the striping alone: the performance without the redundancy), the RAID 1 (the mirroring: the reliability with the half capacity), the RAID 5 (the striping plus a single distributed parity: the balance of the performance, the capacity, and the reliability), the RAID 6 (the striping plus two parities: the double failure's tolerance), and the RAID 10 (the stripe of mirrors: the performance and the reliability with the half capacity). The historical levels (the RAID 2, the RAID 3, the RAID 4) are not used in practice.
- The small-write problem is the RAID 5's (and the RAID 6's) performance problem: a single data block's update requires the parity's update, and the parity's update requires the read-modify-write or the reconstruct-write. The write hole is the window during which the data and the parity are inconsistent, and a crash during the window can corrupt the array. The write-hole's solutions are the battery-backed write cache, the journal, and the copy-on-write.
-
The RAID can be implemented in hardware
(the dedicated controller, with the battery-backed
cache and the dedicated parity's computation) or
in software (the host's processor,
with the
mddriver, the LVM's RAID targets, the Btrfs's and ZFS's integrated RAID). The two implementations have different trade-offs, and the modern processors' performance has reduced the software RAID's overhead's significance. - The rebuild is the array's reconstruction of a failed disk's data. The rebuild's vulnerabilities are its duration (the long window during which the array has no fault tolerance), the second failure's risk, the silent data corruption's probability, and the rebuild's interference with the applications' I/O. The modern systems' responses are the RAID 6, the erasure coding, the RAID 10, the checksums and the self-healing, and the proactive maintenance.
- The solid-state drives change the RAID's design: the SSDs' sudden failures, the write amplification's significance, the faster rebuilds, and the TRIM's propagation. The SSD arrays often use the mirroring (the RAID 1, the RAID 10, the RAID-Z) rather than the parity, because the mirroring's writes are simpler and the amplification is smaller.
- The modern storage systems have moved beyond the classical RAID: the erasure coding (the n fragments with k data fragments) provides the stronger reliability at a smaller capacity cost, the copy-on-write avoids the write-hole, and the checksums' integration with the RAID provides the end-to-end integrity and the self-healing. The ZFS's and Btrfs's integrated RAID are the modern systems' most thorough implementations.
Looking ahead
This lesson presented RAID: the reliability, the availability, and the redundancy, the three techniques (the striping, the mirroring, and the parity), the RAID levels and their trade-offs, the small-write problem and the write hole, the hardware and software implementations, the rebuild's vulnerabilities and the modern systems' responses, and the RAID's interaction with the solid-state drives. It referred several times to the solid-state drives' characteristics — the flash memory's organization, the flash translation layer, the wear leveling, the garbage collection, and the internal parallelism — and to their effect on the storage stack's design. Lesson 11.7 presents the SSD architecture in detail: the flash memory's physics, the NAND and the NOR technologies, the pages and the erase blocks, the flash translation layer, the wear leveling, the garbage collection, the write amplification, the TRIM command, and the SSD's internal parallelism. The lesson completes Unit 11's view of the storage stack, and it is the foundation for the flash-specific file systems (Lesson 10.7's F2FS) and the modern storage systems' designs.
11 References
- Silberschatz, A., Galvin, P. B., & Gagne, G. Operating System Concepts, 10th ed., Chapter 11, Section 11.8.
-
Arpaci-Dusseau, R. H., & Arpaci-Dusseau, A. C.
Operating Systems: Three Easy Pieces, Chapter 38,
Redundant Arrays of Inexpensive Disks
(RAIDs). Available online at
ostep.org. - Tanenbaum, A. S., & Bos, H. Modern Operating Systems, 4th ed., Chapter 5, Section 5.4.3.
- Patterson, D. A., Gibson, G., & Katz, R. H. A Case for Redundant Arrays of Inexpensive Disks (RAID). ACM SIGMOD Conference, 1988.
- Chen, P. M., Lee, E. K., Gibson, G. A., Katz, R. H., & Patterson, D. A. RAID: High-Performance, Reliable Secondary Storage. ACM Computing Surveys, 1994.
- Rodeh, O., Bacik, J., & Mason, C. BTRFS: The Linux B-Tree Filesystem. ACM Transactions on Storage, 2013.
- Bonwick, J., & Moore, B. ZFS: The Last Word in File Systems. Sun Microsystems, 2007.
-
Linux man-pages:
man 8 mdadm,man 4 md,man 7 md,man 5 mdadm.conf,man 8 lvm,man 8 pvcreate,man 8 vgcreate,man 8 lvcreate,man 8 mkfs.ext4,man 8 mkfs.xfs,man 8 mkfs.btrfs,man 8 smartctl,man 1 lsblk.