跳转到内容

Bcachefs

来自 Arch Linux 中文维基

Bcachefs 是一种写时复制(CoW)文件系统,支持多设备、RAID、压缩、校验和加密。它旨在提供类似于 BtrfsZFS 的现代功能。

Bcachefs 基于 Bcache,两者都主要由 Kent Overstreet 开发。

警告:Bcachefs 是一个实验性文件系统。请务必备份所有你无法承受丢失后果的数据。

安装

[编辑 | 编辑源代码]

自 2024 年 1 月内核发布 6.7 版本起,Bcachefs 已被合并到上游,因此可以直接安装 linux 或是 linux-zen 来使用。其他的内核软件包可能基于低于 6.7 版本的内核,所以可能会需要额外的补丁才能使用 Bcachefs。

bcachefs-tools 是 Bcachefs 用户空间的工具。

初次设置

[编辑 | 编辑源代码]

单盘

[编辑 | 编辑源代码]
# bcachefs format /dev/sdX
# mount -t bcachefs /dev/sdX /mnt

多盘

[编辑 | 编辑源代码]

与 RAID0 类似,Bcachefs 默认会将数据条带化存储 (stripe)。数据冗余由 replicas 选项进行处理。 对 2 个存储设备使用 --replicas=2 相当于 RAID1,对 4 个存储设备使用 --replicas=2 相当于 RAID10,以此类推。

# bcachefs format /dev/sdX /dev/sdY --replicas=n
# mount -t bcachefs /dev/sdX:/dev/sdY /mnt

Bcachefs 支持混合使用不同的储存设备。如果储存设备的大小不同,为了让每个储存设备以相同的速率填满数据,文件系统在某些储存设备上会使用更大的条带。如果储存设备的速度不同,对冗余数据的读取请求会被发往 IO 延迟最低的设备。如果有些储存设备比其他更可靠(例如硬件 RAID),可以通过 --durability=2 device 来把上面的每份数据副本算成两份。

加密根文件系统

[编辑 | 编辑源代码]

Bcachefs 使用 自行实现 的全文件系统加密,采用 ChaCha20-Poly1305。要格式化加密的文件系统:

# bcachefs format --encrypted /dev/sdX

如果用于根文件系统,请在 /etc/mkinitcpio.confHOOKS 中添加 bcachefs,以便在启动或从休眠恢复时提示文件系统解锁。

注意: 当前只有基于 BusyBox 的初始内存盘(initramfs)支持bcachefs hook。


SSD 缓存

[编辑 | 编辑源代码]

Bcachefs 有四个储存目标(storage targets): metadata、background、foreground 和 promote。对文件系统进行的写入优先使用 foreground,然后随着时间推移移动至 background。对文件系统的读取会缓存在 promote 上。metadata 目标通常与超低读取延迟的 NVMe 驱动器一起使用,例如 Intel Optane

注意:这只是对一个单一储存池而言的优先级。如果 foreground 满了,则系统会直接向 background 写入,或者如果两个都满了则会试着写入 promote。文件系统的元数据会优先写入 foreground,但也有可能会写入储存目标中的任意一个。在移除缓存设备时请小心,因为它们可能仍旧储存了数据。请参见 #移除设备

推荐的一种配置是使用一组 SSD 作为 foreground 和 promote,使用一组 HDD 作为 background(也就是回写缓存)。

# bcachefs format \
    --label=ssd.ssd1 /dev/sdA \
    --label=ssd.ssd2 /dev/sdB \
    --label=hdd.hdd1 /dev/sdC \
    --label=hdd.hdd2 /dev/sdD \
    --label=hdd.hdd3 /dev/sdE \
    --label=hdd.hdd4 /dev/sdF \
    --replicas=2 \
    --foreground_target=ssd \
    --promote_target=ssd \
    --background_target=hdd
# mount -t bcachefs /dev/sdA:/dev/sdB:/dev/sdC:/dev/sdD:/dev/sdE:/dev/sdF /mnt

如果想配置直写缓存,和上面操作基本一致,不过要对每个 SSD 设备设置 --durability=0 device。 如果想配置绕写缓存,只需把 HDD 设为 foreground,把 SSD 设为 promote。

挂载

[编辑 | 编辑源代码]

默认的挂载方式是在 mount 指令中指定每个设备。

# mount -t bcachefs /dev/sdA:/dev/sdB:/dev/sdC:/dev/sdD:/

mount.bcachefs 支持通过 UUID 挂载文件系统,UUID 会在使用 bcachefs format 创建文件系统时显示。

# mount.bcachefs UUID=f66d108f-83d2-4679-b50b-7d5e710f6

配置

[编辑 | 编辑源代码]

这篇文章的某些内容需要扩充。

原因:缺少应该使用什么选项的细节。 (在 Talk:Bcachefs 中讨论)

大多数选项可以通过以下方式设置:

  • bcachefs format 期间
  • 在格式化后使用 bcachefs set-fs-option
  • 在挂载时通过 mount -o option=value
  • 或通过 sysfs,例如 echo X > /sys/fs/bcachefs/UUID/options/option

挂载选项会覆盖其他方法设置的选项,后者会将选项保存到文件系统的超级块中。

注意:要使用 sysfs 必须先挂载文件系统。除了 fsck 以外,所有的操作都可以在文件系统挂载状态下进行。

一些可用选项举例如下:

Bcachefs 选项
选项 描述
metadata_checksum 指定用于元数据写入的校验和 (checksum)算法。默认情况下,算法为 crc32c。可以从nonecrc32ccrc64xxhash中选择其一。
data_checksum 指定用于数据写入的校验和 (checksum)算法,与metadata_checksum具有相同的默认值和选项。
compression 指定用于(前台)压缩的算法。默认情况下此选项为none。可以从nonelz4gzipzstd中选择其一。
background_compression 指定用于后台压缩的算法,与compression具有相同的默认值和选项。
str_hash 指定用于directory entries和 xattrs 的哈希函数。可以从crc32ccrc64siphash中选择其一。
nocow 在可能的情况下,所有写入都将就地完成。快照 (snapshot) 和 reflink 仍会导致 COW 写入。该选项会隐式禁用数据校验、压缩和加密。
encrypted 启用文件系统加密(chacha20/poly1305);将提示输入密码。

更多选项可以在 bcachefs 文档中找到。

以下内容可以通过 bcachefs setattr file --option=value 按每个文件或目录进行设置。如果在一个目录中设置,它会进行递归传递。

注意:重新平衡线程目前为止不会在后台调整副本。也就是说,如果更改文件的副本选项,则必须手动运行 rereplicate 命令以确保旧文件遵循新规则。
  • 数据冗余数 (data_replicas)
  • 数据校验和 (data_checksum)
  • 前台压缩 (compression)、后台压缩 (background_compression)
  • 存储组配置:foreground_target、background_target、promote_target

要检查哪些选项处于活动状态,可以执行 getfattr -d -m 'bcachefs_effective\.' directory/file

注意:目前储存设备用量显示的是未压缩时的大小。除此之外,压缩功能一切正常。

更改设备所属储存组

[编辑 | 编辑源代码]

可以通过 sysfs 更改所属储存组:

# echo group.drive_name > /sys/fs/bcachefs/filesystem_uuid/dev-X/label
注意:需要重新挂载才能生效。

添加设备

[编辑 | 编辑源代码]
# bcachefs device add --label=group.drive_name /mnt /dev/device

若这是某储存组中的第一个设备,则需要修改储存目标的设置才能使用。以下例子添加了一个缓存设备。

# echo new_group > /sys/fs/bcachefs/filesystem_uuid/options/promote_target
# echo new_group > /sys/fs/bcachefs/filesystem_uuid/options/foreground_target
# echo old_group > /sys/fs/bcachefs/filesystem_uuid/options/background_target
注意:只有新的写入会被分散到新添加的设备中去。已经写入的内容不会改变,除非储存设备的占用达到一个阈值,从而触发重新平衡(rebalance/restripe)。目前无法手动触发重新平衡。

移除设备

[编辑 | 编辑源代码]

首先请确保至少设备上有两份元数据(设备移除(evacuate)功能似乎对元数据不奏效)。如果数据和元数据都已经有冗余了,可以跳过这一步。

# echo 2 > /sys/fs/bcachefs/UUID/options/metadata_replicas
# bcachefs data rereplicate /mnt
# bcachefs device set-state ro device
# bcachefs device evacuate device

将状态设置为 ro,表示只读。

若想移除设备:

# bcachefs device remove device
# bcachefs data rereplicate /mnt

冗余

[编辑 | 编辑源代码]

Bcachefs 中的元数据和数据的冗余级别可以独立配置,以控制数据冗余和持久性(durability)。 以下选项既定义了同步(即时)冗余,它会在写入时原子执行以确保数据完整;同时也定义了最终冗余目标(eventual replication target),其会在在后台异步完成以提高冗余和故障容忍度。

  • --replicas=X 设置元数据和数据副本的目标数量。
  • --metadata_replicas=X 设置在正常运行和重新平衡期间后台维护的元数据副本的目标数量。
  • --data_replicas=X 设置最终要维持的数据副本的目标数量。
  • --metadata_replicas_required=X 设置在元数据被视为已提交之前,必须同步写入的元数据副本的最小数量。
  • --data_replicas_required=X 设置在数据被视为已提交之前,必须同步写入的数据副本的最小数量。
注意: 区分 --[meta]data_replicas_required--[meta]data_replicas 非常重要,因为 _replicas_required 值设定了将被立即写入的副本数量的下限,而 _replicas 值设定了最终会写入的副本数量。可以将 _replicas_required 解释为如果我们只能完成这么多写入,文件系统依然能以降级模式(degraded)运行 [1]

压缩

[编辑 | 编辑源代码]

压缩通过 --compression= 选项设置,支持设置压缩级别。比如要设置 zstd 压缩并使用级别 5,可以使用 --compression=zstd:5

注意: 目前尚未实现多线程压缩。 [2]

子卷

[编辑 | 编辑源代码]

Bcachefs 支持使用与 Btrfs 类似的用户空间接口来管理子卷和快照。新子卷可以创建为空子卷,也可以是另一个子卷的快照。快照是可写的,并且可以多次快照,从而形成快照树。

创建快照的成本非常低:它们不像 Btrfs 那样基于 COW btree 的克隆,而是基于 btree 中单个键的版本控制。你可以创建成千上万个快照,唯一的限制是磁盘空间。

创建子卷

[编辑 | 编辑源代码]

创建一个新的空子卷:

# bcachefs subvolume create /path/to/subvolume

删除子卷

[编辑 | 编辑源代码]

删除已有的子卷或快照:

# bcachefs subvolume delete /path/to/subvolume

为现有子卷创建快照

[编辑 | 编辑源代码]

为现有子卷创建快照:

# bcachefs subvolume snapshot /path/to/source /path/to/dest

子卷在删除其中所有内容后也可以使用常规的 rmdir 删除,比如使用 rm -rf

递归快照创建和递归列出子卷等功能仍待实现。

提示和技巧

[编辑 | 编辑源代码]

这篇文章的某些内容需要扩充。

原因:关于自动挂载的内容可能会有些用处。 (在 Talk:Bcachefs 中讨论)

请查看 Systemd/Journal 以获取更多有用的错误信息。

标志顺序

[编辑 | 编辑源代码]

一些 bcachefs format 标志是根据其参数顺序设置的,并且仅影响切换标志后出现的驱动器。例如,如果希望 SSD 具有 --durability=0 并启用 --discard 而 HDD 使用默认值,请确保按以下顺序传递参数:

# bcachefs format \
    --label=hdd.hdd1 /dev/sdC \
    --label=hdd.hdd2 /dev/sdD \
    --label=hdd.hdd3 /dev/sdE \
    --label=hdd.hdd4 /dev/sdF \
    --durability=0 --discard \
    --label=ssd.ssd1 /dev/sdA \
    --label=ssd.ssd2 /dev/sdB \
    --replicas=2 \
    --foreground_target=ssd \
    --promote_target=ssd \
    --background_target=hdd

格式化后设置冗余

[编辑 | 编辑源代码]

可以使用 set-fs-option 在格式化后设置副本(冗余)数量。

# bcachefs set-fs-option --metadata_replicas=2 --data_replicas=2 /dev/sdX

之后需要让 bcachefs 确保所有文件都拥有副本,命令为:

# bcachefs data rereplicate /mnt


故障排除

[编辑 | 编辑源代码]

32 位程序无法查看目录内容

[编辑 | 编辑源代码]

部分 32 位程序可能无法获取 Bcachefs 目录中的内容,这是由于执行 readdir(3) syscall 时文件系统返回的数据不兼容所导致。[3]

要解决这个问题,可以暂时使用不同的文件系统供程序读写,比如 tmpfs

swapfile 包含空洞或其他不支持的扩展

[编辑 | 编辑源代码]

Bcachefs 目前不支持交换文件

多设备 fstab

[编辑 | 编辑源代码]

目前 systemd 存在一个 bug,导致无法在启动时通过在 fstab 中使用以冒号分隔的设备来挂载多设备 bcachefs 文件系统。使用 mount -a 时可以正常挂载,但在开机启动时不会挂载。不过自从 bcachefs-tools 版本 1.7.0 起,可以通过单个设备节点来挂载多设备阵列,从而允许使用正常的 UUID 指定方法。

# UUID=10176fc9-c4fa-4a30-9fd0-a756d861c4cd     /mnt   bcachefs defaults,nofail 0 0

可以通过以下任一命令找到文件系统 UUID / 外部 UUID:

# bcachefs fs usage /mnt
# bcachefs show-super /dev/sdXY


挂载加密设备错误

[编辑 | 编辑源代码]

对于使用 --encrypted 选项创建的设备,当 bcachefs unlock /dev/sdXY 后挂载失败时,出现

ERROR - bcachefs::commands::cmd_mount: Fatal error: Required key not available

可以通过手动将密钥链接到会话来解决这个问题[4]

# keyctl link @u @s
# mount /dev/sdXY /mnt
Enter passphrase:

不需要输入 mount 要求的密码(按回车键即可)。

另请参阅

[编辑 | 编辑源代码]