Chapter 38: Interface And RAID Internals
This page is a generated reference surface for selective reading. It exists to keep the learner apps guide-first while still preserving source access.
Learning objectives
- Explain the main ideas and vocabulary in Interface And RAID Internals.
- Work through the source examples for Interface And RAID Internals without depending on raw chunk order.
- Use Interface And RAID Internals as selective reference when learner modules point back to Ostep.
Prerequisites
- Earlier prerequisite concepts leading into Chapter 38: Interface And RAID Internals.
Module targets
module-04-file-systems-io
AI companion modes
- Explain simply
- Socratic tutor
- Quiz me
- Challenge my understanding
- Diagnose my confusion
- Generate extra practice
- Revision mode
- Connect forward / backward
Source-of-truth note
This unit is anchored to Ostep and the source chapter "Chapter 38: Interface And RAID Internals". Use external resources only to clarify, extend, or modernize details without replacing the chapter's conceptual spine.
External enrichment
No chapter-specific enrichment resources are curated yet. Add them in the unit manifest when a source clearly improves learning.
Source provenance
- Primary source:
Ostep - Source chapter 38: Chapter 38: Interface And RAID Internals
- Raw source file:
177-38-1-interface-and-raid-internals.md - Raw source file:
179-38-5-raid-level-1-mirroring.md - Raw source file:
182-38-6-raid-level-4-saving-space-with-parity.md - Raw source file:
184-38-7-raid-level-5-rotating-parity.md
Merged source
Interface And RAID Internals
38.1 Interface And RAID Internals
38 Redundant Arrays of Inexpensive Disks
(RAIDs)
When we use a disk, we sometimes wish it to be faster; I/O operations are slow and thus can be the bottleneck for the entire system. When we use a disk, we sometimes wish it to be larger; more and more data is being put online and thus our disks are getting fuller and fuller. When we use a disk, we sometimes wish for it to be more reliable; when a disk fails, if our data isn't backed up, all that valuable data is gone.
CRUX: HOWTOMAKEA LARGE, FAST, RELIABLEDISK
How can we make a large, fast, and reliable storage system? What are the key techniques? What are trade-offs between different approaches?
In this chapter, we introduce the Redundant Array of Inexpensive
Disksbetter known asRAID[P+88], a technique to use multiple disks in concert to build a faster, bigger, and more reliable disk system. The term was introduced in the late 1980s by a group of researchers at U.C. Berkeley (led by Professors David Patterson and Randy Katz and then student
Garth Gibson); it was around this time that many different researchers simultaneously arrived upon the basic idea of using multiple disks to build a better storage system [BG88, K86,K88,PB86,SG86].
Externally, a RAID looks like a disk: a group of blocks one can read or write. Internally, the RAID is a complex beast, consisting of multiple disks, memory (both volatile and non-), and one or more processors to manage the system. A hardware RAID is very much like a computer system, specialized for the task of managing a group of disks.
RAIDs offer a number of advantages over a single disk. One advantage is performance. Using multiple disks in parallel can greatly speed up I/O times. Another benefit iscapacity. Large data sets demand large disks. Finally, RAIDs can improvereliability; spreading data across multiple disks (without RAID techniques) makes the data vulnerable to the loss of a single disk; with some form ofredundancy, RAIDs can tolerate the loss of a disk and keep operating as if nothing were wrong.
1
TIP: TRANSPARENCYENABLESDEPLOYMENT
When considering how to add new functionality to a system, one should always consider whether such functionality can be addedtransparently, in a way that demands no changes to the rest of the system. Requiring a complete rewrite of the existing software (or radical hardware changes) lessens the chance of impact of an idea. RAID is a perfect example, and certainly its transparency contributed to its success; administrators could install a SCSI-based RAID storage array instead of a SCSI disk, and the rest of the system (host computer, OS, etc.) did not have to change one bit to start using it. By solving this problem ofdeployment, RAID was made more successful from day one.
Amazingly, RAIDs provide these advantagestransparentlyto systems that use them, i.e., a RAID just looks like a big disk to the host system. The beauty of transparency, of course, is that it enables one to simply replace a disk with a RAID and not change a single line of software; the operating system and client applications continue to operate without modification. In this manner, transparency greatly improves thedeployabilityof
RAID, enabling users and administrators to put a RAID to use without worries of software compatibility.
We now discuss some of the important aspects of RAIDs. We begin with the interface, fault model, and then discuss how one can evaluate a
RAID design along three important axes: capacity, reliability, and performance. We then discuss a number of other issues that are important to
RAID design and implementation.
To a file system above, a RAID looks like a big, (hopefully) fast, and (hopefully) reliable disk. Just as with a single disk, it presents itself as a linear array of blocks, each of which can be read or written by the file system (or other client).
When a file system issues alogical I/Orequest to the RAID, the RAID internally must calculate which disk (or disks) to access in order to complete the request, and then issue one or morephysical I/Osto do so. The exact nature of these physical I/Os depends on the RAID level, as we will discuss in detail below. However, as a simple example, consider a RAID that keeps two copies of each block (each one on a separate disk); when writing to such amirroredRAID system, the RAID will have to perform two physical I/Os for every one logical I/O it is issued.
A RAID system is often built as a separate hardware box, with a standard connection (e.g., SCSI, or SATA) to a host. Internally, however,
RAIDs are fairly complex, consisting of a microcontroller that runs firmware to direct the operation of the RAID, volatile memory such as DRAM to buffer data blocks as they are read and written, and in some cases, non-volatile memory to buffer writes safely and perhaps even specialized logic to perform parity calculations (useful in some RAID levels, as we will also see below). At a high level, a RAID is very much a specialized computer system: it has a processor, memory, and disks; however, instead of running applications, it runs specialized software designed to operate the RAID.
38.2 Fault Model
To understand RAID and compare different approaches, we must have a fault model in mind. RAIDs are designed to detect and recover from certain kinds of disk faults; thus, knowing exactly which faults to expect is critical in arriving upon a working design.
The first fault model we will assume is quite simple, and has been called the fail-stop fault model [S84]. In this model, a disk can be in exactly one of two states: working or failed. With a working disk, all blocks can be read or written. In contrast, when a disk has failed, we assume it is permanently lost.
One critical aspect of the fail-stop model is what it assumes about fault detection. Specifically, when a disk has failed, we assume that this is easily detected. For example, in a RAID array, we would assume that the
RAID controller hardware (or software) can immediately observe when a disk has failed.
Thus, for now, we do not have to worry about more complex "silent" failures such as disk corruption. We also do not have to worry about a single block becoming inaccessible upon an otherwise working disk (sometimes called a latent sector error). We will consider these more complex (and unfortunately, more realistic) disk faults later.
38.3 How To Evaluate A RAID
As we will soon see, there are a number of different approaches to building a RAID. Each of these approaches has different characteristics which are worth evaluating, in order to understand their strengths and weaknesses.
Specifically, we will evaluate each RAID design along three axes. The first axis iscapacity; given a set ofNdisks each withBblocks, how much useful capacity is available to clients of the RAID? Without redundancy, the answer isN·B; in contrast, if we have a system that keeps two copies of each block (calledmirroring), we obtain a useful capacity of(N· B)/2.
Different schemes (e.g., parity-based ones) tend to fall in between.
The second axis of evaluation isreliability. How many disk faults can the given design tolerate? In alignment with our fault model, we assume only that an entire disk can fail; in later chapters (i.e., on data integrity), we'll think about how to handle more complex failure modes.
Finally, the third axis isperformance. Performance is somewhat challenging to evaluate, because it depends heavily on the workload presented to the disk array. Thus, before evaluating performance, we will first present a set of typical workloads that one should consider.
We now consider three important RAID designs: RAID Level 0 (striping), RAID Level 1 (mirroring), and RAID Levels 4/5 (parity-based redundancy). The naming of each of these designs as a "level" stems from the pioneering work of Patterson, Gibson, and Katz at Berkeley [P+88].
38.4 RAID Level 0: Striping
The first RAID level is actually not a RAID level at all, in that there is no redundancy. However, RAID level 0, orstripingas it is better known, serves as an excellent upper-bound on performance and capacity and thus is worth understanding.
The simplest form of striping willstripeblocks across the disks of the system as follows (assume here a 4-disk array):
Disk 0 Disk 1 Disk 2 Disk 3 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Figure 38.1:RAID-0: Simple Striping
From Figure 38.1, you get the basic idea: spread the blocks of the array across the disks in a round-robin fashion. This approach is designed to extract the most parallelism from the array when requests are made for contiguous chunks of the array (as in a large, sequential read, for example). We call the blocks in the same row astripe; thus, blocks 0, 1, 2, and 3 are in the same stripe above.
In the example, we have made the simplifying assumption that only 1 block (each of say size 4KB) is placed on each disk before moving on to the next. However, this arrangement need not be the case. For example, we could arrange the blocks across disks as in Figure 38.2:
Disk 0 Disk 1 Disk 2 Disk 3 0 2 4 6 chunk size:
1 3 5 7 2 blocks 8 10 12 14 9 11 13 15
Figure 38.2:Striping with a Bigger Chunk Size
In this example, we place two 4KB blocks on each disk before moving on to the next disk. Thus, thechunk sizeof this RAID array is 8KB, and a stripe thus consists of 4 chunks or 32KB of data.
RAID Level 1 Mirroring
38.5 RAID Level 1: Mirroring
Back To RAID-0 Analysis
Let us now evaluate the capacity, reliability, and performance of striping.
From the perspective of capacity, it is perfect: givenNdisks each of size
Bblocks, striping deliversN·Bblocks of useful capacity. From the standpoint of reliability, striping is also perfect, but in the bad way: any disk failure will lead to data loss. Finally, performance is excellent: all disks are utilized, often in parallel, to service user I/O requests.
Evaluating RAID Performance
In analyzing RAID performance, one can consider two different performance metrics. The first issingle-request latency. Understanding the latency of a single I/O request to a RAID is useful as it reveals how much parallelism can exist during a single logical I/O operation. The second is steady-state throughput of the RAID, i.e., the total bandwidth of many concurrent requests. Because RAIDs are often used in high-performance environments, the steady-state bandwidth is critical, and thus will be the main focus of our analyses.
To understand throughput in more detail, we need to put forth some workloads of interest. We will assume, for this discussion, that there are two types of workloads: sequentialandrandom. With a sequential workload, we assume that requests to the array come in large contiguous chunks; for example, a request (or series of requests) that accesses 1 MB of data, starting at blockxand ending at block(x+1 MB), would be deemed sequential. Sequential workloads are common in many environments (think of searching through a large file for a keyword), and thus are considered important.
For random workloads, we assume that each request is rather small, and that each request is to a different random location on disk. For example, a random stream of requests may first access 4KB at logical address 10, then at logical address 550,000, then at 20,100, and so forth. Some important workloads, such as transactional workloads on a database management system (DBMS), exhibit this type of access pattern, and thus it is considered an important workload.
Of course, real workloads are not so simple, and often have a mix of sequential and random-seeming components as well as behaviors inbetween the two. For simplicity, we just consider these two possibilities.
As you can tell, sequential and random workloads will result in widely different performance characteristics from a disk. With sequential access, a disk operates in its most efficient mode, spending little time seeking and waiting for rotation and most of its time transferring data. With random access, just the opposite is true: most time is spent seeking and waiting for rotation and relatively little time is spent transferring data. To capture this difference in our analysis, we will assume that a disk can transfer data atSMB/s under a sequential workload, andRMB/s when under a random workload. In general,Sis much greater thanR(i.e., S≫R).
To make sure we understand this difference, let's do a simple exercise.
Specifically, let's calculateSandRgiven the following disk characteristics. Assume a sequential transfer of size 10 MB on average, and a random transfer of 10 KB on average. Also, assume the following disk characteristics:
Average seek time 7 ms
Average rotational delay 3 ms
Transfer rate of disk 50 MB/s
To computeS, we need to first figure out how time is spent in a typical 10 MB transfer. First, we spend 7 ms seeking, and then 3 ms rotating.
Finally, transfer begins; 10 MB @ 50 MB/s leads to 1/5th of a second, or 200 ms, spent in transfer. Thus, for each 10 MB request, we spend 210 ms completing the request. To computeS, we just need to divide:
S=Amount of Data =10M B = 47.62M B/s
T ime to access 210ms
As we can see, because of the large time spent transferring data,Sis very near the peak bandwidth of the disk (the seek and rotational costs have been amortized).
We can computeRsimilarly. Seek and rotation are the same; we then compute the time spent in transfer, which is 10 KB @ 50 MB/s, or 0.195 ms.
R=Amount of Data = 10KB = 0.981M B/s
T ime to access 10.195ms
As we can see,Ris less than 1 MB/s, andS/Ris almost 50.
Back To RAID-0 Analysis, Again
Let's now evaluate the performance of striping. As we said above, it is generally good. From a latency perspective, for example, the latency of a single-block request should be just about identical to that of a single disk; after all, RAID-0 will simply redirect that request to one of its disks.
From the perspective of steady-state throughput, we'd expect to get the full bandwidth of the system. Thus, throughput equalsN(the number of disks) multiplied byS(the sequential bandwidth of a single disk).
For a large number of random I/Os, we can again use all of the disks, and thus obtainN· RMB/s. As we will see below, these values are both the simplest to calculate and will serve as an upper bound in comparison with other RAID levels.
Our first RAID level beyond striping is known as RAID level 1, or mirroring. With a mirrored system, we simply make more than one copy of each block in the system; each copy should be placed on a separate disk, of course. By doing so, we can tolerate disk failures.
In a typical mirrored system, we will assume that for each logical block, the RAID keeps two physical copies of it. Here is an example:
Disk 0 Disk 1 Disk 2 Disk 3 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7
RAID Level 4 Saving Space With Parity
38.6 RAID Level 4: Saving Space With Parity
We now present a different method of adding redundancy to a disk array known asparity. Parity-based approaches attempt to use less capacity and thus overcome the huge space penalty paid by mirrored systems.
They do so at a cost, however: performance.
Disk 0 Disk 1 Disk 2 Disk 3 Disk 4 0 1 2 3 P0 4 5 6 7 P1 8 9 10 11 P2 12 13 14 15 P3
Figure 38.4:RAID-4 with Parity
Here is an example five-disk RAID-4 system (Figure 38.4). For each stripe of data, we have added a singleparityblock that stores the redundant information for that stripe of blocks. For example, parity block P1 has redundant information that it calculated from blocks 4, 5, 6, and 7.
To compute parity, we need to use a mathematical function that enables us to withstand the loss of any one block from our stripe. It turns out the simple functionXORdoes the trick quite nicely. For a given set of bits, the XOR of all of those bits returns a 0 if there are an even number of 1's in the bits, and a 1 if there are an odd number of 1's. For example:
C0 C1 C2 C3 P
0 0 1 1 XOR(0,0,1,1) = 0
0 1 0 0 XOR(0,1,0,0) = 1
In the first row (0,0,1,1), there are two 1's (C2, C3), and thus XOR of all of those values will be 0 (P); similarly, in the second row there is only one 1 (C1), and thus the XOR must be 1 (P). You can remember this in a simple way: that the number of 1s in any row must be an even (not odd) number; that is theinvariantthat the RAID must maintain in order for parity to be correct.
From the example above, you might also be able to guess how parity information can be used to recover from a failure. Imagine the column labeled C2 is lost. To figure out what values must have been in the column, we simply have to read in all the other values in that row (including the
XOR'd parity bit) andreconstructthe right answer. Specifically, assume the first row's value in column C2 is lost (it is a 1); by reading the other values in that row (0 from C0, 0 from C1, 1 from C3, and 0 from the parity column P), we get the values 0, 0, 1, and 0. Because we know that XOR keeps an even number of 1's in each row, we know what the missing data must be: a 1. And that is how reconstruction works in a XOR-based parity scheme! Note also how we compute the reconstructed value: we just
XOR the data bits and the parity bits together, in the same way that we calculated the parity in the first place.
Now you might be wondering: we are talking about XORing all of these bits, and yet from above we know that the RAID places 4KB (or larger) blocks on each disk; how do we apply XOR to a bunch of blocks to compute the parity? It turns out this is easy as well. Simply perform a bitwise XOR across each bit of the data blocks; put the result of each bitwise XOR into the corresponding bit slot in the parity block. For example, if we had blocks of size 4 bits (yes, this is still quite a bit smaller than a 4KB block, but you get the picture), they might look something like this:
Block0 Block1 Block2 Block3 Parity 00 10 11 10 11 10 01 00 01 10
As you can see from the figure, the parity is computed for each bit of each block and the result placed in the parity block.
RAID-4 Analysis
Let us now analyze RAID-4. From a capacity standpoint, RAID-4 uses 1 disk for parity information for every group of disks it is protecting. Thus, our useful capacity for a RAID group is(N-1)· B.
Reliability is also quite easy to understand: RAID-4 tolerates 1 disk failure and no more. If more than one disk is lost, there is simply no way to reconstruct the lost data.
Finally, there is performance. This time, let us start by analyzing steadystate throughput. Sequential read performance can utilize all of the disks except for the parity disk, and thus deliver a peak effective bandwidth of (N-1)· SMB/s (an easy case).
Disk 0 Disk 1 Disk 2 Disk 3 Disk 0 1 2 3 P0 4 5 6 7 P1 8 9 10 11 P2 12 13 14 15 P3
RAID Level 5 Rotating Parity
38.7 RAID Level 5: Rotating Parity
To address the small-write problem (at least, partially), Patterson, Gibson, and Katz introduced RAID-5. RAID-5 works almost identically to
RAID-4, except that itrotatesthe parity block across drives (Figure 38.7).
Disk 0 Disk 1 Disk 2 Disk 3 Disk 4 0 1 2 3 P0 5 6 7 P1 4 10 11 P2 8 9 15 P3 12 13 14
P4 16 17 18 19
Figure 38.7:RAID-5 With Rotated Parity
As you can see, the parity block for each stripe is now rotated across the disks, in order to remove the parity-disk bottleneck for RAID-4.
RAID-5 Analysis
Much of the analysis for RAID-5 is identical to RAID-4. For example, the effective capacity and failure tolerance of the two levels are identical. So are sequential read and write performance. The latency of a single request (whether a read or a write) is also the same as RAID-4.
Random read performance is a little better, because we can now utilize all disks. Finally, random write performance improves noticeably over
RAID-4, as it allows for parallelism across requests. Imagine a write to block 1 and a write to block 10; this will turn into requests to disk 1 and disk 4 (for block 1 and its parity) and requests to disk 0 and disk 2 (for block 10 and its parity). Thus, they can proceed in parallel. In fact, we can generally assume that given a large number of random requests, we will be able to keep all the disks about evenly busy. If that is the case, then our total bandwidth for small writes will be N·RMB/s. The factor 4 of four loss is due to the fact that each RAID-5 write still generates 4 total
I/O operations, which is simply the cost of using parity-based RAID.
Capacity N·B (N·B)/2 (N-1)·B (N-1)·B
Reliability 0 1(for sure) 1
N(if lucky) 2
Throughput
Sequential Read N·S (N/2)·S (N-1)·S (N-1)·S
Sequential Write N·S (N/2)·S (N-1)·S (N-1)·S
Random Read N·R N·R (N-1)·R N·R
Random Write N·R (N/2)·R 1 ·R NR 2 4
Latency
Read T T T T
Write T T 2T 2T
Figure 38.8:RAID Capacity, Reliability, and Performance
Because RAID-5 is basically identical to RAID-4 except in the few cases where it is better, it has almost completely replaced RAID-4 in the marketplace. The only place where it has not is in systems that know they will never perform anything other than a large write, thus avoiding the smallwrite problem altogether [HLM94]; in those cases, RAID-4 is sometimes used as it is slightly simpler to build.
38.8 RAID Comparison: A Summary
We now summarize our simplified comparison of RAID levels in Figure 38.8. Note that we have omitted a number of details to simplify our analysis. For example, when writing in a mirrored system, the average seek time is a little higher than when writing to just a single disk, because the seek time is the max of two seeks (one on each disk). Thus, random write performance to two disks will generally be a little less than random write performance of a single disk. Also, when updating the parity disk in RAID-4/5, the first read of the old parity will likely cause a full seek and rotation, but the second write of the parity will only result in rotation.
However, the comparison in Figure 38.8 does capture the essential differences, and is useful for understanding tradeoffs across RAID levels.
For the latency analysis, we simply use T to represent the time that a request to a single disk would take.
To conclude, if you strictly want performance and do not care about reliability, striping is obviously best. If, however, you want random I/O performance and reliability, mirroring is the best; the cost you pay is in lost capacity. If capacity and reliability are your main goals, then RAID- 5 is the winner; the cost you pay is in small-write performance. Finally, if you are always doing sequential I/O and want to maximize capacity,
RAID-5 also makes the most sense.
38.9 Other Interesting RAID Issues
There are a number of other interesting ideas that one could (and perhaps should) discuss when thinking about RAID. Here are some things we might eventually write about.
For example, there are many other RAID designs, including Levels 2 and 3 from the original taxonomy, and Level 6 to tolerate multiple disk faults [C+04]. There is also what the RAID does when a disk fails; sometimes it has ahot sparesitting around to fill in for the failed disk. What happens to performance under failure, and performance during reconstruction of the failed disk? There are also more realistic fault models, to take into accountlatent sector errorsorblock corruption[B+08], and lots of techniques to handle such faults (see the data integrity chapter for details). Finally, you can even build RAID as a software layer: suchsoftware RAIDsystems are cheaper but have other problems, including the consistent-update problem [DAA05].