在使用 Rclone 通过 WebDAV 挂载 NAS 的过程中,你可能会遇到文件同步严重延迟、GNOME 文件管理器进度条”虚假完成”等问题。本文将深入分析这些问题的根因——WebDAV 后端的三重缺陷,并给出完整的优化方案,同时对 SFTP 挂载服务进行缓存策略统一和参数调优。

教程概述

本文记录了对三个 Rclone 挂载服务的全面优化过程,内容包括:

  • 问题现象:NAS 同步延迟、GNOME 进度条显示不一致、缓存目录分散
  • 根因分析:WebDAV 后端的 modtime / 哈希 / 变更通知三重缺陷
  • 优化策略:缓存周期调整、RC API 即时刷新、缓存目录统一
  • 配置变更:三个 systemd 服务的逐项参数对比和修改说明
  • 验证结果:优化前后的效果对比和持续运行验证

环境信息

项目 配置
操作系统 Ubuntu 24.04 LTS
内核版本 6.17.0-14-generic
Rclone 版本 v1.72.0
存储架构 双 NVMe 通过 mergerfs 组成 3.7T 存储池

涉及的挂载服务

服务名 协议 远端 挂载点
rclone-nas WebDAV 192.168.5.5:5005 (NAS) /mnt/nas
rclone-lxd SFTP 172.20.73.2:28888 (glm-lxd) /mnt/lxd
rclone-h20 SFTP 172.20.72.102:22 (H20) /mnt/h20

一、问题现象

在日常使用中,这套 Rclone 挂载体系暴露出三个主要问题:

1. NAS 同步延迟严重

当 NAS(192.168.5.5)上的文件被其他设备修改后,在 Linux 的 /mnt/nas 挂载点中无法及时看到变更,通常需要等待数小时甚至更久才能刷新。

2. GNOME 桌面传输显示不一致

通过 GNOME 文件管理器从 Linux 向 NAS 拖拽文件时,进度条显示已传输完毕,但实际上仍有持续的上传流量在跑。前端显示与后端实际传输严重不匹配。

3. 缓存目录不统一

NAS 服务使用 /mnt/data/.rclone_cache(mergerfs 大容量存储池),而 lxd 和 h20 服务使用 /home/cpu/.cache/rclone/(系统盘),缓存分散在不同磁盘上,管理不便且可能占满系统盘。

存储架构概览

1
2
3
4
5
6
7
8
9
10
11
12
nvme0n1 (1.9T) -> /mnt/disk1 ─┐
├─ mergerfs -> /mnt/data (3.7T)
nvme2n1 (1.9T) -> /mnt/disk2 ─┘
├── .rclone_cache/ <- 统一缓存目录
│ ├── vfs/ <- NAS 缓存
│ ├── lxd/ <- lxd 缓存(新增)
│ └── h20/ <- h20 缓存(新增)
├── project/ <- 工作目录
└── ...

nvme1n1 (1.9T) -> / (系统盘)
└── /home/cpu/.cache/rclone/ <- 旧的 lxd/h20 缓存(已弃用)

二、根因分析

1. WebDAV 后端的致命缺陷

通过以下命令获取 NAS WebDAV 后端的特性信息:

1
rclone backend features nas:

关键输出:

1
2
3
4
5
{
"Precision": 3153600000000000000,
"Hashes": [],
"ChangeNotify": false
}

输出解读:

特性 含义
Precision 3153600000000000000 ns (~100 年) 文件修改时间精度约 100 年,完全无法用于变更检测
Hashes [] (空) 不支持任何哈希校验(md5/sha1 等均不支持)
ChangeNotify false 不支持服务端变更推送通知

Rclone 判断远端文件是否变更有三种机制,在 WebDAV 后端上全部失效

  1. modtime 比较:精度约 100 年,两次比较永远判为”相同” → 失效
  2. 哈希比较:Hashes 为空,无法计算 → 失效
  3. 变更通知:ChangeNotify 为 false → 失效

唯一残留的检测手段是文件大小比较,但如果文件内容变了而大小没变,Rclone 完全无法感知。

2. 旧配置如何加剧同步延迟

旧配置中的关键参数:

1
2
3
--vfs-cache-mode full      # 读写都经过本地缓存
--vfs-cache-max-age 24h # 缓存保留 24 小时
--dir-cache-time 30s # 目录列表缓存 30 秒

full 模式下,Rclone 读取文件时会先检查本地缓存:

  • 如果缓存存在且 modtime 对比认为”没有变化” → 直接返回本地缓存(不访问远端)
  • 由于 modtime 精度约 100 年 → Rclone 永远认为”没有变化”
  • 因此缓存中的旧文件在 --vfs-cache-max-age 24h 到期前永远不会被刷新

最坏情况:NAS 上文件被修改后,在 Linux 端最多需要等待 24 小时 才能看到新内容。

3. GNOME 进度条不一致的原因

--vfs-cache-mode full 下,文件写入的完整流程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
用户拖拽文件到 /mnt/nas/


GNOME 调用 write() 写入 FUSE 挂载点


Rclone VFS 层将数据写入本地 SSD 缓存 (/mnt/data/.rclone_cache/)
│ ← 这一步是 SSD 速度,极快

GNOME 收到 write() 返回成功 → 显示进度 100%

▼ (后台异步)
Rclone 从本地缓存上传到 NAS (受千兆网络速度限制)
│ ← 这一步是网络速度,较慢

实际传输完成(但 GNOME 早已关闭进度条)

GNOME 文件管理器看到的是”写入 FUSE 挂载点”的速度(SSD 速度),而不是”上传到 NAS”的真实网络速度。这是 FUSE 异步写入缓存的固有行为,无法完全消除,但可以通过 --vfs-write-back 参数缩小时间差。

4. SFTP 后端对比

通过 rclone backend features h20: 确认 SFTP 后端的特性:

1
2
3
4
5
{
"Precision": 1000000000,
"Hashes": ["md5", "sha1"],
"ChangeNotify": false
}
特性 WebDAV (NAS) SFTP (lxd/h20)
modtime 精度 ~100 年 (无效) 1 秒 (精确)
哈希支持 md5, sha1
变更通知 不支持 不支持
变更检测能力 仅靠文件大小 modtime + 哈希 + 文件大小

SFTP 后端的 modtime 精确到 1 秒,且支持 md5/sha1 哈希,变更检测机制完全正常。因此 lxd/h20 不存在 NAS 那样的同步延迟问题,优化重点在于统一缓存目录微调参数


三、优化策略设计

三目标权衡

三个核心目标之间存在固有的”不可能三角”:

  • 同步实时性 vs 传输效率:缓存越短越实时,但缓存命中率越低
  • 传输效率 vs 前端显示一致性:异步上传让前端感觉快(但显示不真实),同步上传让前端等网络
  • 前端显示一致性 vs 同步实时性:要显示真实进度就不能走本地缓存,但不走缓存会牺牲写入体验

最终方案

**NAS (WebDAV)**:保留 full 缓存模式(维持写入流畅性和读取缓存加速),但将缓存过期时间从 24 小时大幅缩短到 5 分钟,同时启用 RC API 支持手动即时刷新。

**lxd / h20 (SFTP)**:保持 writes 缓存模式(SFTP 有精确 modtime,读取不需要缓存),统一缓存目录到 mergerfs 大容量存储,微调参数。


四、配置修改

1. 备份原配置

在修改前,先备份所有原始配置文件:

1
2
3
sudo cp /etc/systemd/system/rclone-nas.service /etc/systemd/system/rclone-nas.service.bak.20260308
sudo cp /etc/systemd/system/rclone-lxd.service /etc/systemd/system/rclone-lxd.service.bak.20260308
sudo cp /etc/systemd/system/rclone-h20.service /etc/systemd/system/rclone-h20.service.bak.20260308

命令解释:

  • sudo cp ... .bak.20260308:将原始 service 文件备份,文件名带日期后缀,方便日后回滚

2. 修改 rclone-nas.service

文件路径:/etc/systemd/system/rclone-nas.service

修改前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ExecStart=/usr/bin/rclone mount nas:/ /mnt/nas \
--config /home/cpu/.config/rclone/rclone.conf \
--allow-other \
--umask 002 \
--log-level INFO \
--log-file /home/cpu/rclone-nas.log \
--cache-dir /mnt/data/.rclone_cache \
--vfs-cache-mode full \
--vfs-cache-max-size 200G \
--vfs-cache-max-age 24h \
--buffer-size 256M \
--vfs-read-chunk-size 128M \
--vfs-read-chunk-size-limit off \
--transfers 8 \
--checkers 16 \
--dir-cache-time 30s

修改后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ExecStart=/usr/bin/rclone mount nas:/ /mnt/nas \
--config /home/cpu/.config/rclone/rclone.conf \
--allow-other \
--umask 002 \
--log-level INFO \
--log-file /home/cpu/rclone-nas.log \
--cache-dir /mnt/data/.rclone_cache \
--vfs-cache-mode full \
--vfs-cache-max-size 100G \
--vfs-cache-max-age 5m \
--vfs-write-back 5s \
--buffer-size 256M \
--vfs-read-chunk-size 128M \
--vfs-read-chunk-size-limit off \
--dir-cache-time 15s \
--attr-timeout 1s \
--no-modtime \
--rc

同时修改 ExecStop,添加 -z 懒卸载标志:

1
2
3
4
5
# 修改前
ExecStop=/bin/fusermount3 -u /mnt/nas

# 修改后
ExecStop=/bin/fusermount3 -uz /mnt/nas

参数变更详解

参数 修改前 修改后 说明
--vfs-cache-max-size 200G 100G 缓存寿命短了,不需要那么大
--vfs-cache-max-age 24h 5m 核心变更:最大同步延迟从 24 小时降至 5 分钟,改善 288 倍
--dir-cache-time 30s 15s 目录列表刷新间隔缩短一半
--transfers 8 (移除) 该参数是 Copy Flag,对 mount 命令无效
--checkers 16 (移除) 该参数是 Copy Flag,对 mount 命令无效
--vfs-write-back (默认 5s) 5s (显式) 写入后 5 秒开始上传,缩小 GNOME 进度条与实际传输的时间差
--attr-timeout (未设置) 1s FUSE 内核属性缓存仅 1 秒,提高文件属性实时性
--no-modtime (未设置) 新增 不依赖 modtime 做变更判断(因为精度约 100 年,完全无效)
--rc (未设置) 新增 启用远程控制 API(localhost:5572),支持手动即时刷新缓存
ExecStop -u -uz 添加懒卸载标志,避免有进程占用时停止服务失败

3. 修改 rclone-lxd.service

文件路径:/etc/systemd/system/rclone-lxd.service

修改前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ExecStartPre=/bin/mkdir -p /home/cpu/.cache/rclone/lxd

ExecStart=/usr/bin/rclone mount lxd:/home/cpu/research /mnt/lxd \
--config /home/cpu/.config/rclone/rclone.conf \
--allow-other \
--umask 002 \
--log-level INFO \
--log-file /home/cpu/rclone-lxd.log \
--cache-dir /home/cpu/.cache/rclone/lxd \
--vfs-cache-mode writes \
--vfs-cache-max-size 20G \
--vfs-cache-max-age 1h \
--buffer-size 64M \
--vfs-read-ahead 128M \
--sftp-chunk-size 255K \
--sftp-idle-timeout 2m \
--dir-cache-time 30s \
--attr-timeout 1s

修改后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ExecStartPre=/bin/mkdir -p /mnt/data/.rclone_cache/lxd

ExecStart=/usr/bin/rclone mount lxd:/home/cpu/research /mnt/lxd \
--config /home/cpu/.config/rclone/rclone.conf \
--allow-other \
--umask 002 \
--log-level INFO \
--log-file /home/cpu/rclone-lxd.log \
--cache-dir /mnt/data/.rclone_cache/lxd \
--vfs-cache-mode writes \
--vfs-cache-max-size 50G \
--vfs-cache-max-age 1h \
--vfs-write-back 5s \
--buffer-size 128M \
--vfs-read-ahead 128M \
--sftp-chunk-size 255K \
--sftp-idle-timeout 2m \
--dir-cache-time 15s \
--attr-timeout 1s \
--rc --rc-addr localhost:5573

参数变更详解

参数 修改前 修改后 说明
--cache-dir /home/cpu/.cache/rclone/lxd /mnt/data/.rclone_cache/lxd 统一到 mergerfs 大容量存储,不再占用系统盘
--vfs-cache-max-size 20G 50G 大容量存储上可以给更多缓存空间
--buffer-size 64M 128M 增大缓冲区,提升大文件传输性能
--dir-cache-time 30s 15s 目录列表更快刷新
--vfs-write-back (未设置) 5s 写入后 5 秒开始上传
--rc --rc-addr (未设置) localhost:5573 启用 RC API(端口 5573,避免与 NAS 冲突)

4. 修改 rclone-h20.service

文件路径:/etc/systemd/system/rclone-h20.service

修改前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ExecStartPre=/bin/mkdir -p /home/cpu/.cache/rclone/h20

ExecStart=/usr/bin/rclone mount h20:/home_zfs/gaoliming/research /mnt/h20 \
--config /home/cpu/.config/rclone/rclone.conf \
--allow-other \
--umask 002 \
--log-level INFO \
--log-file /home/cpu/rclone-h20.log \
--cache-dir /home/cpu/.cache/rclone/h20 \
--vfs-cache-mode writes \
--vfs-cache-max-size 20G \
--vfs-cache-max-age 1h \
--buffer-size 64M \
--vfs-read-ahead 128M \
--sftp-chunk-size 255K \
--sftp-idle-timeout 2m \
--dir-cache-time 30s \
--attr-timeout 1s

修改后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ExecStartPre=/bin/mkdir -p /mnt/data/.rclone_cache/h20

ExecStart=/usr/bin/rclone mount h20:/home_zfs/gaoliming/research /mnt/h20 \
--config /home/cpu/.config/rclone/rclone.conf \
--allow-other \
--umask 002 \
--log-level INFO \
--log-file /home/cpu/rclone-h20.log \
--cache-dir /mnt/data/.rclone_cache/h20 \
--vfs-cache-mode writes \
--vfs-cache-max-size 50G \
--vfs-cache-max-age 1h \
--vfs-write-back 5s \
--buffer-size 128M \
--vfs-read-ahead 128M \
--sftp-chunk-size 255K \
--sftp-idle-timeout 2m \
--dir-cache-time 15s \
--attr-timeout 1s \
--rc --rc-addr localhost:5574

变更内容与 lxd 一致(缓存目录迁移 + 参数统一),RC API 端口为 5574。


五、重启服务与验证

1. 重启所有服务

1
2
3
4
sudo systemctl daemon-reload
sudo systemctl restart rclone-nas
sudo systemctl restart rclone-h20
sudo systemctl restart rclone-lxd

命令解释:

  • daemon-reload:通知 systemd 重新读取所有 service 文件
  • restart:依次重启三个 Rclone 挂载服务,使新配置生效

2. 检查服务状态

服务 状态 说明
rclone-nas active (running) 正常运行
rclone-h20 active (running) 正常运行
rclone-lxd activating (start) 远端 glm-lxd 容器未开机,非本次修改导致

3. 验证挂载点

1
mount | grep fuse.rclone

预期输出:

1
2
nas: on /mnt/nas type fuse.rclone (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000,allow_other)
h20:/home_zfs/gaoliming/research on /mnt/h20 type fuse.rclone (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000,allow_other)

NAS 和 H20 挂载点正常可访问,目录列表正常。

4. 验证 RC API

1
2
3
rclone rc vfs/stats                          # NAS (localhost:5572)
rclone rc vfs/stats --rc-addr localhost:5574 # H20
rclone rc vfs/forget # NAS 缓存刷新

三个端口均正常响应。

5. 验证缓存目录

1
ls /mnt/data/.rclone_cache/

预期输出:

1
vfs  vfsMeta  lxd  h20

三个服务的缓存已统一到 /mnt/data/.rclone_cache/ 下。


六、RC API 手动刷新用法

三个服务均启用了 RC API,当需要临时绕过缓存立即查看远端最新文件时,可以使用以下命令:

1
2
3
4
rclone rc vfs/forget                            # 刷新 NAS (localhost:5572)
rclone rc vfs/forget --rc-addr localhost:5573 # 刷新 lxd
rclone rc vfs/forget --rc-addr localhost:5574 # 刷新 h20
rclone rc vfs/stats # 查看 NAS 缓存状态

命令解释:

  • vfs/forget:清除 VFS 层的所有缓存元数据,下次访问时强制从远端重新读取
  • vfs/stats:查看当前缓存状态(缓存大小、文件数量等)
  • --rc-addr:指定目标服务的 RC API 地址(默认是 localhost:5572)

各服务的 RC API 端口分配:

服务 RC 端口
rclone-nas localhost:5572(默认)
rclone-lxd localhost:5573
rclone-h20 localhost:5574

七、优化效果总结

NAS 同步延迟改善

指标 修改前 修改后 改善幅度
缓存最大寿命 24 小时 5 分钟 288x
目录列表刷新 30 秒 15 秒 2x
文件属性缓存 未限制 1 秒 -
手动即时刷新 不支持 RC API 支持 从无到有
最坏同步延迟 ~24 小时 ~5 分 15 秒 275x

缓存目录统一

服务 修改前 修改后
rclone-nas /mnt/data/.rclone_cache /mnt/data/.rclone_cache(不变)
rclone-lxd /home/cpu/.cache/rclone/lxd /mnt/data/.rclone_cache/lxd
rclone-h20 /home/cpu/.cache/rclone/h20 /mnt/data/.rclone_cache/h20

全部统一到 mergerfs 存储池(两块 NVMe 共 3.7T),避免占用系统盘空间。


八、已知限制与后续建议

仍然存在的限制

  1. GNOME 进度条仍然不完全准确full 缓存模式下写入先落到本地 SSD,GNOME 看到的是 SSD 速度而非网络速度。这是 FUSE 异步写入的固有行为。要观察真实上传进度,可以通过 tail -f ~/rclone-nas.log 查看日志。

  2. 同大小文件修改检测:NAS WebDAV 不支持 modtime 和哈希,如果文件内容变了但大小没变,仍然需要等 5 分钟缓存过期后才能检测到。需要即时刷新时使用 rclone rc vfs/forget

  3. lxd 服务依赖远端容器:glm-lxd 容器未开机时,rclone-lxd 服务会持续重启。这是正常行为,不影响其他服务。

长期建议

如果 NAS 支持 SMB/CIFS 协议,建议考虑切换,原因包括:

  • SMB 有精确到秒的 modtime 支持
  • Linux 内核原生 CIFS 驱动,无 FUSE 层开销
  • 支持 inotify 文件变更通知
  • 前端显示与传输完全同步(无异步缓存层)

旧缓存清理

lxd 和 h20 原来的缓存目录 /home/cpu/.cache/rclone/(位于系统盘 nvme1n1)已在验证新配置正常运行后删除(92K,仅含空目录结构)。所有缓存现已统一存放在 /mnt/data/.rclone_cache/(mergerfs 存储池)下。


九、回滚方法

如需回滚到旧配置:

1
2
3
4
5
sudo cp /etc/systemd/system/rclone-nas.service.bak.20260308 /etc/systemd/system/rclone-nas.service
sudo cp /etc/systemd/system/rclone-lxd.service.bak.20260308 /etc/systemd/system/rclone-lxd.service
sudo cp /etc/systemd/system/rclone-h20.service.bak.20260308 /etc/systemd/system/rclone-h20.service
sudo systemctl daemon-reload
sudo systemctl restart rclone-nas rclone-lxd rclone-h20

命令解释:

  • cp ... .bak.20260308 ...:将备份文件还原覆盖当前配置
  • daemon-reload + restart:重新加载配置并重启服务

附录:完整的优化后配置文件

rclone-nas.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[Unit]
Description=Rclone Mount for NAS WebDAV
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
User=cpu
Group=cpu

ExecStartPre=/bin/mkdir -p /mnt/data/.rclone_cache

ExecStart=/usr/bin/rclone mount nas:/ /mnt/nas \
--config /home/cpu/.config/rclone/rclone.conf \
--allow-other \
--umask 002 \
--log-level INFO \
--log-file /home/cpu/rclone-nas.log \
--cache-dir /mnt/data/.rclone_cache \
--vfs-cache-mode full \
--vfs-cache-max-size 100G \
--vfs-cache-max-age 5m \
--vfs-write-back 5s \
--buffer-size 256M \
--vfs-read-chunk-size 128M \
--vfs-read-chunk-size-limit off \
--dir-cache-time 15s \
--attr-timeout 1s \
--no-modtime \
--rc

ExecStop=/bin/fusermount3 -uz /mnt/nas
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

rclone-lxd.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[Unit]
Description=Rclone Mount for glm-lxd SFTP
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
User=cpu
Group=cpu

ExecStartPre=/bin/mkdir -p /mnt/data/.rclone_cache/lxd

ExecStart=/usr/bin/rclone mount lxd:/home/cpu/research /mnt/lxd \
--config /home/cpu/.config/rclone/rclone.conf \
--allow-other \
--umask 002 \
--log-level INFO \
--log-file /home/cpu/rclone-lxd.log \
--cache-dir /mnt/data/.rclone_cache/lxd \
--vfs-cache-mode writes \
--vfs-cache-max-size 50G \
--vfs-cache-max-age 1h \
--vfs-write-back 5s \
--buffer-size 128M \
--vfs-read-ahead 128M \
--sftp-chunk-size 255K \
--sftp-idle-timeout 2m \
--dir-cache-time 15s \
--attr-timeout 1s \
--rc --rc-addr localhost:5573

ExecStop=/bin/fusermount3 -uz /mnt/lxd
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

rclone-h20.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[Unit]
Description=Rclone Mount for PianLab-CPU-HPC SFTP (H20)
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
User=cpu
Group=cpu

ExecStartPre=/bin/mkdir -p /mnt/data/.rclone_cache/h20

ExecStart=/usr/bin/rclone mount h20:/home_zfs/gaoliming/research /mnt/h20 \
--config /home/cpu/.config/rclone/rclone.conf \
--allow-other \
--umask 002 \
--log-level INFO \
--log-file /home/cpu/rclone-h20.log \
--cache-dir /mnt/data/.rclone_cache/h20 \
--vfs-cache-mode writes \
--vfs-cache-max-size 50G \
--vfs-cache-max-age 1h \
--vfs-write-back 5s \
--buffer-size 128M \
--vfs-read-ahead 128M \
--sftp-chunk-size 255K \
--sftp-idle-timeout 2m \
--dir-cache-time 15s \
--attr-timeout 1s \
--rc --rc-addr localhost:5574

ExecStop=/bin/fusermount3 -uz /mnt/h20
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target