MD中的Hot-replace机制就是当raid5设备中某块磁盘发生读写错误时,不会立刻将该磁盘踢掉,而是触发在线重构操作,将该磁盘数据拷贝到顶进的spare盘中,如果遇到坏块,则通过校验后再写入spare盘中。
从linux kernel3.3内核开始MD引入了hot-replace机制,该机制在磁盘出现局部坏块时,不会立刻将磁盘剔除,而是将该磁盘设置成WantReplacement状态。如果此时有热备盘,就会将该热备盘加入,且设置成Replacement状态,之后会将原磁盘的信息直接拷贝到热备盘中,只有遇到坏块,才会将校验后的数据写入热备盘,整盘拷贝结束,才将原来的盘踢掉。
因为减少了校验的过程,Hot-Replace机制可以加快rebuild的速度,同时也可以减少磁盘被踢掉后造成的双盘错的概率。
以下内容基于Fedora17的内核linux-3.3.4,并对比了linux-3.6.6对md改进。
目标
hot-replace机制有如下问题需要解决:
1. 什么时候会触发hot-replace机制,其工作原理是什么?
2.
需要被替换掉的磁盘信息状态是什么,怎么处理?
3. 等待替换有问题磁盘的磁盘信息状态是什么,怎么处理?
4. 需要被替换掉的磁盘什么时候移除出raid?
5. 处于hot-replace过程中,异常断电重启/机器正常重启后,是否继续hot-replace,如果不是,此时raid处于什么状态?
设计实现
状态定义
1. Md部分,磁盘状态新增两个状态:
WantReplacement:被设置了此标记的成员盘会被替换掉,并准备触发hot-replace
Replacement:当有成员盘被设置了WantReplacement状态后,此时如果有热备盘,则会将热备盘设置成Replacement,开始hot-replace
2. Raid5部分,每个stripe中描述磁盘信息结构中新增如下状态:
R5_DOUBLE_LOCKED:如果raid5设备正处于hot-replace rebuild状态中,设置成WantReplacement状态和Replacement状态的磁盘,在上层有写io时,都会写,此举主要是保证数据的一致性,当这两块磁盘都写完后,这次写操作才算完成,此标记就是保证两块磁盘数据都写完成
R5_ReadRepl:如果要读的数据在Replacement状态的磁盘上已经更新,则设置此标记,数据直接从这个磁盘读取
R5_MadeGoodRepl:从标记了Replacement状态的磁盘上读数据时发生了错误,错误被修复后,会设置此标记
R5_NeedReplace:如果要读的数据在Replacement状态的磁盘上还未更新,则设置此标记,并开始将这个数据从其他磁盘上校验出来
R5_WantReplace:如果要读的数据在Replacement状态的磁盘上还未更新,且设置了R5_NeedReplace,并且数据已经从其他磁盘上校验出来,则设置此标记,然后数据会被写到Replacement状态的磁盘
结构设计
1. 结构数组disk_info:此结构数组记录raid5中每个成员盘的结构指针rdev,为了支持hot-replace功能,新增加指针replacement。当有磁盘设置成want-replacement状态后,顶进的spare盘被设置成replacement状态,此时指针replacement就指向spare盘的结构指针
2. Stripe结构中描述每个成员盘的结构r5dev:此结构中为replacement状态的磁盘扩充了struct bio rreq;struct bio_vec rvec;主要用于数据的读写时的处理
实现方式
此机制实现上比较独立,并不牵扯到bitmap位图的修改,md部分也只是新增了两个磁盘状态,以raid5而言,其核心功能实现部分都集中在raid5。
MD部分实现
新增两个磁盘状态WantReplacement和Replacement,为此,此部分只需要sys接口对每个磁盘状态的更改。
通过命令echo want_replacement
> /sys/block/md1/md/rd0/state,可以设置md1 中rd0设备为WantReplacement,之后会唤醒sync线程开始触发rebuild操作。
如果设置了一个磁盘状态为want_replacement后,当前没有spare盘,则不会触发rebuild操作,直到有spare盘加入raid设备中,此时的rebuild操作为hot-replace。
Raid处于运行状态,不可以更改磁盘的Replacement状态。创建raid时不指定-R参数时,可以更改磁盘的Replacement状态。
另外,查看/proc/mdstat接口,处于Replacement状态的磁盘,其后面有(R)标志。
RAID5部分实现
其主要实现原理如下:
1. Raid设备创建时,给描述每个设备信息的结构disk_info初始化,rdev指针描述本磁盘的结构,而replacement指针赋值为空;
2. Raid设备正常运行时,检测到某个成员盘disk0被设置成WantReplacement状态,则将spare盘spare0设置成Replacement状态,raid开始进入hot-replace rebuilding;此时disk0的状态为want_replacement,in_sync,spare0的状态为spare,replacement;
3. Raid设备处理rebuilding时,如果disk0上的数据正常,则从disk0上读,然后写到spare0上;如果disk0上的数据不正常,则需要从其他盘上校验数据,然后将校验的数据写到spare0和disk0上;
4. Raid设备处理io时,如果是读到disk0,则会判断disk0和spare0数据是否一致,如果一致,则从spare0上读,如果不一致,则需要校验获得数据;如果是写,则会同时写disk0和spare0;
5. Raid设备处理rebuilding结束,spare盘spare0状态变成in_sync,原来的成员盘disk0状态变成fautly;也就是说,只有hot-replace结束后,才会踢盘。
6. Raid设备发生写错误时,如果是replacement状态的磁盘写错误,直接将此磁盘踢掉,等待新的spare盘顶入变成replacement状态;如果是want-replacement状态的磁盘写错误,标记为WriteErrorSeen,触发badblock机制;如果是成员盘写错误,标记为WriteErrorSeen,并且标记为want-replacement,触发hot-replace;
说明:
当同时有两块成员盘被标记为want-replacement状态,且当前有两块spare盘,不会出现两块盘都hot-replace的情况,只有第一块盘结束后,第二块盘才开始hot-replace;
在badblock机制的保证下,也不会轻易触发踢盘操作,只要不是同一个stripe的描述的数据出现2个或者2个以上错误,raid依然正常运行。
7. Raid设备发生读错误时,当raid降级、replacement状态的磁盘读错误、整个raid的读错误数达到stripe个数都会造成踢盘,否则就会设置成rewrite,然后通过校验将数据再写到发生错误的磁盘,尝试修复该位置数据,之后再将数据读出来。
8. Raid中某个设备被remove时,会将该磁盘的状态清掉。
9. 被标记为want-replacement状态的磁盘,其并没有元数据保存该状态,当raid被停止后,再恢复出来时,标记为want-replacement状态的磁盘不会组装到raid中,而之前处于hot-replace
rebuilding的raid将会变成降级rebuilding状态,此时会接着之前的位置继续做重构。
hot-replace触发点
触发点有两个地方:
1. 手动设置一块成员盘为want_replacement,此可以模拟hot-replace;
2. 磁盘发生写错误时。
模拟测试
测试平台:Fedora17
测试工具:dd(测试读/写,粒度4K)
Raid5参数:chunk=64k,bitmap-chunk=2048k,metadata=1.2
测试方法:手动设置一块成员盘为want-replacement状态
测试用例:
1. 三个成员盘disk0,disk1,disk2,一个热备盘spare0,disk0设置成want-replacement
测试结果:
通过iostat查看带宽,可以看到disk0只有读,spare0只有写,其他两个盘无io;mdadm –D /dev/md1,可以看到raid并没有降级, spare0变成spare rebuilding状态;
2. 三个成员盘disk0,disk1,disk2,disk0设置成want-replacement
测试结果:
通过iostat查看带宽,三块盘均无io,mdadm –D /dev/md1,可以看到raid并没有降级,处于正常状态;再加入一个热备盘spare0,测试结果同用例1。
3. 三个成员盘disk0,disk1,disk2,一个热备盘spare0,disk0设置成want-replacement,等待hot-replace结束,将disk0加回raid
测试结果:
raid正常,disk0为spare,如果将raid stop掉,再run起来,发现disk0没有组装到raid中,此时可以将disk0清掉superblock,避免此情况。
测试总结:
1. 没有热备盘的情况,如果一块成员盘被设置成want-replacement状态,不会立刻踢盘(写错误时,badblock保证),也不会触发hot-replace,只有有热备的情况下,才会触发。
2. 将有磁盘元数据信息(superblock)的磁盘插回到raid中,遇到raid重启,会导致组装不进去。
总结
针对前面提到的问题,这里总结如下:
1. 当有块成员盘被设置成want-replacement状态,且当前有热备盘时会触发hot-replace机制,能够读到的数据直接拷贝,读不出来的数据通过校验写入到顶进的热备盘中。
2. 被设置成want-replacement状态的磁盘信息只是在raid运行时被设置,并不会以元数据的形式保存到磁盘中,因此在机器重启后,该磁盘不会组装到raid中。即重启机器后,不会继续做hot-replace操作。
3. 被设置成replacement状态的磁盘信息会保存在元数据中随着元数据的下刷保存到磁盘中,因此机器重启后,能识别出来某个磁盘为之前的spare rebuild磁盘,之后raid运行后,会继续做重构。
4. 处于replacement状态的磁盘在遇见写错误时,会直接踢盘。而处于want-replacement状态的磁盘因为有badblock机制的保证,写不会立刻踢盘,如果没有badblock机制,直接将其踢掉,hot-replace机制在桌面盘中不能完全发挥其优势。
5. 处于replacement状态的磁盘当出现读写错误时会被踢掉。
阅读(1948) | 评论(0) | 转发(0) |