坑边闲话:这篇文章属于临时起意,后来发现技术上有严重问题。如果你看到这句话,说明问题没有被纠正,请带着批判的眼神来看。

此前我在视频里提到 BV1iAPgexEi6 里提到可以使用 Alist/CloudDrive/Rclone/Raidirve 这种网盘工具把网络盘挂载到本地,实现云盘本地化使用。现在我感觉有点过于理想了。

想说的东西很多,今天这篇专栏就当作打草稿,读者且来批判性观看。

1. CD2 的缓存模型·

任何读写模型都有流控机制,哪怕是本地的 PCIe NVMe 硬盘,也会借助 PCIe 协议的 Credit-Based Flow Control 做流控。当然,这不同于 TCP 的滑动窗口,PCIe 流控协议更倾向于低延迟,目标是防止缓冲区溢出。

所以按照这个观点来看,我们的 PC 透过 cd2 往网盘写入数据,cd2 在接收本地的写入请求时,也需要有一个缓存、流控协议,防止本地的文件浏览器或者 rsync 这种 sender 把 cd2 的缓存写爆。

今天我发现一个有趣的现象,cd2 有一个缓存机制:

图 1. CloudDrive2 的临时文件路径。

我一般把它放到 C:\Windwos\temp 目录下,这是标准的 Windows 缓存目录。

1.1 FreeFileSync 进行写入·

我们可以借助文件浏览器、FFS、rsync 等软件将本地文件同步到网盘,这很好。

以 FFS 为例,往云端挂载路径的写入请求,被 cd2 缓存下来,cd2 的缓存写入成功之后,cd2 会立即给 FFS 反馈写入成功。然而,实际上的云存储里并没有写入数据。这当然属于缓存一致性问题。只不过我们知道,在网络良好的情况下,缓存一致性终究会得到解决,但是一定要注意,一定一定要人工确认 cd2 后台的队列干净之后再删除、清理本地的备份,否则一旦 cd2 缓存实效就欲哭无泪了!

可怕的是,我发现 cd2 没有做缓存控制算法,如果传输大量文件,cd2 会尽可能地去填满缓存目录,直到把系统盘 C:\ 写爆,此后会发生什么,我只能说画面太美,不敢想象。

可能 cd2 比较自信,认为用户上传的文件基本都是可以秒传,只要哈希算得够快,缓存就可以及时清理。然而,对于我自己压缩的备份文件,秒传是不可能的,于是就产生了这样的问题。

2. 怎么解决问题·

其实 cd2 有一个内部解决方案,那就是不管缓存容量,而是只管理队列!

这个很简单粗暴,我们可以在后台把 transfer 队列容量设置得尽可能小,preprocessing 也尽可能小,这样发送队列就会小,缓存占用也会少。

只有一种情况我不知道会不会出问题,那就是单一文件体积过大,大过了缓冲区容量。这时候是否会回退到无缓冲机制?我就不知道了,毕竟 cd2 是不开源的软件。

文件级别的缓存就是这么离谱,只有真正的块级别缓存才好使。粒度过粗总是面临问题。

那么解决思路就很简单了。

首先是本地的 cd2,何必使用文件级别的缓存呢?直接把文件缓存优化为文件指针构成的队列不就行了?其实也没有这么简单

cd2 保留真实缓存的目的很简单,那就是尽可能保证数据一致性。因为发送端有可能重复提交修改过的文件,这时候保留文件指针就必须加文件锁,加锁在文件同步中是大忌讳!

比如对于文件 F,我们一分钟一个版本,F1 F2 F3 …

上传的时候就需要保证云端也能依次接收这些版本。如果上锁,那么在传输 F1 的过程中,就不能编辑 F,导致生产线收到阻塞。拷贝 F1 到缓存是一个很合适的方案。

大部分系统是不支持文件快照的,如果可以对文件拍快照,那么就可以无锁了。

3. 两难的局面·

所以两难的局面出现了。

第一,拷贝机制需要进行对发送者进行干预,比如通过不给 sender 发送提交成功的信号进而阻塞发送队列。这是一个好方法,可以保护缓冲区不被写爆。但是发送者迟迟不能提交也会阻塞进程。当然,这对备份场景是毫无影响,这也是我认为比较理想的局面。但是难以应付非备份场景,频繁提交。

第二,文件指针替代缓存。这对与备份也是很合适的,甚至比第一种要好,它可以优化缓存设备的寿命。不得不感叹备份真是太好伺候了。然而在真实场景下这种机制就是灾难,同步上锁等待网络传输,想想就难受!

4. 期待·

据我推测,cd2 应该是保留了两级流水:

第一级:秒传哈希计算,sender 发过来的所有东西都先在内存里计算一次哈希(毕竟哈希计算很快,数百MB/s),不入本地缓存,然后「应秒尽秒」,期待文件不要走到接下来的流水线上;(这个可以用一个云端文件试一试,一验证便知晓!)

第二级:若第一级哈希计算没有命中云端数据,就会写入本地缓存,等待上传。流水一直走,直到缓存写爆,接下来发生什么就不得而知了。当然,我没有做极限测试,因为任由服务器写爆 C:\ 是很危险的,有可能无法开机,所以我只观测到 512GB 的 C 盘仅剩 40GB 到 80GB 可用空间就停了。

希望 cd2 尽快优化缓冲区机制,现在肆意写缓冲区,实在是太吓人了。

That’s all.