系统管理

作者:Martin Schulze

RAID 代表“廉价磁盘冗余阵列”。它的目的是同时加快和保障磁盘访问速度。然而,RAID 并非新技术。它于 1987 年在加州大学伯克利分校被发明。在 Linux 出现之前,它仅以特殊硬件的形式提供,价格昂贵。当然,它只能用于高端计算中心。

在过去的几十年里,处理单元的性能每年增长五到十倍,具体取决于您相信哪个统计数据。在同一时期,磁盘容量翻了一番或两番,而价格每隔一到两年减半。二手电子产品无法反映当前的处理器速度。这导致 I/O 成为现代计算机的当前瓶颈。不妨尝试在配备普通 SCSI 磁盘布局的笨拙 PII-233 上编译我们著名的 XFree86 源代码。

当伯克利的人们意识到这一点时,他们能够预见到在不久的将来不会出现硬盘的划时代新技术。由于磁性和机械导向的磁盘被保留,物理定律只允许略微改进,因此需要找到其他解决方案。

这促成了几个 RAID 级别的定义。如今,它们不仅用于高级计算机机房,也用于所谓的中端领域。自从一些内核黑客决定为 Linux 内核实现 RAID 以来,这项技术可以被低端 PC 使用,普通用户可以对性能的提高和数据安全性感到满意。

System Administration

图 1. RAID-5 的运行

RAID 级别共享以下属性

  • 几个不同的物理磁盘被组合并作为一个复合元素访问。在 Linux 下,这是通过多设备驱动程序完成的,也称为 /dev/md*。

  • 存储的数据以明确定义的方式分布在所有磁盘上。

  • 数据以冗余方式存储在磁盘上,因此在发生故障时,数据可以恢复。

通过将数据分成相等的块并将它们分布在所有受影响的磁盘上,可以获得比仅使用一个快速磁盘更高的 I/O 性能。这是因为能够以并行方式从磁盘请求数据。实现此目的最简单的方法称为条带化模式或 RAID 级别 0,但它不包含任何冗余。

冗余以不同的方式实现。最简单的方法是将数据存储在两个相同的磁盘上。这在 RAID-1 中定义,也称为镜像。当然,只有当使用至少四个磁盘时,才能获得性能提升。

当不复制所有数据,而是生成唯一的校验和并与常规数据一起存储时,可以获得更有效的冗余。如果单个磁盘发生故障,则可以使用该条带的所有数据块以及计算出的校验和来重建其数据。计算校验和最简单的方法是 XOR 条带中的所有数据块。这在 RAID 级别 4 和 5 中定义。非官方的级别 6 使用另一个块用于不同的校验和算法,从而产生两个冗余磁盘,甚至更好地避免崩溃。

如何设置 RAID

将文件系统与 RAID 一起使用有很多优点。首先是速度。RAID 组合了多个磁盘,并按顺序从磁盘读取/写入块。其次,您可以获得比最大磁盘更大的文件系统(对于 /var/spool/news/、/pub/ 等很有用)。第三,实现冗余意味着磁盘故障不会导致数据丢失。有关 RAID 的技术信息,请参阅 ftp://ftp.infodrom.north.de/pub/doc/tech/raid/。

要将 RAID 与 Linux 一起使用,您需要一个具有适当支持的内核。首先,这指的是对“多设备驱动程序”(CONFIG_BLK_MD_DEV)的支持。Linux 2.0.x 支持线性模式和条带化模式(后者也称为 RAID 0)。Linux 内核 2.1.63 也支持 RAID 级别 1、4 和 5。如果您想为 2.0.x 使用这些级别,则必须安装本文末尾提到的内核补丁。

要使用其中任何一种,您必须激活内核中的相应驱动程序。(无论如何,我建议您自己编译内核。)此外,您需要安装特殊的工具。对于线性模式和 RAID 级别 0,您需要 mdutils 包,该包应包含在您的发行版中。要使用 RAID 级别 1、4 或 5,您需要安装 raidtools 包,该包取代了 mdutils 包。

如果您使用大小完全相同的分区,条带化工作效率最高。Linux 的 RAID 驱动程序也可以处理不同的大小,但效率较低。在这种情况下,驱动程序在使用了特定数量的磁盘空间后,不会将所有磁盘用于条带化。在任何时候都会使用最大数量的磁盘。

在设置 RAID 并将几个磁盘组合成一个复合设备后,您不会使用 /dev/sd* 直接访问磁盘。相反,您可以使用多设备驱动程序,该驱动程序提供 /dev/md*。这些设备是块设备,就像普通磁盘一样,因此您只需在它们上面创建一个文件系统并挂载。

Linux 内核的默认设置最多提供四个这样的复合设备。每个 MD 最多可以包含八个物理磁盘(块设备)。如果您的设置需要更多组合设备或更多复合设备,您必须编辑 Linux 内核源代码树中的 include/linux/md.h,特别是 MAX_REALMAX_MD_DEV。为了测试目的,您可以使用一些环回设备代替物理磁盘。

通过 RAID 进行交换
System Administration

图 2. RAID 在 Linux 内核中的位置

Linux 内核本身就支持将交换空间分布在多个磁盘上。与其设置 RAID-0 设备并将交换指向它,不如简单地将所有交换分区添加到 /etc/fstab 并使用 swapon -a 来激活它们。内核对它们使用条带化(RAID-0)。这是一个示例设置

/dev/sda3  none  swap  sw
/dev/sdb3  none  swap  sw
/dev/sdc3  none  swap  sw
设置 RAID

为普通文件系统(如 /var、/home 或 /usr)设置 RAID 非常简单。在您对磁盘进行分区后,指示 RAID 子系统如何组织分区。此信息将复制到 /etc/mdtab 以供稍后激活。可以通过发出以下命令来完成

mdcreate -c4k raid0 /dev/md0 /dev/sda1 /dev/sdb1\
   /dev/sdc1

列表 1。

如果您想使用 RAID 级别 1、4 或 5,您必须使用一个额外的配置文件,该文件反映了如列表 1 所示的磁盘设置。这些级别更复杂,需要在复合设备顶部添加特殊签名。此签名由 mkraid 命令生成。剩余的设置如下所示

mkraid /etc/raid/raid5.conf
mdcreate raid5 /dev/md1 /dev/sdd1 /dev/sde1\
   /dev/sdf1 /dev/sdg1 /dev/sdh1

现在已经创建了两个 RAID;第一个由三个分区组成,而第二个使用了其中的五个分区。根据要存储在它们上面的数据,选择了不同的块大小。下一步是使用以下命令激活这些设备

mdadd -ar
从现在开始,您可以将 /dev/md0 和 /dev/md1 称为可能包含您的文件系统的块设备。为了使用这些设备,请在启动序列期间发出此命令。请查看您的发行版的启动序列。其中一些(例如,Debian)已经包含了这一行。

在内核知道磁盘是如何组织之后,您可以在新设备上创建文件系统,并将它们像往常一样添加到 /etc/fstab 中。

RAID 上的根文件系统

在根文件系统上使用 RAID 有点棘手。问题在于,如果内核不是以线性方式位于磁盘上(就像在 EXT2 或 MSDOS 文件系统上一样),则 LILO 无法读取和启动内核。解决方案是将内核放在具有普通文件系统的不同分区上,并在内核启动后激活 RAID。

这样,LILO 会启动内核,但内核本身将无法挂载根文件系统,因为其 RAID 子系统尚未初始化。现在您遇到麻烦了,对吗?不。

对于较新的 2.1.x 内核,可以使用内核参数从 RAID 加载内核。

md=<
   <fault level>,dev0,dev1,...,devn

这需要使用 append= 选项添加到 LILO 中,或者直接在启动阶段的 LILO 提示符下添加。您可以在 Linux 源代码树的 Documention/md.txt 中找到更多信息。

对于稳定的内核(2.0.x)和“不太新的”开发内核(2.1.x),您需要一种机制来在内核加载后但在尝试挂载根文件系统之前调用一些程序。这至少指的是 mdadd

实现此目的的唯一方法是使用初始 RAM 磁盘,也称为 initrd。有关 initrd 的一般信息可以在内核源代码树内的 Documentation/initrc.txt 中找到。

您很可能必须编译自己的内核,尽管如果您的发行版包含所有工具,您可以尝试使用随发行版一起提供的内核。您需要将模块支持添加到描述的解决方案中。但是,描述的设置需要额外的内核编译选项,如列表 2 所示。此外,您必须包含对您的 SCSI 卡等的支持。如果您不确定这些选项,请参阅 Kernel-HOWTO 并使用 ? 显示所引用驱动程序的描述。

列表 2。

如果 Linux 内核使用 initrd,它会将给定的 RAM 磁盘挂载为根文件系统,并在找到时执行 /linuxrc。然后内核继续其启动过程并挂载真正的根文件系统。旧的 initrd 根将被移动到 /initrd(如果该目录可用),或者在不可用时被卸载。如果只是移动,则 RAM 磁盘仍保留在内存中。因此,在内存较小的系统上,您应该让内核在不再需要时完全删除它。

initrd 文件是一个“简单”的根磁盘,包含执行 /linuxrc 文件所需的所有文件。如果它是一个 shell 脚本,它包括一个工作 shell 和此脚本中使用的所有工具。为了执行程序,它还包括一个工作 libc,其中包含 ld.so 和工具。或者,您可以静态链接包含的程序,而不需要共享的 libc。由于这不会节省任何空间,因此没有必要。

在从 /linuxrc 初始化 RAID 后,您必须告诉内核其新根文件系统的位置。那时,可以将其配置为使用 initrd 作为根文件系统。幸运的是,我们的内核黑客伙伴设计了另一个简单的界面来设置根文件系统。

此工具利用 /proc 文件系统。新根文件系统的设备号必须发送(使用 echo)到 /proc/sys/kernel/real-root-dev,内核会在 /linuxrc 完成后继续使用该设置。

由于 LILO 通常无法从非线性块设备(如 RAID)启动,因此您必须保留一个小分区,其中包含内核和初始 RAM 磁盘。我已决定使用 10MB 分区作为 /boot。二进制文件可以存储在此分区中,并且可以从救援软盘访问。我想知道为什么要使用这个,因为 Linux 非常稳定,但为了安全起见,这可能是一个好主意。

10MB 对于一个内核和一个大约 1MB 大小的 RAM 磁盘来说已经足够了。目前,我的系统仅使用了此空间的 2.5MB,因此有充足的发挥空间。由于 /boot 使用普通文件系统(例如,EXT2),您可以使用 /etc/lilo.conf 将其指向您设置中的 /boot/vmlinuz。

现在您需要决定在您的 /linuxrc 脚本中做什么。基本上,激活 RAID 并告诉内核您的根文件系统所在的位置。列表 3 显示了一个 /linuxrc 程序示例。

列表 3。

任何块设备都可以用作根文件系统。在给定的示例中,使用了 0x900。这代表主设备号 9 和次设备号 0,这是 /dev/md0 的编码。

接下来,列出所需的二进制文件和其他文件,包括 /dev 中的一些设备文件。为了使 /linuxrc 脚本工作,您需要 /dev/tty1。其他必要的设备取决于您的 /etc/mdtab 文件。您至少需要 /dev/md0。

上面的示例使用了这些二进制文件:ash、mount、umount 和 mdadd。还需要这些文件:mdtab、fstab、mtab 和 passwd。

列表 4。

列表 4 显示了我使用的 mdtab 文件。对于我的文件,必须在初始 RAM 磁盘上创建这些块设备:/dev/hda2、/dev/hda4、/dev/hdb2、/dev/hdb4、/dev/md0、/dev/md1、/dev/md2 和 /dev/md3。使用 mknod 命令创建这些设备文件。您可以通过查看您的 /dev 目录或阅读内核源代码目录中的 Documentation/devices.txt 来找到它们的主设备号和次设备号。以下命令创建 tty1 和 md0

mknod dev/tty1 c 4 1
mknod dev/md0 b 9 0

创建初始 RAM 磁盘的最佳方法是创建目录 /tmp/initrd 并在其中安装您需要的一切。完成此操作后,确定已使用的磁盘空间 (du -s),然后创建 initrd 文件。以下命令将创建一个 1MB 大小的初始 RAM 磁盘。要使用它,您的内核必须包含对环回设备的支持。

dd if=/dev/zero of=/tmp/initrd.bin bs=1024k\
   count=1
mke2fs /tmp/initrd.bin
mount -o loop /mnt /tmp/initrd.bin
由于使用了动态链接的二进制文件,因此还必须安装链接器和动态库,至少包括 /lib/libc*.so、/lib/ld-linux.so.2、/lib/ld-2.0.*.so 和适当的 /etc/ld.so.config 文件——适当的意味着 /lib 应该是文件中的唯一一行。使用以下命令创建一个新的库缓存 /etc/ld.so.cache 文件
ldconfig<\!s>-r<\!s>/tmp/initrd
并将所需的二进制文件安装到适当的目录中:/sbin 或 /bin。

不要忘记创建 /proc 目录,否则挂载将失败。fstab 和 mtab 文件可以为空且只读,但必须存在于初始 RAM 磁盘上。没有程序会尝试写入这两个文件。对于 /etc/passwd 文件,仅包含 root 用户就足够了。

在您将 /tmp/initrd 中的所有内容复制到挂载在 /mnt 的 RAM 磁盘后(请参阅上文),卸载它(例如,使用命令 umount /mnt)并将文件移动到 /boot/initrd.bin。现在告诉 LILO 加载内核和 RAM 磁盘,使用类似于列表 5 中所示的 /etc/lilo.conf 中的记录。

列表 5。

发出 lilo 命令,您就快完成了。由于 RAID 子系统现在在任何 /etc/init.d 脚本发出之前在启动阶段配置,因此您应该禁用 /etc/init.d 脚本中的 mdadd 调用。

此设置意味着您在某些非 RAID 磁盘上安装了正在运行的 Linux 系统。至少在您的交换分区上安装一个小型基本系统,在另一台机器上编译内核,在适当的机器上设置 RAID,移动文件,然后在之后继续安装。

资源

System Administration
Martin Schulze 在德国奥尔登堡学习计算机科学。他使用 Linux 已经好几年了,并尽力在力所能及的地方改进它。如今,他在家乡维护着几台机器,并参与了几个 Linux 项目,例如担任 Debian GNU/Linux 的 RAID 维护者。可以通过电子邮件 joey@infodrom.north.de 与他联系。
加载 Disqus 评论