CentOS 7 使用 Btrfs 文件系统组建 RAID5 实例(可用于搭建 NAS)


一、前言

我打算暑假在家里搭个服务器,其中 NAS 存储功能占了很大的比重。

作为 Linux 爱好者,我当然不想使用“群晖”之类的专用 NAS 系统,而是想深入了解各种文件系统的特性,用 CentOS 系统全手动搭建 NAS 系统。

我的要求是:要能用 RAID5 冗余、可以方便而无损的增减硬盘。

经过一段时间的摸索,有以下几种可行的方案:

  1. mdadm 创建软 RAID5,然后在上面创建 EXT4 文件系统;
  2. 使用 LVM 创建 RAID5 逻辑卷,然后在上面创建 EXT4 文件系统;
  3. 使用 Btrfs 文件系统组建 RAID5;
  4. zpool 组建 zfs 文件系统;
  5. 买硬件 RAID 卡。

方案 5 最先排除,因为是“最傻瓜”的方案,基本上零折腾,而且 RAID 卡一掉电的话数据就全丢了。

方案 1 和 2 试着配置了下,也成功了,不过维护难度较大,而且需要保存 RAID 元数据。

方案 3 比起方案 1、2 配置和维护也简单多了。

方案 4 最复杂,文档完全看不懂,试着搞了下,哎~还是放弃吧。

最后,我选择了方案 3,也就是 Btrfs。

关于 RAID 类型选择以及 RAID 知识不在本文讨论范围内,不懂的请自行搜索。

本文纯属个人学习经验分享,希望可以帮到您!如有错误请及时留言提出,谢谢!

此外,在本文发表了几天之后,WannaCry 勒索病毒就肆虐了全球!这迫使我去研究 Btrfs 的快照功能。

我为此专门写了一篇文章专门介绍了 Btrfs 快照的简单用法,建议去了解一下。

「用 snapper 轻松玩转 Btrfs 的快照功能」


二、Btrfs 简介

Btrfs(B-tree文件系统,通常念成 Butter FS,Better FS 或 B-tree FS),一种支持写入时复制的文件系统,运行在 Linux 操作系统,采用 GPL 授权。
Oracle 于 2007 年对外宣布这项计划,并发布源代码,在 2014 年 8 月发布稳定版。目标是取代 Linux 目前的 ext3 文件系统,改善 ext3 的限制,特别是单个文件的大小,总文件系统大小或文件检查和加入 ext3 未支持的功能,像是可写快照(writable snapshots)、快照的快照(snapshots of snapshots)、内建磁盘阵列(RAID),以及子卷(subvolumes)。Btrfs 也宣称专注在“容错、修复及易于管理”。

来自:维基百科
更多详情请移步:ArchWiki


三、实验环境

  • 虚拟机:VMware Fusion 8.5
  • 操作系统:CentOS 7.3.1611 最小安装
  • 虚拟磁盘:sdb sdc sdd sde(大小均为 2G)
  • 磁盘挂载点:/mnt/data

四、Btrfs 的创建

创建卷名为 data 的 Btrfs 文件系统,数据和元数据的存储模式均为 RAID5,包含 sdbsdcsdd 三个成员。

命令:

mkfs.btrfs -L "data" -d RAID5 -m RAID5 -f /dev/sd[b-d]

运行结果:

btrfs-progs v4.4.1
See http://btrfs.wiki.kernel.org for more information.

Label:              data
UUID:               d8d84a93-9203-4b31-b7e3-e281765c2c83
Node size:          16384
Sector size:        4096
Filesystem size:    6.00GiB
Block group profiles:
  Data:             RAID5           417.50MiB
  Metadata:         RAID5           417.50MiB
  System:           RAID5            20.00MiB
SSD detected:       no
Incompat features:  extref, raid56, skinny-metadata
Number of devices:  3
Devices:
   ID        SIZE  PATH
    1     2.00GiB  /dev/sdb
    2     2.00GiB  /dev/sdc
    3     2.00GiB  /dev/sdd

这样的话,Btrfs 文件系统就创建成功了。

说明

⦁ Btrfs 支持 RAID 0、1、5、6、10。


五、Btrfs 的挂载

5.1 挂载文件系统到 /mnt/data,并使用 zlib 压缩

命令:

mount /dev/sdb /mnt/data -o compress=zlib

说明

  1. 压缩算法可以选 zlib 或 lzo。zlib 算法能获得更小的压缩率,但是牺牲了速度。lzo 做到了压缩率与性能平衡,推荐作为日常使用。这里用于 NAS,不要求过高的速度,所以选择更小的压缩率的 zlib。
  2. 挂载设备选 Btrfs 组内任一成员即可,也可指定该 Btrfs 组的 UUID(一般用于 fstab 文件中)。

5.2 检查挂载点

命令:

mount | grep btrfs

运行结果:

/dev/sdb on /mnt/data type btrfs (rw,relatime,compress=zlib,space_cache,subvolid=5,subvol=/)

5.3 检查容量

命令:

df -h /mnt/data

运行结果:

文件系统        容量  已用  可用 已用% 挂载点
/dev/sdb        6.0G   17M  5.2G    1% /mnt/data

经检查,容量符合 RAID5 标准。


六、Btrfs 信息查看

这一节我表达起来稍微有点困难,所以大家了解下就好了。

6.1 查看文件系统 UUID 及状态

命令:

btrfs fi show

运行结果:

Label: 'data'  uuid: d8d84a93-9203-4b31-b7e3-e281765c2c83
    Total devices 3 FS bytes used 320.00KiB
    devid    1 size 2.00GiB used 480.00MiB path /dev/sdb
    devid    2 size 2.00GiB used 480.00MiB path /dev/sdc
    devid    3 size 2.00GiB used 480.00MiB path /dev/sdd

6.2 查看文件系统上各种数据的用量

命令:

btrfs filesystem df /mnt/data

运行结果:

Data, RAID5: total=640.00MiB, used=192.00KiB #数据用量
System, RAID5: total=64.00MiB, used=16.00KiB #系统数据用量
Metadata, RAID5: total=256.00MiB, used=112.00KiB #元数据用量
GlobalReserve, single: total=16.00MiB, used=0.00B #全局保留数据用量

6.3 查看文件系统上各个成员的用量

命令:

btrfs device usage -h /mnt/data

运行结果:

/dev/sdb, ID: 1
   Device size:             2.00GiB
   Data,RAID5:            320.00MiB
   Metadata,RAID5:        128.00MiB
   System,RAID5:           32.00MiB
   Unallocated:             1.53GiB

/dev/sdc, ID: 2
   Device size:             2.00GiB
   Data,RAID5:            320.00MiB
   Metadata,RAID5:        128.00MiB
   System,RAID5:           32.00MiB
   Unallocated:             1.53GiB

/dev/sdd, ID: 3
   Device size:             2.00GiB
   Data,RAID5:            320.00MiB
   Metadata,RAID5:        128.00MiB
   System,RAID5:           32.00MiB
   Unallocated:             1.53GiB

6.4 查看文件系统上各个成员的 UUID

命令:

blkid | grep btrfs

运行结果:

/dev/sdc: LABEL="data" UUID="d8d84a93-9203-4b31-b7e3-e281765c2c83" UUID_SUB="e1a9d8a9-6e80-404b-b352-c39b3bfc4447" TYPE="btrfs" 
/dev/sdb: LABEL="data" UUID="d8d84a93-9203-4b31-b7e3-e281765c2c83" UUID_SUB="7b70553c-6003-4d24-83eb-5ea8fab743bb" TYPE="btrfs" 
/dev/sdd: LABEL="data" UUID="d8d84a93-9203-4b31-b7e3-e281765c2c83" UUID_SUB="7db87ff4-d02a-43ad-8c13-788c130d5fdf" TYPE="btrfs" 

说明

⦁ UUID 是整个文件系统的全局 UUID(挂载设备指定这个就好),UUID_SUB 是文件系统各成员的 UUID。


七、添加磁盘到 RAID 组中

7.1 将 sde 添加进上面创建好的文件系统

命令:

btrfs device add /dev/sde /mnt/data

说明

⦁ 如果提示磁盘上面存在文件系统,可以加 -f 强制创建。

7.2 检查文件系统

命令:

btrfs fi show

运行结果:

Label: 'data'  uuid: d8d84a93-9203-4b31-b7e3-e281765c2c83
    Total devices 4 FS bytes used 320.00KiB
    devid    1 size 2.00GiB used 480.00MiB path /dev/sdb
    devid    2 size 2.00GiB used 480.00MiB path /dev/sdc
    devid    3 size 2.00GiB used 480.00MiB path /dev/sdd
    devid    4 size 2.00GiB used 0.00B path /dev/sde

可以看到,sde 已经添加进来了,但是上面还没有存放数据。我们需要进行一次数据平衡,让数据均匀的分布在各个成员上。

7.3 平衡数据

命令:

btrfs balance start /mnt/data

运行结果:

Done, had to relocate 3 out of 3 chunks

说明

⦁ 如果数据很多的话,平衡数据的过程会花费很长时间。建议在命令后面加上 & 将命令挂在后台运行。平衡过程不能被中断。

7.4 检查平衡结果

命令:

btrfs fi show

运行结果:

Label: 'data'  uuid: d8d84a93-9203-4b31-b7e3-e281765c2c83
    Total devices 4 FS bytes used 512.00KiB
    devid    1 size 2.00GiB used 416.00MiB path /dev/sdb
    devid    2 size 2.00GiB used 416.00MiB path /dev/sdc
    devid    3 size 2.00GiB used 416.00MiB path /dev/sdd
    devid    4 size 2.00GiB used 416.00MiB path /dev/sde

可以看到,数据已经均匀的分布在各个成员上面了。


八、从 RAID 组中删除磁盘(未损坏)

8.1 将 sde 从文件系统中移除

命令:

btrfs device delete /dev/sde /mnt/data

说明

  1. 请确保文件系统剩余空间充足,否则会报错。
  2. 移除过程中,将自动执行数据平衡。数据很多的话同样会很慢。

8.2 检查文件系统

命令:

btrfs fi show

运行结果:

Label: 'data'  uuid: d8d84a93-9203-4b31-b7e3-e281765c2c83
    Total devices 3 FS bytes used 320.00KiB
    devid    1 size 2.00GiB used 480.00MiB path /dev/sdb
    devid    2 size 2.00GiB used 480.00MiB path /dev/sdc
    devid    3 size 2.00GiB used 480.00MiB path /dev/sdd

九、故障模拟 & 更换损坏的磁盘(必看!)

说明

  1. 我把 sde 重新添加进来了,并平衡文件系统,下面模拟磁盘 sde 故障并换了一块新磁盘(还是 sde)。
  2. 下面将使用 dd 命令创建一个随机文件把磁盘塞满,然后校验文件的 MD5 值,以便验证是否可以实现冗余功能。

9.1 用 dd 命令创建一个随机文件把磁盘塞满

命令:

dd if=/dev/urandom of=/mnt/data/fulldisk.img bs=10M

运行结果:

dd: 写入"/mnt/data/fulldisk.img" 出错: 设备上没有空间
记录了576+0 的读入
记录了575+0 的写出
6036258816字节(6.0 GB)已复制,434.008 秒,13.9 MB/秒

9.2 校验文件 MD5 值并记录

命令:

md5sum /mnt/data/fulldisk.img

运行结果:

462f799d2ad07295ec76162e05dba76c  /mnt/data/fulldisk.img

9.3 卸载文件系统

命令:

umount /mnt/data

说明

  1. 不卸载也可以,卸载只是为了方便发现故障。
  2. 如果 Btrfs 文件系统处于已挂载状态并且正在使用中,然后磁盘掉了,系统不会有任何提示,用 btrfs fi show 也是看不出磁盘有问题的。如果读取到的块正好处于掉了的那块磁盘中,系统会提示 IO 出错。如果需要搭建可靠的 RAID 系统的话,建议配合 smartmontools 之类的磁盘监控软件使用(这一点我做的实验不多,不能确保完全正确)。

9.4 用 dd 命令抹掉 sde 上的数据

模拟 sde 磁盘损坏,然后手动换了一块全新的 sde

命令:

dd if=/dev/zero of=/dev/sde bs=4M

运行结果:

dd: 写入"/dev/sde" 出错: 设备上没有空间
记录了513+0 的读入
记录了512+0 的写出
2147483648字节(2.1 GB)已复制,1.31242 秒,1.6 GB/秒

9.5 检查文件系统

命令:

btrfs fi show

运行结果:

warning, device 4 is missing
checksum verify failed on 5795479552 found EA8B5A91 wanted 0E68E727
checksum verify failed on 5795479552 found EA8B5A91 wanted 0E68E727
bytenr mismatch, want=5795479552, have=5774508032
ERROR: cannot read chunk root
Label: 'data'  uuid: d8d84a93-9203-4b31-b7e3-e281765c2c83
    Total devices 4 FS bytes used 1.09GiB
    devid    1 size 2.00GiB used 1.00GiB path /dev/sdb
    devid    2 size 2.00GiB used 1.00GiB path /dev/sdc
    devid    3 size 2.00GiB used 1.00GiB path /dev/sdd
    *** Some devices missing

可以看到 4 号位的 sde 已经消失了。

9.6 尝试再次挂载

命令:

mount /dev/sdb /mnt/data -o compress=zlib

运行结果:

mount: 文件系统类型错误、选项错误、/dev/sdb 上有坏超级块、
       缺少代码页或助手程序,或其他错误

       有些情况下在 syslog 中可以找到一些有用信息- 请尝试
       dmesg | tail  这样的命令看看。

显然不能正常挂载了。

9.7 以降级模式强制挂载

命令:

mount -t btrfs -o degraded /dev/sdb /mnt/data

9.8 替换 4 号位磁盘

说明

⦁ 看到几号磁盘 missing 就替换几号的。

命令:

btrfs replace start 4 /dev/sde /mnt/data

9.9 查看替换进度

说明

⦁ 查看命令会一直进行,直到替换完成。可以按 Ctrl+C 停止查看。

命令:

 btrfs replace status /mnt/data

运行结果:

20.3% done, 0 write errs, 0 uncorr. read errs
Started on  2.May 21:41:17, finished on  2.May 22:04:51, 0 write errs, 0 uncorr. read errs

替换完成。

9.10 以正常方式重新挂载文件系统

命令:

umount /mnt/data
mount -o compress=zlib /dev/sdb /mnt/data

没有报错,挂载成功,说明文件系统已修复。

9.11 重新校验文件MD5值

命令:

md5sum /mnt/data/fulldisk.img

运行结果:

462f799d2ad07295ec76162e05dba76c  /mnt/data/fulldisk.img

经比对,该 MD5 与 9.2 的 MD5 一致,冗余有效!

发表评论