通常情况下,NAS 用户都会使用 RAID 来扩展硬盘,但 RAID 的扩展和使用都略有不便,不同 Level 的 RAID 的选择,扩展时需要同时扩展足够的硬盘,以及更换硬盘的重建等等。

注意:RAID 不是备份,RAID 只能保障不停机,备份需要遵守数据 321 原则!

我一开始使用的也是 RAID,但有次硬盘坏了一个,是 SATA 线送了,导致 RAID 一直在重建,根本没办法使用,而且我只有一块校验盘,如果此时再坏一块盘,数据就全部都没了。

由于我上面存放的都是电影和动漫,没了可以再下,但会有很长时间慢慢重新攒资源,挺麻烦的。

有次同事推荐使用 mergerfs,可以将做个硬盘按目录级别进行合并,我想着和 overlay 差不多嘛,就了解了下,感觉还不错,趁着最近有心情写博客,记录一下配置文件。

首先我使用的是 debian 12 的系统,仓库里已经有 mergerfs 的包了,使用别的系统的话,也可以去 release 里下载打包好的,或者使用 docker 运行。

mergerfs 的 wiki 给出了一套 systemd 的方案,我就拿来直接用了。

创建 prepare 服务

创建脚本 /usr/local/bin/prepare-for-mergerfs

#!/usr/bin/env sh

# Setup things
# Wait for things
/bin/sleep 10

# Report back to systemd that things are ready
/bin/systemd-notify --ready

创建服务 /etc/systemd/system/prepare-for-mergerfs.service

[Unit]
Description=Dummy mount service

[Service]
Type=notify
RemainAfterExit=yes
ExecStart=/usr/local/bin/prepare-for-mergerfs

[Install]
WantedBy=default.target

这个服务的作用是首次启动时,等待 10 秒向 systemd 报告启动完成。

创建 mergerfs 服务

创建服务 /etc/systemd/system/mergerfs.service

[Unit]
Description=Dummy mergerfs service
Requires=prepare-for-mergerfs.service
After=prepare-for-mergerfs.service

[Service]
Type=simple
KillMode=none
ExecStart=/usr/bin/mergerfs \
-f \
-o defaults \
-o cache.files=partial \
-o fsname=mergerfs \
-o allow_other \
-o use_ino \
-o category.create=mfs \
-o dropcacheonclose=false \
-o moveonenospc=true \
-o posix_acl=true \
-o func.getattr=newest \
/media-1:/media-2:/media-3:/media-4:/media-5 \
/mnt/merger
ExecStop=/bin/fusermount -uz /mnt/merger
Restart=on-failure

[Install]
WantedBy=default.target

这里简单说一下参数,mergerfs [options]

需要合并的目录使用冒号分割 /media-1:/media-2,这些都是独立的分区,有着不一样的文件系统,有的是 zfs,有的是 ext4,mergerfs 不需要关心,因为挂载后都是内核在操作。

绝大部分情况下,都不需要修改 mergerfs 的 options,但有几个需要留意。

cache.files

控制文件的缓存模式,可选的值有

  1. libfuse
  2. off
  3. partial
  4. full
  5. auto-full
  6. per-process

默认是 libfuse。

fsname

设置文件系统的名称,如在 mount、df 等中所见。默认为连接在一起的源路径列表,并删除最长的公共前缀。

allow_other

该选项废弃,如果以 root 身份运行,mergerfs v2.35.0 及更高版本会自动设置此 FUSE 选项。但由于我使用的是 v2.33,所以还需要保留该选项。

点击查看废弃选项的文档