磁盘驱动器可以说是最容易发生故障的计算机组件。
RAID系统在驱动器之间分割数据以提高性能和/或可靠性。
所有RAID都是在软件中完成的。
所谓“硬件RAID”是由RAID控制器内的软件管理的,而不是由操作系统管理的。
有些RAID控制器实际上运行的是具有特定于供应商的RAID代码的完整BSD操作系统。
硬件RAID更像是“由黑匣子软件完成的RAID”,而不是任何神奇的高级产品。
不同的硬件RAID控制器以不同的格式在磁盘上存储数据。如果你的RAID控制器坏了,你不能用任何RAID控制器来替换它——新型号可能无法识别磁盘上的数据。
发生故障时,出色的备份远比相同或兼容的控制器、相同品牌和型号的备用控制器更可靠。
注意,许多RAID控制器不能充当哑磁盘控制器(dumb disk controller,应该是说直通控制器,或透明控制器)。当我们需要一个普通磁盘(JBOD——just a bunch of disks)时,它会将每个磁盘做成一个专有格式的单磁盘RAID阵列提供给我们。
操作系统管理软RAID。软RAID比硬RAID消耗更多的系统处理器时间和内存,但负载在现代硬件上无关紧要。将用于购买RAID卡的资金投入到更强的CPU或内存上,会更划算。而且可以避免由于RAID故障带来的风险(比如无法找到相同的替代品)。
硬RAID通常会有一个交互式界面或菜单驱动的BIOS界面来管理RAID。软RAID通常没有此类菜单,它需要你真正知道自己在做什么。
硬RAID通常会有免责条款以推脱责任。
FreeBSD有许多硬RAID卡的命令行管理程序,需要查看手册页或硬件支持列表确定是否支持你的阵列卡。
软RAID的一个弱点是,大多数硬件无法从比镜像更复杂的任何软件RAID分区启动。如果你想从RAID-5阵列启动,那你需要硬RAID。
FreeBSD软件RAID的另一个问题是,它与备份GPT分区表冲突。
大多数情况下,建议使用FreeBSD的软RAID。
尽量在RAID中使用不同品牌、不同型号、不同批次的硬盘,以避免同批次批量故障。但要注意,不同品牌的磁盘即使标称容量相同,而实际容量也可能会稍有不同。
电源不足也会损坏磁盘,尽量使用多电源。
尽量广泛分离驱动器,让它们位于不同的控制器上。
FreeBSD通过GEOM支持许多常见的RAID类型,它还支持通过ZFS进行各种类型的容灾。
严格来说,ZFS提供的容错并不是RAID。它是卷管理器和RAID的特定结合。
如果ZFS能满足需求,就用ZFS。
GEOM的全部意义在于你负责(you are in charge)。FreeBSD提供的是工具,而不是政策。
GPT分区方案将分区表的副本放在第一个和最后一个磁盘扇区上。
FreeBSD的GEOM raid将raid标签放在提供者的最后一个扇区上。
如果直接RAID磁盘,会覆盖备份GPT表。如果主分区表和备份分区表不匹配,GPT会认为其分区表已损坏。
xxxxxxxxxx
# gpart show da0
=> 40 1953525088 da0 GPT (932G) [CORRUPT]
40 1953525088 - free - (932G)
分区表的现有分区副本实际上没有损坏。GPT只看到一个分区表。你必须决定如何处理这些冲突。
一种选择是接受警告并继续前进。你在磁盘前面有一个有效的分区表副本,RAID冗余应该处理任何错误。
另一种选择是将GPT分区作为软RAID geoms的提供者。这适用于许多情况,但如果这是一个镜像引导驱动器,则必须以某种方式在磁盘上安装引导加载程序,这需要一个分区。
磁盘大小、条带大小、奇偶检验。
使用GEOM RAID时,所有磁盘的大小必须相同,或者至少每个磁盘上的空间量必须相同。
假设RAID阵列中有一组10个4TB的驱动器,其中一个驱动器出现故障。你能找到的最小的替换驱动器是6TB。你可以使用此驱动器,但只能使用4TB的替换驱动器,这会浪费额外的2TB。不要试图在这2TB的空间上创建分区,对这个分区的任何操作都会拖慢整个阵列。
在每个磁盘上创建一个分区,用于FreeBSD RAID。
将RAID分区设置为最小驱动器上可容纳的最大分区大小。
在旧版本的FreeBSD中,可以将FreeBSD安装到单个磁盘上,然后创建镜像。
在较新版本中,这很难实现。最好假设向RAID阵列添加磁盘会擦除该磁盘上的所有数据。
在对活动磁盘进行镜像之前,应备份数据。那为啥不直接备份,然后正确构建新阵列呢?
始终先创建RAID卷,然后再将数据放在磁盘上。
奇偶检验是一种非常简单的校验和,用于确保数据被正确复制。
RAID设备使用奇偶检验进行错误检测,从而可以评估磁盘部分的状态。这使磁盘阵列能够提供冗余。
RAID系统必须将磁盘空间专用于奇偶校验。它们透明地执行,这就是为什么在使用某些RAID时会丢失空间的原因。
条带大小是指在一次传输中写入单个驱动器上的文件块的大小。
常见的条带大小为128KB。例如一个512KB的文件会被分成4个条带,分散存储在磁盘上。
对于特定的工作负载,某种条带尺寸可能更适合。但条带大小应该是扇区大小的偶数倍,否则性能会大幅下降。
默认的128KB条带是一个很好的平均值,适用于大多数工作负载。
RAID有几种类型,用数字标识。常见的是RAID-0、RAID-1和RAID-5。
FreeBSD也支持RAID-3,并且可以将这些RAID类型组合成RAID-10、RAID-50、RAID0+1等更奇特的RAID。
FreeBSD GEOM RAID工具支持常用的GEOM命令,如gmirror show,但也有用于RAID特定任务的命令。
xxxxxxxxxx
# gmirror status
Name Status Components
mirror/gm0 COMPLETE da1p1 (ACTIVE)
da2p1 (ACTIVE)
输出格式因各种RAID命令而异,但一般来说COMPLETE意味着阵列状态良好。
list命令现实特定GEOM类型的各种提供者和使用者。
本章中的所有GEOM RAID示例都使用1TB驱动器。每个驱动器使用GPT分区方案,并具有单个磁盘分区。
除非另有说明,一般都是这样创建的:
xxxxxxxxxx
# gpart create –s gpt da0
# gpart add –t freebsd-ufs –a 4k da0
这些磁盘的型号不同,来自不同的供应商,使用gpart show命令验证分区大小是否相同。
建议对每个驱动器附加一个GPT标签,并使用该标签而不是原始的设备名称。
条带化磁盘可以将多个硬盘组合成一个大型虚拟硬盘驱动器。
条带在所有驱动器之间共享事务,理论上可以提高性能和吞吐量。
性能很少能达到两个驱动的总和,但应该能超过一个单独驱动器的性能。
使用gstripe命令配置和管理磁盘条带化。
首先使用kldload或gstripe load加载geom_stripe.ko内核模块。
如果想在启动时自动加载RAID-0,在/boot/loader.conf中加载此模块。
使用gstripe label命令创建条带提供者并驱动器它们在其中。
下面我们创建一个名为Stripe1的条带驱动器。此条带包含所有四个示例驱动器。使用-s选项指定条带大小:
xxxxxxxxxx
# gstripe label -s 128kb Stripe1 da0p1 da1p1 da2p1
我们现在有了一个条带提供者:/dev/stripe/Stripe1。然后再设备上放置一个文件系统,不要忘记使用-j表示软更新日志(soft updates journaling):
xxxxxxxxxx
# newfs –j /dev/stripe/Stripe1
底层磁盘不需要大小相同,更不用说具有共同的几何图形。这可以消除对老式硬盘几何结构的任何疑虑。
如果要分区,可将GPT分区表添加到条带化设备中:
xxxxxxxxxx
# gpart create -s gpt /dev/stripe/Stripe1
stripe/Stripe1 created
现在可以向条带磁盘中添加分区了。
条带geom无法修复。
更换坏掉的磁盘,重建阵列,然后从备份中恢复。
如果要删除条带化分区并在其他地方重复使用磁盘,请卸载条带化设备。
在每个成员设备上运行gstripe clear命令:
xxxxxxxxxx
# gstripe clear da0p1 da1p1 da2p1
现在可以卸载内核模块了。
FreeBSD可以在器日志状态电子邮件中包含条带设备的状态。
向/etc/periodic.conf文件中添加daily_status_gstripe_enable=YES启用报告。
镜像磁盘在多个物理设备上维护多个数据副本。
虽然镜像传统上包括两个磁盘,但实际可以将任意数量的磁盘放入镜像中。
最好的镜像在物理上尽可能分开:多个磁盘,在不同的磁盘控制器上,甚至可能在不同的机柜(enclosure)中。
镜像磁盘会在每个磁盘的末尾写入元数据,覆盖其中已经存在的任何内容。
建议在首次创建驱动器时对其进行镜像,这样就不会覆盖实际数据。
虽然可以镜像一个已经使用了一段时间的磁盘,但长期使用的磁盘往往会分散数据。
首先使用kldload或gmirror load加载geom_mirror.ko内核模块。
如果希望镜像在启动时可用,可在/boot/loader.conf中激活gmirror模块。
创建和使用镜像与创建和使用条带化提供程序非常相似:标识要镜像的磁盘,并使用gmerror标记磁盘。在这个例子中,我用两个磁盘分区创建了一个镜像。如果要镜像启动驱动器,请参阅第11章。
首先使用gmirror label创建有一个提供者的镜像,然后使用gmirror insert命令添加一个镜像成员:
xxxxxxxxxx
# gmirror label Mirror1 da4p1
# gmirror insert Mirror1 da3p1
现在我们有了一个名称为Mirror1的镜像,包含两个驱动器分区。使用gmirror status命令查看镜像状态:
xxxxxxxxxx
# gmirror status
Name Status Components
mirror/Mirror1 DEGRADED da4p1 (ACTIVE)
da3p1 (SYNCHRONIZING, 1%)
镜像设备还没有完成镜像。geom必须从原来磁盘上复制所有资料到新镜像中。这可能要耗费一些时间,却决于驱动器和系统速度。
复制速度是相当成比例的,所以可以假设,如果同步在十分钟内完成了10%,那整个过程大约需要100分钟。
一旦同步完成,它们看起来会是这样的:
xxxxxxxxxx
# gmirror status
Name Status Components
mirror/Mirror1 COMPLETE da4p1 (ACTIVE)
da3p1 (ACTIVE)
从此,所有写入和删除都会在两个磁盘上进行。
GEOM镜像允许在不丢失数据的情况下更换发生故障的硬盘驱动器。
然而,在维修中的灵活性完全取决于硬件。如果有热插拔的驱动器,可以在系统运行时操作。如果是一个桌面式的塔式机箱,所有驱动器都安装在内部,则必须要关机以更换损坏的驱动器。
检查镜像状态以找到镜像中失败的成员:
xxxxxxxxxx
# gmirror status
Name Status Components
mirror/Mirror1 DEGRADED da3p1 (ACTIVE)
DEGRADED(降级)一词在状态字段中以不友好的大写字母出现,而第二个镜像成员没有出现。这就像是有人拔出了驱动器的电源线,引发了错误或其他什么。
首先,使用gmirror forget命令从镜像集中删除损坏的驱动器。这不会删除整个镜像配置,而是告诉gmirror忘记镜像中丢失的任何磁盘。
然后立即检查镜像的状况,以验证其是否完整:
xxxxxxxxxx
# gmirror forget Mirror1
# gmirror status
Name Status Components
mirror/Mirror1 COMPLETE da3p1 (ACTIVE)
一个只有一个成员的镜像并不是真正的镜像,但它包含了所有数据。使用insert命令添加一个新成员:
xxxxxxxxxx
# gmirror insert Mirror1 da2p1
# gmirror status
Name Status Components
mirror/Mirror1 DEGRADED da3p1 (ACTIVE)
da2p1 (SYNCHRONIZING, 23%)
磁盘同步完成后,镜像就恢复了。
镜像中可以有任意数量的成员。使用三个驱动器可以大大减少冷数据库备份所需要的时间。
当您想运行冷备份时,请关闭数据库。(这是无法避免的:冷备份的定义就是从“关闭数据库”开始。)从三向镜像中删除一个驱动器。重新启动数据库。
您的数据库现在正在双向镜像上运行,可以正常更新。分离的驱动器具有冷数据库的副本。将该驱动器装载到临时装载点上,并备份数据副本。备份完成后,将第三个驱动器重新添加到镜像中。镜像会重新同步此磁盘,您就可以进行下一次冷备份了。
如果想删除镜像,请卸载其上的任何文件系统。无法销毁已挂载的geom。然后停下来,清理镜像。
xxxxxxxxxx
# gmirror stop Mirror1
# gmirror clear da2p1 da3p1
现在可以将这些磁盘用于其他GEOM RAID。
FreeBSD可以检查您的镜像状态,并在每日状态邮件中向您发送结果。
在/etc/periodic.conf中添加行daily_status_gmirror_enable=YES。
(FreeBSD14好像是使用graid来管理raid,包括RAID5)
RAID-10又称跨镜像磁盘的条带。可能是提供大量高性能存储的最佳方式。
磁盘被分组到镜像中,然后数据在镜像中条带化。
geom不需要计算奇偶校验;镜像提供冗余、条带提供性能。
虽然RAID-10使用大量磁盘,但它是高吞吐量性能的有利竞争者。
从技术上讲,RAID-10是一种嵌套RAID。它在多个RAID-1之上运行的RAID-0。
在真正的高可用性RIAD-10中,镜像磁盘尽可能广泛地分开非常重要。将它们放在不同的控制器、不同的SCSI机架、不同的电源和不同的机架上。
这使得RAID-10的成本太高,无法用于客户网页,而普通的旧镜像就足够了,但它对金融和制造应用程序很有好处,在这些应用程序中,必须拥有所能获得的所有速度和正常运行时间。
在开始创建RAID-10之前,拿张纸,写下各种磁盘以及打算把它们放在哪里。
我将硬盘驱动器da1和da2配对为mirror1。驱动器da3和da4组成mirror2。偶数磁盘位于一个控制器上,奇数磁盘位于另一个控制器上。这样,一个控制器的故障不会损坏我的数据。
使用gmirror配置镜像:
xxxxxxxxxx
# gmirror label mirror0 da1p1 da2p1
# gmirror label mirror1 da3p1 da4p1
检查镜像状态,以验证它们都分配了正确的磁盘。即使镜像没有完全同步,可以继续操作,但请在投入生产之前给镜像一些时间来完成。
接下来,创建一个包含两个镜像设备的gstripe设备。我们将使用128KB的条带大小,并将条带设备称为raid10,创建后,检查其状态以验证是否添加了正确的设备:
xxxxxxxxxx
# gstripe label -s 128KB raid10 mirror/mirror0 mirror/mirror1
完成了。/dev/stripe中有一个raid0设备。在上面创建文件系统,挂载它,就可以使用了。
RAID-10作为一个整体是不会失效的,但单个镜像可能会失效。
使用gmirror status 命令检查各个驱动器。
也可以查看条带设备的状态,但条带基本上不会出问题。
修复失效的镜像即可。
要从系统中销毁RAID-10,应先销毁条带geom,然后再销毁各个镜像。
有些人认为应该先创建条带设备,然后再镜像它们。
尽量不要这样做,以为恢复需要对磁盘进行更多写入。
如果坚持要RAID 0+1,请按照RAID-10反向操作:创建条带设备,然后镜像它们。
以RAID-10和RAID-01为例,可以结合FreeBSD的RAID功能来创建一些其他级别的RAID。
比如通过镜像RAID-5来创建RAID51,或条带化RAID-5来创建RAID-50。
这些设置大多数是对磁盘的浪费,没有任何实际意义,甚至会对数据产生更大的危险。
从别人的RAID错误中吸取教训——你没有时间独自犯下所有错误。
FreeBSD包括一个用于管理SATA RAID设备的工具graid。
尽管名字带g,但它并不是GEOM RAID工具,而是硬件RAID软件的接口。BIOS RAID阵列会在/dev/RAID目录中列出。
大多数SATA RAID实施最好从BIOS进行管理。graid手册页建议新用户从BIOS创建RAID阵列,并使用graid命令查看配置。
graid list查看找到的BIOS RAID设备,但仅此而已。
似乎新版FreeBSD在用graid管理GEOM RAID,所以才取消了graid5?
以下是graid(8)手册页内容:
graid —— 软件RAID设备控制套件。
xxxxxxxxxx
graid label [-f] [-o fmtopt] [-S size] [-s strip] format label level
prov ...
graid add [-f] [-S size] [-s strip] name label level
graid delete [-f] name [label | num]
graid insert name prov ...
graid remove name prov ...
graid fail name prov ...
graid stop [-fv] name ...
graid list
graid status
graid load
graid unload
graid实用程序用于管理GEOM RAID类支持的软RAID配置。
GEOM RAID类使用磁盘上的元数据来提供对不同RAID BIOS定义的软件RAID卷的访问。
根据RAID BIOS类型及其元数据格式,支持不同的配置和功能子集。
为了允许从RAID卷启动,元数据格式应与RAID BIOS类型及其功能相匹配。
为了保证这些匹配,建议通过RAID BIOS接口创建卷,而有经验的用户可以使用此实用程序自由创建卷。
graid的第一参数(子命令)表示要执行的操作:
使用单独卷创建一个阵列。
format参数指定用于阵列的磁盘上的元数据格式,比如“Intel”。
label参数指定创建的卷的标签。
level参数指定创建的卷的RAID级别,比如RAID0、RAID1等等。
后续列表枚举用作阵列组件的提供者。特殊名称“NONE”可用于为缺失的磁盘保留空间。组件的顺序可能很重要,这取决于特定的RAID级别和源数据格式。
可用选项如下:
在已存在的阵列中创建卷。
name参数指定阵列的名称,阵列名称有label子命令创建。
level参数与label子命令中的相同。
从现有阵列中删除卷。
当删除最后一个卷后,阵列也会被删除,其元数据也会被擦除。
name参数指定要处理的阵列名称。
label或num参数指定要删除的卷。
向指定的阵列中插入指定的提供者以取代第一个丢失或失效的组件。
如果没有此类组件,则插入的磁盘会被作为热备盘。
从指定的阵列中移除指定的提供者,并销毁元数据。
如果此时有热备盘,则移出的磁盘会被热备盘取代。
将指定的磁盘标识为失效,除非由于冗余耗尽而绝对必要,否则将从活动中删除。
如果此时存在热备盘,则将用其中一个替换失效的磁盘。
停止指定的阵列。元数据将被清除。
list status load unload
参见geom命令。
GEOM RAID类遵循模块化设计,允许使用不同的元数据格式。目前支持以下格式:
SNIA通用RAID磁盘数据格式(Disk Data Format)v2.0规范定义的格式。用于一些Adaptec RAID BIOS和一些硬件RAID控制器。
由于格式灵活性高,不同的实现支持不同的功能集,并具有不同的磁盘上元数据布局。
为了提供兼容性,GEOM RAID类模拟了第一个检测到的DDF阵列的功能。考虑到这一点,它可能支持每个卷、每个阵列、每个磁盘分区等不同数量的磁盘。
支持以下配置:
RAID0(2+个磁盘),RAID1(2+个硬盘),RAID1E(3+个磁盘)、RAID3(3+个硬盘)、RAID4(3+个光盘)、RAID5(3+个磁带)、RAID5E(4+个磁盘)、RAID5EE(4+个硬盘)。
格式支持两个选项“BE”(big-endian)和“LE”(little-endian),这意味着由规范定义的大端字节序(默认)和某些Adaptec控制器使用的小端字节序。
Intel RAID BIOS使用的格式。
每个阵列最多支持两个卷。
支持配置:
RAID0(2+个磁盘)、RAID1(2个磁盘)、RAID5(3+个磁盘”)、RAID10(4个磁盘)。
Intel RAID BIOS不支持的配置,但可自行执行,风险自负:RAID1(3+个磁盘)、RAID1E(3+个硬盘)、RAID10(6+个磁盘)。
JMicron RAID BIOS使用的格式。
支持每个阵列一个卷。支持以下配置:
RAID0(2+个磁盘)、RAID1(2个磁盘)、RAID 10(4个磁盘)、CONCAT(2+个磁盘)。
JMicron RAID BIOS不支持配置,但可自行执行,风险自负:RAID1(3+个磁盘)、RAID1E(3+个硬盘)、RAID10(6+个磁盘)和RAID5(3+个盘)。
NVIDIA MediaShield RAID BIOS使用的格式。
支持每个阵列一个卷。支持以下配置:
RAID0(2+个磁盘)、RAID1(2个磁盘)、RAID5(3+个磁盘)、RAID10(4+个磁盘)、SINGLE(1个磁盘)、CONCAT(2个+磁盘)。
NVIDIA MediaShield RAID BIOS不支持配置,但可自行执行风险:RAID1(3+个磁盘)。
Promise和AMD/ATI RAID BIOS使用的格式。
每个阵列支持多个卷。每个磁盘可以拆分为最多两个任意卷使用。支持配置:
RAID0(2+个磁盘)、RAID1(2个磁盘),RAID5(3+个磁盘)、RAID10(4个磁盘)。
RAID BIOS不支持配置,但可自行执行,风险自负:RAID1(3+个磁盘)、RAID10(6+个磁盘)。
SiliconImage RAID BIOS使用的格式。
支持每个阵列一个卷。支持以下配置:
RAID0(2+个磁盘)、RAID1(2个磁盘)、RAID5(3+个磁盘)、RAID10(4个磁盘)、SINGLE(1个磁盘)、CONCAT(2+个磁盘)。
SiliconImage RAID BIOS不支持配置,但可自行执行,风险自负:RAID1(3+个磁盘)、RAID10(6+个磁盘)。
GEOM RAID类遵循模块设计,允许使用不同的RAID级别。目前已实现以下RAID级别的完全支持:
RAID0、RAID1、RAID1E、RAID10、SINGLE、CONCAT。
对于处于最佳状态(不使用冗余)的卷,以下RAID级别支持为只读:
RAID4、RAID5、RAID5E、RAID5EE、RAID5R、RAID6、RAIDMDF。
GEOM RAID类不支持某些元数据格式允许的RAID级别迁移。
如果您是使用BIOS或其他方式开始迁移的,请确保在那里完成迁移。在可能出现数据损坏的情况下,不要在迁移卷上运行GEOM RAID类!
NVIDIA元数据格式不支持2TiB以上的卷。
以下sysctl(8)变量可用于控制RAID GEOM类的行为。
运行成功返回0,其他非0返回值都意味着命令运行失败了。