磁盘驱动器继续变得更小更便宜,如今在一台计算机系统上连接许多磁盘从经济上来说已经可行了。一个系统拥有大量磁盘,就有机会改善数据的读写速率,因为磁盘操作可以并行进行。此外,这种设置提供能力,以提高数据存储的可靠性,因为冗佘信息可以存储在多 个磁盘上。因此,单个磁盘的故障不会导致数据丢失。
多种磁盘组织技术统称为磁盘冗余阵列(RAID)技术,通常用于处理性能与可靠性问题。过去,RAID 是由小且便宜的磁盘组成,可作为大且昂贵的磁盘的有效替代品。现在,RAID 的使用主要是因为高可靠性和高数据传输率,而不是经济原因。因此,RAID 中的 I 表示“独立”(independent)而不是“廉价”(inexpensive)。
首先分析 RAID 的可靠性。N 个磁盘内的某个磁盘故障的机会远远高于单个特定磁盘故障的机会。假设单个磁盘的平均故障时间为 100 000 小时,那么 100 个磁盘中的某个磁盘的平均故障时间为 100 000/100 = 1000 小时或 41.66 天,这并不长!如果只存储数据的一个副本,则每个磁盘故障会导致丢失大量数据,这样高的数据丢失率是不可接受的。
可靠性问题的解决是引入冗余。存储额外信息,这是平常不需要的,但是在磁盘故障时可以用于重建丢失的信息。因此,即使磁盘故障,数据也不会丢失。
最为简单(但最昂贵)的引入冗余的方法是,重复每个磁盘。这种技术称为镜像。由于镜像,每个逻辑磁盘由两个物理磁盘组成,并且每次写入都在两个磁盘上进行。这称为镜像卷。如果卷中的某个磁盘故障,则可以从另一卷中读取。只有在第一个损坏磁盘没有替换之前第二个磁盘又出错,才会丢失数据。
镜像卷的平均故障时间(这里的故障是数据丢失)取决于两个因素。一个是,单个磁盘的平均故障时间。另一个是平均维修时间,这是用于替换损坏磁盘并恢复其上数据的平均时间。假设两个磁盘的故障是独立的;即一个磁盘故障与另一个磁盘故障没有关联。那么,如果单个磁盘的平均故障时间为 100 000 小时,并且平均修补时间为 10 小时,则镜像磁盘系统的平均数据丢失时间为 100 0 002/(2X10)= 500X106 小时或 57 000 年。
需要注意,磁盘故障的独立性假设并不真正成立。电源故障和自然灾害,如地震、火灾、水灾,可能导致同时损坏两个磁盘。另外,成批生产磁盘的制造缺陷可以导致相关故障。随着磁盘老化,故障概率增加,从而增加了在替代第一磁盘时第二个磁盘故障的概率。然而,尽管所有这些考虑,镜像磁盘系统仍比单个磁盘系统提供更高的可靠性。
电源故障是一个特别的关注点,因为它们比自然灾害更为常见。即使使用磁盘镜像,如果对两个磁盘写入同样的块,而在两块完全写入之前电源故障,则这两块可能处于不一致的状态。
这个问题的一种解决方法是,先写一个副本,再写下一个。另一个是,为 RAID 阵列添加固态非易失性 RAM 的缓存。这种写回高速缓存在电源故障时会得到保护。这样,假设 NVRAM 有某种错误避免和纠错功能,如 ECC 和镜像,写入可以认为在这一阶段已完成。
现在分析多个磁盘的并行访问如何改善性能。通过磁盘镜像,读请求的处理速度可以加倍,因为读请求可以送到任一磁盘(只要成对的两个磁盘都能工作,情况几乎总是这样的)。例如,每次读取的传输速率是与单个磁盘系统相同,但是每单位时间的读取次数翻了一番。
采用多个磁盘,通过将数据分散在多个磁盘上,也可以改善传输率。最简单形式是,数据分条包括将每个字节分散在多个磁盘上,这种分条称为位级分条。
例如,如果有 8 个磁盘,则可以将每个字节的位i写到磁盘 i 上。这 8 个磁盘可作为单个磁盘使用,其扇区为正常扇区的 8 倍,更为重要的是它具有 8 倍的访问率。每个磁盘参与每个访问(读或写);这样每秒所能处理的访问数量与单个磁盘的一样,但是每次访问的数据在同样时间内为单个磁盘系统的8倍。
位级分条可以推广到其他磁盘数量,它或者是 8 的倍数或者除以 8。例如,如果采用 4 个磁盘阵列,则每个字节的位 i 和位 4+i 可存在磁盘 i 上。此外,分条不必按位级来进行。
例如,对于块级分条,文件的块可以分散在多个磁盘上;对于 n 个磁盘,文件的块 i 可存在磁盘 (i mod n)+ 1 上。其他分条级别,如单个扇区或单块扇区的字节,也是可能的。块级分条是最常见的。
磁盘系统的并行化,通过分条实现,有两个主要目标:
镜像提供高可靠性,但是昂贵。分条提供高数据传输率,但并未改善可靠性。通过磁盘分条和“奇偶”位(下面将要讨论),在低代价下提供冗余可以有多种方案。这些方案有不同的性价折中,并分成不同的级别,称为RAID级别。这里讨论各种级别,图 1 显示了它们(图中,P 表示纠错位,而 C 表示数据的第二副本)。
对于图中所示的各种情况,4 个磁盘用于存储数据,额外磁盘用于存储冗余信息以便故障恢复。
RAID 级别 0 为具有块分条但没有冗余(如镜像或奇偶位)的磁盘阵列,如图 1a) 所示。
RAID 级别 1 指磁盘镜像。 图 1b) 显示了这种镜像组织。
RAID 级别 2 也称为内存方式的差错纠正(ECC)组织。内存系统长期以来实现了基于奇偶位的错误检测。内存系统内的每个字节都有一个关联的奇偶位,以记录字节中为 1 的个数是偶数(parity = 0)或是奇数(parity = 1)。
如果字节的 1 个位发生了损坏(或是 1 变成 0 或是 0 变成 1),则字节的奇偶校验位改变,因此与所存储的奇偶校验位就不匹配。类似地,如果存储的奇偶校验位损坏了,则它不匹配计算的奇偶校验位。因此,单个位差错可为内存系统所检测。差错纠正方案存储两个或多个额外位,并且当单个位出错时可以重建数据。
ECC 方法通过将字节分散在磁盘上,可以直接用于磁盘阵列。例如,每个字节的第 1 位可以存在磁盘 1 上,第 2 位在磁盘 2 上,等等,直到第 8 位存在磁盘 8 上;而纠错位存在其他磁盘上。这个方案如图 1c) 所示,其中标记为 P 的磁盘存储了差错纠正位。
如果有一个磁盘故障了,则可从其他磁盘中读取字节的其余位和相关差错纠正位,以重构损坏的数据。请注意,对于 4 个磁盘的数据,RAID 级别 2 只用了 3 个额外磁盘,而 RAID 级别 1 则需要 4 个额外磁盘。
RAID 级别 3 或位交错奇偶校验结构,改进了级别 2。它考虑了如下事实:与内存系统不同,磁盘控制器能够检测到一个扇区是否正确读取,这样单个奇偶位可以用于差错检测和差错纠正。
方案如下:如果一个扇区损坏了,则我们就知道它是哪个扇区;而且通过计算其他磁盘扇区的相应位的奇偶值,可以得出损坏的位是 1 还是 0。如果剩余位的奇偶校验等于存储奇偶值,则丢失位为 0;否则,为 1。
RAID 级别 3 与级别 2 一样好,但是在额外磁盘的数量方面要更便宜(它只有一个额外磁盘),因此级别 2 在实际中并不使用。级别 3 如图 1d) 所示。
与 RAID 级别 1 相比,RAID 级别 3 有两个优点:
RAID 级别 3 的(其他奇偶检验的 RAID 级别也有的)另一性能问题是,需要计算和写入奇偶校验位。与非奇偶检验位 RAID 阵列相比,这种开销导致写入更慢。
为了减轻这种性能损失,许多 RAID 存储阵列的控制器带有专门计算奇偶校验位的硬件。这种控制器将奇偶校验位计算从 CPU 转移到阵列。这种阵列还有 NVRAM 缓存,以便在计算奇偶校验位时存储块,并且缓存从控制器到磁盘的写入。这种组合使得奇偶校验 RAID 几乎与非奇偶校验的一样快。事实上,做奇偶校验的带有缓存的 RAID 可以胜过非缓存非奇偶校验的 RAID。
RAID 级别 4 或块交错奇偶校验结构采用块级分条,这与 RAID 0 一样,此外在一个单独的磁盘上保存其他 N 个磁盘的块的奇偶校验块。这种方案如图 1e) 所示。如果有一个磁盘故障,则通过奇偶校验块和其他磁盘的相应块恢复故障磁盘的块。
每个块的读只访问一个磁盘,可以允许其他磁盘处理其他请求。因此,虽然每个访问的数据传输速率更慢,但是多个读访问可以并行处理,导致了更高的总体 I/O 速率。大的读取传输速率很高,因为可以并行读取所有磁盘。大的写入也有很高传输速率,因为可以并行写入数据和奇偶校验。
小的独立写入不能平行执行。操作系统写入的数据小于一块要求,读取块,修改新数据,并写回。奇偶校验块也必须更新。这称为读-改-写周期。因此,单个写需要 4 次磁盘访问:两次读入两个旧块,两次写入两个新块。
RAID 级别 5 或块交错分布奇偶校验结构,不同于级别 4,它将数据和奇偶校验分散在所有 N+1 个磁盘上,而不是将数据存在 N 个磁盘上并且奇偶校验存在单个磁盘上。
对于每块,一个磁盘存储奇偶校验,而其他的存储数据。例如,对于 5 个磁盘的阵列,第 n 块的奇偶校验保存在磁盘 (n mod 5) + 1 上;其他 4 个磁盘的第 n 块保存该奇偶块对应的真正数据。这种方案如图 1f) 所示,其中 P 分布在所有磁盘上。奇偶校验块不能保存同一磁盘的块的奇偶校验,因为磁盘故障会导致数据及奇偶校验的丢失,因此无法恢复损失。
通过将奇偶校验分布在所有磁盘上,RAID 5 避免了 RAID 4 方案的对单个奇偶校验磁盘的潜在过度使用。RAID 5 是最常见的奇偶校验 RAID 系统。
RAID 级别 6,也称为 P+Q 冗余方案,与 RAID 级别 5 非常类似,但是保存了额外冗余信息以防范多个磁盘故障。除了使用奇偶校验,可以使用差错纠正码,如 Read-Solomon 码。
在图 1g) 所示的方案中,每 4 位的数据使用了 2 位的冗余数据,而不是像级别 5 那样的一个奇偶位,这个系统可以容忍两个磁盘故障。
RAID 级别 0+1 为 RAID 级别 0 和级别 1 的组合。RAID 0 提供了性能,而 RAID 1 提供了可靠性。通常,它比 RAID 5 有更好的性能。它适用于高性能和高可靠性的环境。不过,与 RAID 1 一样,存储所需的磁盘数量也加倍了,所以也相对昂贵。对于 RAID 0+1,一组磁盘分成条,每一条镜像到另一条。
另一正在商业化的 RAID 选项是 RAID 1+0,即磁盘先镜像,再分条。这种 RAID 比 RAID 0+1 有一些理论上的优点。例如,如果 RAID 0+1 中的一个磁盘故障,那么整个条就不能访问,虽然所有其他条可用。对于RAID 1+0,如果单个磁盘不可用,但其镜像仍然如所有其他磁盘一样可用(图 2)。
这里描述的基本 RAID 方案有很多变种。因此,对于不同RAID级别的精确定义,可能存在一定的混清。
RAID 实现是另一可变之处。考虑 RAID 实现的如下层次:
其他特征,如快照和复制,在每个级别中都可以实现。快照是在最后一次更新之前文件系统的视图。复制涉及不同站点之间的自动复制写入,以提供冗余和失败恢复。
复制可以是同步或异步的。对于同步复制,在写入完成之前,必须在本地和远程的站点中写入每块;而对于异步复制,写入是定期地按组来进行的。如果主站点故障,则异步复制可能导致数据丢失,但是它更快且没有距离限制。
这些特征的实现,因 RAID 实现级别的不同而不同。例如,如果 RAID 实现采用软件,则每个主机可能需要实现和管理其自己的复制。然而,如果 RAID 实现采用存储阵列或 SAN 互连,则无论主机操作系统或其功能如何,都可以复制主机的数据。
大多数 RAID 实现的另一方面是热备份磁盘。热备份(hot spare)不是用于存储数据,但是配置成在磁盘故障时用作替换。例如,如果每对磁盘之一故障,则热备份可以用于重构镜像磁盘对。这样,就可以自动重建 RAID 级别,而无需等待替换故障磁盘。分配多个热备份允许多个磁盘故障而无需人工干预。
RAID 级别有很多,系统设计人员如何选择 RAID 级别?
一个考虑是重构性能。如果磁盘故障,则重建数据的所需时间可能很大。如果要求持续提供数据,如高性能或交互式数据库系统,那么这可能是个重要因素。此外,重建性能影响平均故障时间。
重建性能随着使用 RAID 级别而异。RAID 级别 1 的重建最简单,因为可以从另一个磁盘来复制数据。对于其他级别,需要访问阵列内的所有其他磁盘,以便重建故障磁盘的数据。对于大磁盘集的 RAID 5 重建,可能需要几个小时。
RAID 级别 0 用于数据损失并不重要的高性能应用程序。RAID 级别 1,对于需要高可靠性和快速恢复的应用程序,很受欢迎。RAID 0+1 和 RAID 1+0 用于性能和可靠性都重要的应用,例如小型数据库。由于 RAID 1 的高空间开销,RAID 5 通常是存储大量数据的首选。虽然级别 6 并不为许多 RAID 实现所支持,但是它应该比级别 5 提供更好的可靠性。
RAID 系统设计人员和存储管理员还必须做出其他几个决定。例如,给定 RAID 集应有多少磁盘?每个奇偶校验位应保护多少位?如果阵列内的磁盘越多,则数据传输率就越高,但是系统就越昂贵。如果奇偶校验位保护的位越多,则由于奇偶校验位而导致的空间开销就越低,但是在第一个故障磁盘需要替换之前而第二个磁盘出现故障并且导致数据丢失的机会就越高。
RAID 概念已扩展到其他存储设备(包括磁带阵列),甚至无线系统的数据广播。当应用于磁带阵列时,即使磁带阵列内的一个磁带损坏,仍然可以利用 RAID 结构恢复数据。当应用于广播数据时,每块数据可分为短单元,并和奇偶校验单元一起广播。如果一个单元出于某种原因不能收到,则它可以通过其他单元来重构。通常,磁带驱动机器人包括多个磁带驱动器,可将数据分散在所有驱动器上以增加吞吐量和降低备份时间。
RAID 并不总是确保数据对操作系统和使用者是可用的。
例如,文件指针可能是错的,或文件结构内的指针可能是错的。如果没有正确恢复,则不完整的写入会导致数据损坏。一些其他进程也会偶然写出文件系统的结构。RAID 防范物理媒介错误,但不是其他硬件和软件错误。与软件和硬件错误一样,系统数据潜在危险也有许多。
Solaris ZFS 文件系统采用创新方法来解决这些问题,即采用校验和,这是用于验证数据完整性的一种技术。ZFS 维护所有块(包括数据和元数据)的内部校验和。这些校验和没有与正在进行校验的块放在一起;而是与块的指针放在一起(见图 3)。
考虑一个信息节点(存储文件系统元数据的结构),带有数据指针。每个数据块的校验和位于 inode 内,如果数据有问题,则校验和会不正确,并且文件系统会知道它。如果数据是镜像的,有一个块具有正确的校验和,并且另有一个块具有不正确的校验和,那么ZFS会自动采用好的块来更新错误的块。
类似地,指向 inode 的目录条目具有 inode 的校验和。当访问目录时,inode 的任何问题会检测到。所有 ZFS 结构都会进行校验和,以便提供比 RAID 磁盘集或标准文件系统更高级别的一致性、错误检测和错误纠正。因为 ZFS 的整体性能非常快,校验和计算与额外块读-改-写周期的额外开销不是明显的。
大多数的 RAID 实现的另一个问题是缺乏灵活性。考虑一个具有 20 个磁盘的存储阵列,它分为 4 组,每组有 5 个磁盘。5 个磁盘的组为 RAID 级别 5。因此,有 4 个单独的卷,每个都有文件系统。但是如果文件太大以致于不适合 5 个磁盘的组,怎么办?如果另一个文件系统需要很少的空间,怎么办?如果事先已经知道这些因素,则可以正确分配磁盘和卷。然而,很多时候磁盘的使用和需求随时间而变化。
即使存储阵列允许 20 个磁盘的集合创建成一个大的 RAID 集,其他问题可能出现。多个各种大小的卷可以创建在这个集上。但是有的卷管理器不允许我们改变卷的大小。在这种情况下,会有与上述相同的不匹配文件系统大小的问题。有些卷管理器允许更改大小,但是有些文件系统不允许文件系统生长或收缩。卷可以更改大小,但是文件系统需要重建以利用这些改变。
ZFS 将文件系统管理和卷管理组合到一起,比这些功能的传统分开提供更强的功能。磁盘,或磁盘分区,通过 RAID 集组成存储池。每个池可以容纳一个或多个 ZFS 文件系统。整个池的可用空间可用于该池的所有文件系统。
ZFS 采用内存模型的 malloc() 和 free(),为每个文件系统分配和释放存储。因此,存储使用没有人为限制,无需在卷之间重定位文件系统,或调整卷大小。ZFS 提供配额来限制文件系统的大小,并提供预留以确保文件系统可以增长指定数量,但是文件系统所有者可以随时改变这些变量。图 4a) 显示了传统卷和文件系统,而图 4b) 显示了 ZFS 模型。