Published on

BTRFS 随记

Authors

[[Linux]]

INFO

准备在 HomeLab 上组一个 BTRFS 的 NAS,在此记录一些相关概念


什么是 BTRFS

Btrfs 是一个针对 Linux 的写时复制文件系统,旨在实现先进功能并专注于容错、修复和易管理性。由多家公司联合开发,根据 GPL 许可证授权,并向任何人开放贡献。

主要的 Btrfs 特点包括:

  • 基于范围的文件存储(最大文件大小为264
  • 小文件空间高效打包
  • 索引目录空间高效利用
  • 动态 inode 分配
  • 可写快照
  • 子卷(单独的内部文件系统根)
  • 对象级镜像和条带化
  • 数据和元数据上的校验和(提供多种算法)
  • 压缩(提供多种算法)
  • 重定向链接、去重
  • 在线校验码验证 Scrub
  • 层次配额组(支持子卷和快照)
  • 集成多设备支持,具有几个 RAID 算法
  • 离线文件系统检查
  • 有效增量备份和 FS 镜像(send/receive)
  • Trim/discard
  • 在线文件系统碎片整理
  • Swapfile 支持
  • 分区模式
  • 读/写元数据验证

RAID 概念

Btrfs 可以支持多种 RAID 模式,包括 RAID 0、RAID 1、RAID 5、RAID 6、RAID 10、F1 和 SHR。

下面是一些常见的 RAID 类型的简介:(By New Bing)

  • RAID 0 是一种将数据分散存储在多个硬盘上的方法,也称为条带化(striping)。它的优点是可以提高数据传输速度,因为每个硬盘只需要读写一部分数据。它的缺点是没有冗余,如果任何一个硬盘出现故障,整个磁盘阵列就会损坏,数据无法恢复。RAID 0 至少需要两块硬盘,可以使用任意数量的硬盘。每个硬盘的容量不必相同,但是最终的磁盘阵列容量等于最小容量的硬盘乘以硬盘数量。
  • RAID 1 是一种将数据复制存储在两个或多个硬盘上的方法,也称为镜像(mirroring)。它的优点是可以提高数据可靠性和读取性能,因为当一个硬盘出现故障时,另一个硬盘仍然可以提供完整的数据。它的缺点是磁盘利用率低,写入性能受限于最慢的硬盘。RAID 1 至少需要两块硬盘,可以使用任意数量的硬盘。每个硬盘的容量不必相同,但是最终的磁盘阵列容量等于最小容量的硬盘。
  • RAID 5 是一种将数据和相对应的奇偶校验信息存储到组成 RAID 5 的各个磁盘上,并且奇偶校验信息和相对应的数据分别存储于不同的磁盘上,其中任意 N-1 块磁盘上都存储完整的数据,也就是说有相当于一块磁盘容量的空间用于存储奇偶校验信息。它的优点是可以提高数据可靠性和 I/O 性能,因为当 RAID 5 的一个磁盘发生损坏后,不会影响数据的完整性,从而保证了数据安全。当损坏的磁盘被替换后,RAID 还会自动利用剩下奇偶校验信息去重建此磁盘上的数据,来保持 RAID 5 的高可靠性。它的缺点是写入数据的速度比对单个硬盘进行写入操作稍慢,因为需要计算和写入奇偶校验信息。RAID 5 至少需要三块硬盘,可以使用任意数量的硬盘。每个硬盘的容量不必相同,但是最终的磁盘阵列容量等于最小容量的硬盘乘以硬盘数量减一。
  • RAID 10 是一种将 RAID 1 和 RAID 0 结合起来的方法,也称为镜像条带化(mirrored striping)。它先将两块或多块硬盘组成 RAID 1 的镜像组,然后再将多个镜像组组成 RAID 0 的条带化阵列。它的优点是可以同时提高数据可靠性和 I/O 性能,因为当一个硬盘出现故障时,另一个硬盘仍然可以提供完整的数据,而且数据分散在多个硬盘上,可以并行读写。它的缺点是磁盘利用率低,成本高。RAID 10 至少需要四块硬盘,可以使用任意数量的硬盘,但必须是偶数。每个硬盘的容量不必相同,但是最终的磁盘阵列容量等于最小容量的硬盘乘以硬盘数量除以二。

使用

btrfs 使用 raid5 的方法是在创建文件系统时指定 -d raid5 和 -m raid5 选项,例如:

mkfs.btrfs -d raid5 -m raid5 /dev/sda /dev/sdb /dev/sdc

这样可以将三个硬盘组成一个 raid5 的 btrfs 文件系统,数据和元数据都有冗余保护。如果要在后续中扩容,可以使用 btrfs device add 命令添加新的硬盘,例如:

btrfs device add /dev/sdd /mnt/data

这样可以将 /dev/sdd 添加到已经挂载在 /mnt/data 的 btrfs 文件系统中。然后可以使用 btrfs balance start 命令重新平衡数据和元数据,例如:

btrfs balance start -dconvert=raid5 -mconvert=raid5 /mnt/data

这样可以将新添加的硬盘的空间分配到数据和元数据的 raid5 中,增加文件系统的总容量。

也可以动态删除磁盘,例如:

btrfs device delete /dev/sdd /mnt

删除磁盘后也需要运行 btrfs balance start 来重新分配数据和元数据。

如果发生磁盘损坏,btrfs 有一些修复工具可以尝试恢复数据,例如:

  • btrfs check --repair:检查并修复文件系统的错误,需要指定超级块和树根块的位置。
  • btrfs rescue super-recover:恢复损坏的超级块,需要指定设备路径。
  • btrfs rescue chunk-recover:恢复损坏的块组信息,需要指定设备路径。
  • btrfs restore:从损坏的文件系统中恢复文件到另一个位置,需要指定设备路径和目标路径。

内存消耗

btrfs 也会消耗一定的内存,但不像 zfs 那样需要大量的内存来缓存数据。btrfs 的内存消耗主要取决于以下几个因素:

  • 文件系统的大小和复杂度:btrfs 需要在内存中维护一些元数据结构,如 B+树、块组、空闲空间缓存等,这些结构会随着文件系统的增长而占用更多的内存。
  • 文件系统的活跃度:btrfs 会在内存中缓存一些常用的数据和元数据,以提高读写性能。如果文件系统经常有大量的读写操作,那么缓存的数据也会更多,从而占用更多的内存。
  • 文件系统的特性:btrfs 支持一些高级的特性,如快照、子卷、压缩、校验和等,这些特性也会消耗一些内存。例如,快照会导致元数据碎片化,压缩会增加 CPU 和内存的负担,校验和会占用一些内存空间来存储校验值等。

总的来说,btrfs 的内存消耗并不是一个固定的值,而是根据文件系统的实际情况而动态变化的。一般来说,btrfs 的内存消耗不会超过物理内存的 10% ,如果超过了这个比例,可能是由于某些 bug 或者配置问题导致的。

btrfs 是如何解决内存消耗问题的呢?主要有以下几个方面:

  • btrfs 采用了一种延迟分配(delayed allocation)的技术,即在写入数据时,并不立即分配磁盘空间和元数据空间,而是先在内存中缓存起来,然后在合适的时机批量分配和写入。这样可以减少磁盘碎片和元数据更新的次数,从而提高性能和降低内存消耗。
  • btrfs 采用了一种写时复制(copy-on-write)的技术,即在修改数据或元数据时,并不直接覆盖原有的内容,而是先复制一份到新的位置,然后再修改。这样可以保证数据和元数据的一致性和完整性,同时也可以实现快照等高级功能。写时复制技术虽然会增加一些内存消耗,但也可以通过回收旧版本的空间来释放内存。
  • btrfs 提供了一些用户可配置的选项来控制内存消耗,如可以通过 mount 选项或者 btrfs balance 命令来调整压缩算法、校验算法、空闲空间缓存等参数。用户可以根据自己的需求和场景来选择合适的选项,以平衡性能和内存消耗。

写时复制(copy-on-write,cow)是 btrfs 的一种核心技术,它可以保证数据和元数据的一致性和完整性,同时也可以实现快照等高级功能。写时复制技术虽然会增加一些内存消耗,但也可以通过回收旧版本的空间来释放内存。

写时复制技术并不会导致存储空间的浪费,反而可以节省存储空间。这是因为写时复制技术可以实现数据的去重(deduplication)和压缩(compression),从而减少存储空间的占用。

参考资料:

0 Linked Reference(s)