zfs raidz结构详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
6、RAIDZ 约定,一次 IO 一定是校验数+1 的整数倍,比如 RAIDZ_P 一次 IO 下来如果是 3 扇区,最后会 有一个 SKIP 扇区(因此,才会有 5 中校验要交换的做法),zfs 为了保证空间再分配时不至于出现孔洞,所以 在申请空间时,就必须满足是(nparity + 1)的整数倍,就样的好处在于,任意申请的空间,重用时,至少都 是够最小运算模式的。
四: 示例:如果 x 为 10,位于偶数 1M 内,设数据为 D1,D2,D3,D4,D5,校验为 P,则数据会存储在:
disk1
disk2
disk3
disk4
disk5
sec#0
0
1
2
3
4
sec#1
5
6
7
8
9
sec#2
10
11
P=D1+D3+D5+D6 D1
D3
sec#3
D5
D6
P=D2+D4
D2
46
*/
47
/*r 表示除去整数行外,不足一行部分,还剩多少 io 扇区(仅计数据,不计校验)*/
48
r = s - q * (dcols - nparity);
49
50
/* The number of "big columns" - those which contain remainder data. */
7、为了保证 IO 高效,zfs 一次写入 IO 时,会优先以 vdev 为单位连续写入,所以,会很不像 1 扇区为条 带大小的 RAID5,具体见结构描述示例:
假设有 5 块硬盘组成 RAIDZ,分别是 DISK1,DISK2,DISK3,DISK4,DISK5 顺序也按此排列:
如果一次 IO 大小为 1 扇区,RAIDZ VDEV 的 offset 地址为 X,则(x/5)先计算出在哪个条带,再通过(x % 情况
5)得到开始盘序,在同一条带上再向后挪一个磁盘(可能会返回 disk1),这 2 个扇区一个是数据,一 一:
个是校验(此情况 RAIDZ 无需填充),就完成了此次 IO 的存储 示例:如果 x 为 10,位于偶数 1M 内,设数据为 D,校验为 P,则数据会存储在:
disk1
disk2
disk3
disk4
33 uint64_t q, r, c, bc, col, acols, scols, coff, devidx, asize, tot;
34
35 /*
36 * "Quotient": The number of data sectors for this stripe on all but
37 * the "big column" child vdevs that also contain "remainder" data.
63 /* acols:需要存取的 io 列数 */
64 /* scols:加上可能的 skip 后的 io 列数 */
65 /*如果 io 扇区数量不必要动用所有 vdev,则没必要所有列都处理*/
66 if (q == 0) {
67 /* Our I/O request doesn't span all child vdevs. */
D2
P=D1+D3+D5+D6
D3
P=D2+D4
D4
sec#516 sec#517
作者:张宇
源码主要位于 module\zfs\vdev_raidz.c,涉及分配规则的函数为 vdev_raidz_map_alloc(),仔细对源码解读、 注释后的结果如下: 1 /* 2 * Divides the IO evenly across all child vdevs; usually, dcols is 3 * the number of children in the target vdev. 4* 5 * Avoid inlining the function to keep vdev_raidz_io_start(), which 6 * is this functions only caller, as small as possible on the stack. 7 */ 8 /* 9 *分配原则是需要在所有子 vdev 之间平均分配 IO,dcols 是目标 vdev 中的子节点数。
同时相对于传统raid也没有一个标准的校验模式虽然比较像raid5但假如是1扇区的io就更像raid13raidz也可以支持多重冗余内部称之为raidzp即通常提到的raidz支持1块硬盘掉线raidzq支块盘同时掉线如同raid6raidzr支持3块盘同时掉线4raidz的io地址是带有校验的地址值不同于传统raid校验传统raid的校验区域对于文件系统而言是不可见的5raidzp的校验位置在每次io的位置相对一致但为了负载均衡约定如果io首地址是偶数1m内即offset1m为偶数校验在数据的最前面
disk1 0
disk2 1
disk3 2
disk4 3
disk5 4
sec#1
5
6
7
8
9
sec#2
10
11
P=D1+D3+D4+D5 D1
D3
sec#3
D4
D5
P=D2
D2
SKIP
sec#4 sec#5
作者:张宇
示例:如果 x 位于奇数 1M 内,设数据为 D1,D2,D3,D4,校验为 P,则数据会存储在:
比如:RAIDZ 一段连续的空间中间,释放了 6 个扇区,如果再重用时只用了 5 个,那剩下的 1 个还是会 浪费掉,无法分配。如果是 RAIDZ2 或 RAIDZ3,这种问题就更突出了。反正无法避免浪费,为了运算简洁, 干脆在每次申请时就按整块的处理,确保无论如何释放,都不会在下一次 IO 时出现浪费。
D4
sec#4 sec#5
作者:张宇
示例:如果 x 位于奇数 1M 内,设数据为 D1,D2,D3,D4,D5,校验为 P,则数据会存储在:
sec#512
disk1 0
disk2 1
disk3 2
disk4 3
disk5 4
sec#513 5
6
7
8
9
sec#514 10
11
D1
sec#515 D5
D6
D1
sec#515 SKIP
sec#516 作者:张宇
P=D1+D2
D2
情况 如果一次 IO 大小为 5 扇区,RAIDZ VDEV 的 offset 地址为 X,设"+"表示异或
三:
示例:如果 x 为 10,位于偶数 1M 内,设数据为 D1,D2,D3,D4,D5,校验为 P,则数据会存储在:
sec#0
disk5
sec#0
0
1
2
3
4
sec#1
5
6
7
8
9
sec#2
10
11
P=D
D
sec#3
作者:张宇
示例:如果 x 位于奇数 1M 内,设数据为 D,校验为 P,则数据会存储在:
disk1
disk2
disk3
disk4
disk5
sec#512 0
1
2
3
4
sec#513 5
6
7
sec#514 10
11
D
sec#515 作者:张宇
51
/*尾部扇区数,加上可能的校验的大小---如果尾部扇区数为 0,表示正好凑整 N 行,就不用另
加校验扇区了。*/ 52
bc = (r == 0 ? 0 : r + nparity); 53
54 /*
55 * The total number of data and parity sectors associated with
56 * this I/O.
57 */
58 /*表示算上校验的完整扇区总数*/
59 tot = s + nparity * (q + (r == 0 ? 0 : 1));
60
61 /* acols: The columns that will be accessed. */
62 /* scols: The columns that will be accessed or skipped. */
zfs raidz 结构详解
1、RAIDZ 是和 ZFS 密切配合的一种 RAID 模型,RAIDZ 在接收数据时是由 ZFS 指定一个可变长的数据流。 根据这个数据流的大小不同,RAIDZ 在存储时也会有不同。
2、RAIDZ 相对于传统 RAID,没有严格的 blocksize 概念,如果数据流小,甚至可以是 1 扇区的 blocksize。 同时相对于传统 RAID,也没有一个标准的校验模式,虽然比较像 RAID5,但假如是 1 扇区的 IO,就更像 RAID1 了。
disk1
disk2
disk3
disk4
disk5
sec#512 0
1
2
3
4
sec#513 5
6
7
8
9
sec#514 10
11
D1
P=D1+D3+D4+D5
D3
sec#515 D4
D5
D2
P=D2
SKIP
sec#516 sec#517
作者:张宇
情况 如果一次 IO 大小为 6 扇区,RAIDZ VDEV 的 offset 地址为 X,设"+"表示异或
28 uint64_t f = b % dcols;
29
30 /* The starting byte offset on each child vdev. */
31 /*计算每个子 vdev 的起始字节位置,用父 vdev 的扇区号简单地除以"子 vdev 数量"*/
32 uint64_t o = (b / dcols) << unit_shift;
5
6
7
8
9
sec#2
10
11
P=D1+D2
D1
D2
sec#3
SKIP
sec#4
作者:张宇
示例:如果 x 位于奇数 1M 内,设数据为 D1,D2,校验为 P,则数据会存储在:
disk1
disk2
disk3Hale Waihona Puke disk4disk5
sec#512 0
1
2
3
4
sec#513 5
6
7
8
9
sec#514 10
11
20
uint64_t b = zio->io_offset >> unit_shift;
21
22
/* The zio's size in units of the vdev's minimum sector size. */
23
/*一次 IO 的字节大小,其实就是 RAIDZx 这个 vdev,一次 IO 的有效数据大小(不包含校验,扇
68 acols = bc;
69
70
scols = MIN(dcols, roundup(bc, nparity + 1));
71
} else {
72
acols = dcols;
5、RAIDZ_P 的校验位置在每次 IO 的位置相对一致,但为了负载均衡,约定,如果 IO 首地址是偶数 1M 内(即 offset / 1M 为偶数),校验在数据的最前面;如果 IO 首地址是奇数 1M 内,校验插入数据流,在第一 个扇区(从 0 开始计数)。此规则仅适用于 RAIDZ_P,不适用于 RAIDZ_Q,RAIDZ_Q
3、RAIDZ 也可以支持多重冗余,内部称之为 RAIDZ_P(即通常提到的 RAIDZ,支持 1 块硬盘掉线)、RAIDZ_Q(支 持 2 块盘同时掉线,如同 RAID6)、 RAIDZ_R(支持 3 块盘同时掉线)
4、RAIDZ 的 IO 地址是带有校验的地址值,不同于传统 RAID 校验(传统 RAID 的校验区域对于文件系统 而言是不可见的)
15
uint64_t nparity)
16 {
17
raidz_map_t *rm;
18
/* The starting RAIDZ (parent) vdev sector of the block. */
19
/* 在父 vdev 上的扇区编号,其实就是 RAIDZx 这个 vdev,DVA 中标注的扇区号*/
8
9
P=D
情况 如果一次 IO 大小为 2 扇区,RAIDZ VDEV 的 offset 地址为 X,设"+"表示异或
二: 示例:如果 x 为 10,位于偶数 1M 内,设数据为 D1,D2,校验为 P,则数据会存储在:
disk1
disk2
disk3
disk4
disk5
sec#0
0
1
2
3
4
sec#1
10 *避免内联函数以保持 vdev_raidz_io_start(),它是这个函数只有调用者,在堆栈上要尽可能小。
11
by:北亚张宇
12 */
13 noinline static raidz_map_t *
14 vdev_raidz_map_alloc(zio_t *zio, uint64_t unit_shift, uint64_t dcols,
38 */
39
40
/*q 表示共占用多少完整行(以每个扇区为行高)*/
41
q = s / (dcols - nparity);
42
43
/*
44
* "Remainder": The number of partial stripe data sectors in this I/O.
45
* This will add a sector to some, but not all, child vdevs.
区数*每扇区字节数)*/ 24
uint64_t s = zio->io_size >> unit_shift; 25
26 /* The first column for this stripe. */
27 /*条带的第一列,是用父 vdev 的扇区编号对 vdev 数(raid 成员数)取余的结果*/
相关文档
最新文档