很多人遇到过服务器RAID5挂掉,往往掉一个盘后,第二个盘也立刻挂掉。

大家都知道RAID5 一次允许一个盘缺失,

RAID 5也是以数据的校验位来保证数据的安全,但它不是以单独硬盘来存放数据的校验位,而是将数据段的校验位交互存放于各个硬盘上。这样,任何一个硬盘损坏,都可以根据其它硬盘上的校验位来重建损坏的数据。硬盘的利用率为n-1。

如果挂掉两个盘,数据就玩完了。
理论上两个硬盘同时失效的概率是很低的,但为什么会这样呢?

从数学角度说,每个磁盘的平均无故障时间 (MTBF) 大约为 50 万至 150 万小时(也就是每 50~150 年发生一次硬盘损坏)。实际往往不能达到这种理想的情况,在大多数散热和机械条件下,都会造成硬盘正常工作的时间大幅减少。考虑到每个磁盘的寿命不同,阵列中的任何磁盘都可能出现问题,从统计学角度说,阵列中 N 个磁盘发生故障的机率比单个磁盘发生故障的机率要大 N 倍。结合上述因素,如果阵列中的磁盘数量合理,且这些磁盘的平均无故障时间 (MTBF) 较短,那么在磁盘阵列的预期使用寿命过程中,就很有可能发生磁盘故障(比方说每几个月或每隔几年就会发生一次故障)。

两块磁盘同时损坏的几率有多大呢(“同时”就是指一块磁盘尚未完全修复时另一块磁盘也坏掉了)?如果说 RAID 5 阵列的MTBF相当于MTBF^2,那么这种几率为每隔10^15个小时发生一次(也就是1万多年才出现一次),因此不管工作条件如何,发生这种情况的概率是极低的。从数学理论角度来说,是有这种概率,但在现实情况中我们并不用考虑这一问题。不过有时却是会发生两块磁盘同时损坏的情况,我们不能完全忽略这种可能性,实际两块磁盘同时损坏的原因与MTBF基本没有任何关系。

今天刚好在测试一个ZFS阵列,能清晰地进行数据校验并看到结果,于是正好分析了一下原因。

对这种情况来说,这里首先要引入一个一般人不常接触到的概念:

BER 硬盘误码率,英文是BER(Bit Error Rate),是描述硬盘性能的一个非常重要的参数,是衡量硬盘出错可能性的一个参数。

这个参数代表你写入硬盘的数据,在读取时遇到 不可修复的读错误的概率。

(不能恢复的ECC读取错误)从统计角度来说也比较少见,一般来说是指读取多少位后会出现一次读取错误。

随着硬盘容量增加,驱动器读取数据的误读率就会增加,而硬盘容量暴涨,误码率的比例一直保持相对增加。一个1TB的驱动器是需要更多读取整个驱动器,这是在RAID重建期间发生错误的概率会比300G 驱动器遇到错误的几率大。
那这个错误的几率到底有多大呢?或者说,我们写入多少GB数据,才会遇到1byte的读取错误呢?

对于不同类型的硬盘(以前企业级、服务器、数据中心级硬盘用SCSI/光纤,商用、民用级别是IDE;现在对应的则是SAS/SATA;
他们的MRBF(平均无故障时间)是接近的,但是BER便宜的SATA硬盘要比昂贵的SCSI硬盘的误码率(BER)要高得多。
也就是说,出现某个sector无法读取的情况,SATA要比SCSI严重得多。
这两种硬盘(企业级的SCSI/ FC/ SAS 磁盘)/(商用/民用级的IDE/SATA)BER的差距大概是1-2个数量级。

按照文中的计算,一个1TB的硬盘,通常你无法读取所有sector的概率达到了56%,因此你用便宜的大容量SATA盘,在出现硬盘故障的情况下重建RAID的希望是:无法实现。

我们回到RAID5的情况来。
在RAID5大行其道之初,硬盘的容量基本不超过100GB.

在过去,做RAID5一般RAID的磁盘容量都不大,比如72GB。无法恢复一个RAID的概率按照文献是1.1%(注意,1.1%已经很不错了,因为你在硬盘故障之后,才需要去恢复RAID。两个概率是要相乘的。

当硬盘容量上升到200GB,假设出现故障的概率是线性增长的[1]。那么失败率有11%,估计负责存储的人就被老板操的厉害了。

但是56%,也就是你用1TB的SATA硬盘做RAID5的话,当你遇到一个硬盘失效的情况,几乎剩下的两个以上硬盘(RAID5最少组合是3个)铁定会遇到一个硬盘读取错误,从而重建失败。

所以,以前小硬盘做RAID5,基本很少遇到同时挂掉两个盘的情况;现在硬盘大了,出问题的概率也越来越大了。

有人会问:56%?
文章里面这个数据还是显得有些“不可信”。大概是因为下面两个原因,我们才没有怎么听说过这么高的BER吧。

首先,我们自己用的硬盘都不会跑RAID。虽然现在我们自己的硬盘容量也变得很大(现在主流台式机SATA硬盘应该就是500G),但是这个量级的硬盘上,你往往不会把500G硬盘全部写满;而大多数数据你都很少去读取它。因此从概率上讲,坏道出现在那些没卵味的电影和音乐上的可能性大很多:大多数电影和音乐都没卵味。

但是对于跑RAID的用户,对整个硬盘进行读取的事情经常发生。即使系统足够和谐,知道不对你报告那些出现在你从不读取的文件中的坏道,但是也只是略过了报告这一步:它还是会找到所有的坏道,56%就来了。

其次,虽然你丢了一些sector,一般情况下也没啥关系。还是以电影和音乐为例,大多数的压缩算法都从设计上允许有一些这样或者那样的误码。丢了几个sector的数据,也许对你来说就是松岛枫身上一些无名的马赛克而已,你都不知道是硬盘作祟。

现在还有所谓的监控专用企业级SATA,其原理就是在固件上做手脚,让硬盘即使遇到写入的数据读取错误,也不管三七二十一直接跳过,不再重试读取(标准硬盘的读取方式是遇到某个扇区CRC错误自动重新再去读,直到读到正确的数据为止)。这对监控数据来说是理所当然的(大多数监控的硬盘都是在不停地写入,但是很少需要读取),除非遇到出现问题需要重现影像时。
遇到这种情况概率是很低地,我手头的数十个十六路硬盘摄像机,镜头也过百个,基本上几个月才需要用到回放一次,而即使需要回放,也只需要其中的很小一部分数据(比如某几个摄像头,某一天中一个小时的录像)。
但是拿这种硬盘来做RAID5就更糟糕了,当RAID5重建需要数据百分百正确时,你压根不可能读到正确的数据。

我们继续来看今天的测试数据:
我用FreeBSD 的RAIDZ软阵列创建了一个6X1TB硬盘的RAID5。当然,我没有硬盘损坏,这六个硬盘都是好的;
但是我们不管这个,这里用RAIDZ的原因是RAIDZ有数据巡检(scrub)功能,然后又能直观地看到数据巡检的结果。
一般的硬件阵列卡,也就是插在主板PCI/PCIX/PCIE/或者主板集成的RAID5,压根就没这项功能;
企业级的数据存储,也只有到盘阵级别(比如IBM DS3000/4000/5000,DELL MD3000....etc)才有这类功能,但是你也看不到检查的结果,最多能在日志里看到某个硬盘CRC失败,然后跳红灯掉出来,阵列柜告警通知你换硬盘。你别想知道这个硬盘到底是彻底挂了呢,还是有读取错误,还是有坏道。。。总之两眼一抹黑。
ZFS的好处之一就在这里了:你在命令行打个 zpool scrub tank (tank就是你创建的raid的名字),它就开工忠实地开始巡检整个阵列了,读取上面的每个字节数据,并与当初写入时的md5值进行比较,发现错误的话就报告,并尝试用冗余数据修复。这个过程是后台进行的,并且用户可以直观地看到巡检的进度、速度/所需时间以及结果。

1|  scan: scrub in progress since Tue Jan 10 16:19:26 2012
2|       4.67T scanned out of 5.02T at 332M/s, 0h18m to go
3|        620K repaired, 92.88% done
4|config:
5|
6|        NAME             STATE     READ WRITE CKSUM
7|        ftp              ONLINE       0     0     0
8|          raidz1-0       ONLINE       0     0     0
9|            mfisyspd0p3  ONLINE       0     0     3  (repairing)
            mfisyspd5p3  ONLINE       0     0     6  (repairing)
            mfisyspd1p3  ONLINE       0     0     2  (repairing)
            mfisyspd4p3  ONLINE       0     0     8  (repairing)
            mfisyspd2p3  ONLINE       0     0     2  (repairing)
            mfisyspd3p3  ONLINE       0     0     3  (repairing)

errors: No known data errors

哦,我来解释一下上面的数据的意思。为了方便起见,我在前面编了1-9行号。
第二行,数据量/阵列容量,剩余时间。因为是测试,我非常BT地把阵列几乎塞满了数据;
第三行:读取错误数据量//巡检进度;

7,8,就是阵列状态,
第9行以后是6个硬盘的编号和状态。
大家要注意的是第9行开始以后6行的最后一列,也就是提示repairing括号前的CKSUM数据。
看到墨有?有墨有?有墨有?

每个硬盘都出现了数量不等的读取错误,最少两个盘各两个;最多一个盘8个。

OK。经过整整四个多小时的扫描后,我们的阵列数据修复了620K。
这些数据才刚写进去没过多久,最早的数据也没有超过一周。

scan: scrub repaired 620K in 4h25m with 0 errors on Tue Jan 10 20:45:12 2012
config:

        NAME             STATE     READ WRITE CKSUM
        ftp              ONLINE       0     0     0
          raidz1-0       ONLINE       0     0     0
            mfisyspd0p3  ONLINE       0     0     3
            mfisyspd5p3  ONLINE       0     0     6
            mfisyspd1p3  ONLINE       0     0     2
            mfisyspd4p3  ONLINE       0     0     8
            mfisyspd2p3  ONLINE       0     0     2
            mfisyspd3p3  ONLINE       0     0     3

但是这个修复的原因是RAID5,并且每个硬盘都是好的状态,有提供足够的CRC冗余。

你别小看这620K——当你的RAID5挂掉了一个盘(根据MTBF原理,你如果有50个硬盘,每年都可能损坏至少一个);

这620K数据就是致命的了:
剩下的5个硬盘,已经无法提供足够的CRC校验数据;除非每个字节都能被顺利读取,否则这个RAID5算是废了,
只要有1个扇区错误,你就算用一个全新的硬盘替换掉那个挂掉的硬盘,也无法顺利重建RAID5。
对于市面上常见的阵列卡,直接的后果就是,在用热备盘重建时,或者甚至尚未开始重建
(RAID5没有热备又没有及时发现硬盘挂掉,或者手头、仓库没有冷备盘,采购途中等)RAID5带病运行时,
需要读取数据,偏偏又很不巧读到那个该死的BER扇区,于是BER扇区所在的硬盘直接跳掉。。。又红了。。。。。

嗯嗯,以上数据已经解释了RAID5往往一次挂两个的原因——不是用户RP问题,从BER 角度来说,是硬盘其实早坏鸟,我们没发现而已。当某个硬盘因为MTBF原因整个挂掉,有问题的BER 扇区开始跳出来作梗,于是RAID5就完蛋鸟。

我们也能总结遇到RAID5一次挂掉俩盘的概率:

1. 使用越大容量的硬盘做RAID5,遇到BER 扇区的概率越大;比如用100G硬盘做RAID5就比用1TB的安全;
2. 使用越多盘数的硬盘做RAID5,遇到BER 扇区的概率越大;比如用3个盘做的RAID5,比6个盘做的RAID5安全;
3. 使用越便宜的硬盘做RAID5,遇到BER 扇区的概率越大;比如用SCSI/FC/SAS盘比用IDE/SATA的RAID5安全;
4. RAID5里面存放的数据越多,塞得越满,遇到BER 扇区的概率越大;比如存了100G数据的比存了1TB数据的RAID5安全;

第四条同时也要看阵列卡,某些卡REBUID时只读取存过数据的扇区,某些卡则不管三七二十一要读完整个盘。

从数据角度来说,ZFS软阵列此时有它独特的优势:即使存在BER扇区,它也能跳过坏扇区继续读取其他数据,从而将损失控制在最小范围内(仅仅是BER扇区所在的文件有问题,而不会整个阵列挂掉)

比如这个例子:

scan: scrub repaired 0 in 9h0m with 4768 errors on Thu Sep 8 08:23:00 2011
config:

NAME STATE READ WRITE CKSUM
ftp ONLINE 0 0 39
da2 ONLINE 0 0 156

errors: Permanent errors have been detected in the following files:

ftp:<0x7ef04>
ftp:<0x7ef11>
ftp:<0x7ef12>
ftp:<0x7ee1a>
ftp:<0x7ef31>
ftp:<0x7ef42>
ftp:<0x7ee57>
ftp:<0x7ef5e>
ftp:<0x7ef6d>
ftp:<0x7ee70>
ftp:<0x7ee71>
ftp:<0x7ef71>
ftp:<0x7ee87>

10TB的分区,巡检后发现156个错误,但是损失仅仅是13个文件。
而且能指出这13个文件的位置及文件名,并且这13个文件也不是完全不能读取,仅仅是某些字节损坏而已。

也许这13个文件中有些是影音、图像,损失几个字节无伤大雅;也许是其他地方另有备份,可以重新复制过来;也许是某些系统文件,只需重装软件或系统即可恢复,总之,用了zfs 后损失可以控制在能容忍的范围内,这就是zfs软件阵列的优势了。

顺便鼓吹一下,zpool scrub 命令可以定期执行哦,比如每隔1-2周的周六晚上开始运行,自动检查并修复错误。这种数据自动巡检功能我从来没有在任何插卡式或者板载阵列卡上见到过,只有阵列柜级别的存储设备上才有,而且巡检报告也没有精确到文件级别这种程度。

如果用了硬件阵列卡,这个就悲剧了。。。。啥都没有。


OK,原因已经分析了,经验也总结过了,
最后一节:怎么做?

我是下载狂,一定要要放很多数据,数据量以TB计,即将突破三位数;
又是穷人,花不起很多钱,只能用最便宜的SATA盘,最好是最便宜又大碗的西数绿盘;
技术有差距啊,折腾不起ZFS;
胆子又小,担惊受怕不起,看完这篇文章,想到自己RAID里的数据随时会全部莫有,晚上睡觉都睡不着,伤不起啊肿摸办?

解决方案1. 对于不重要的大量数据,比如可以下载来的影音数据,不要做阵列。直接用单盘,每个盘放一批数据。

数据量大到一定程度,目前来说凡是总量在2TB以上的SATA阵列,如果你做了RAID5,不仅数据没保障,万一坏掉一个盘,你有50%以上的概率同时掉第二个盘,那是一定毛都不剩一根。
运气好的话,可以通过让第二个挂掉的硬盘强行上线的方式勉强恢复阵列运行,你也必须有同等容量的空间让你腾挪数据;
不要说这个数据量的备用空间一般不会有,就算有,来回折腾一次所需要耗费的时间足够让你一个礼拜没个安耽觉睡。
有人说不会啊,我这个RAID5读取有300MB/s呢,2TB数据只要两个小时。
那是你平时——RAID5缺盘运行时,性能大概只有平时的1/10-1/20,外加上肯定有读不过去的文件需要跳过。。。。再加上读不过去会掉盘,
又要重启重新强制上线——这样的事件还不止一次,按照前面的测试,6个1T盘一共遇到24个读取错误,也就是你备份的进度得熄火24次——这些事儿堆一块儿,如果不是一个心理素质非常好的,处理过N起类似事件经验的数据中心老油子,对于第一次遇到这种情况的新手绝对是噩梦般的经历。

解决方案2. 做RAID1阵列。对于重要的、并且经常变动更新数据,比如财务数据、照片、文档资料,建议用RAID1。
RAID1多花了一个盘,但是多了一道保障。

解决方案3:光磁介质冷备份。通常我们叫做刻盘,呵呵。或者硬盘冷备——我两个硬盘各复制一份,拔掉一个硬盘放抽屉里,最适合照片之类数据。

解决方案4:RAID6。不过这个需要高级别的RAID卡支持,这个卡通常会很贵,至少贵出1-2个1TB盘的价值;
同等容量还要多加一个硬盘,个人觉得在6个硬盘以内,相对RAID1的方案没有优势。既没有经济优势,又没有性能优势——啥都没有,不如老老实实做RAID1。
优点当然有咯:即使遇到挂一个盘,它还算是一个RAID5——性能没有大减,数据也还有冗余,我慢慢等硬盘保修回来即可。
注意哦,6个1T以上盘。也就是说,你的硬盘总容量少于这个数字,还是不用考虑RAID6了。

假设Raid5的阵列由多块硬盘组成,运行3年了,每天24小时工作,运行这么久硬盘或多或少会有些成长坏道,如果一块硬盘坏了,更换了新硬盘,Rebuild时,其他硬盘的成长坏道将导致Rebuild失败,故有作者"第二块盘坏掉的几率大于70%"一说,实质是疏于管理造成的.

自从几个月前吃了亏之后,我格外关注公司几台服务器的Raid的健康状况.这两个月陆续更换了4块存在坏道的硬盘(这些硬盘的使用时间大约是3年多),避免了阵列损坏.
我的做法就是抓取Raid阵列卡的日志,查看阵列的"巡读日志"和硬盘的"Midea Error"数量,及时更换存在隐患的硬盘.

而且我个人认为hotspare也不是很保险,不能依赖,还是重在管理.


人生有無數種可能,人生有無限的精彩,人生沒有盡頭。一個人只要足夠的愛自己,尊重自己內心的聲音,就算是真正的活著。