14 个版本 (7 个破坏性版本)
0.10.3 | 2023年12月25日 |
---|---|
0.10.2 | 2023年11月1日 |
0.10.1 | 2023年10月3日 |
0.10.0 | 2023年7月10日 |
0.6.1 | 2019年10月21日 |
#209 在 文件系统
每月69 次下载
96KB
2K SLoC
SCFS – SplitCatFS
一个便捷的分割和连接文件系统。
动机
历史
在设置基于云的备份和归档解决方案时,我遇到了以下现象:许多小文件上传得相当快,并且 – 取决于实际的云存储提供商 – 高度并发,而大文件往往会减慢整个过程。解释很简单,许多云存储提供商不支持单个文件的并发或分块上传,有时甚至不支持恢复部分上传。您需要一次性上传,按顺序一个字节一个字节,要么全有,要么全无。
现在考虑一种情况,您上传一个巨大的文件,比如包含系统和配置的Raspberry Pi SD卡的镜像。我有一个这样的文件,大约有4GB大。现在,在备份我的系统时,这是最后一个要上传的文件。根据预计时间计算,这需要几个小时,所以我让它过夜。第二天早上我发现,在上传过程大约95%的时候,我的互联网连接突然中断了几秒钟,但足以让传输工具中断上传。临时文件从云存储中删除,所以我不得不重新从零开始。几个小时的上传时间浪费了。
我想到了一种方法来分割大文件,以便我可以更有效地上传它们,但最终得出结论,手动分割文件、上传它们并在本地删除它们不是一种非常可扩展的解决方案。
因此,我想出了一个特殊文件系统的想法。一个将大文件呈现为许多单独文件中的小片段的文件系统。实际上,这些片段都会指向同一个物理文件,只是有不同的偏移量。这样我就可以并行上传分块文件,而不会损失太多进度,即使上传过程中途中断。
SplitFS 就是这样诞生的。
如果我下载这样的分块文件部分,我需要在之后调用 cat * >file
以重新创建实际文件。这似乎与手动分割文件一样麻烦。这就是为什么我在开发SCFS时也考虑了 CatFS。CatFS将透明地连接分块文件,并将它们再次呈现为完整文件。
为什么 Rust?
我相对较新接触Rust语言,我认为,要想深入理解Rust,最好的方式是承担一个需要投入时间和对语言有一定了解的项目。
安装
SCFS可以通过Cargo轻松安装,通过crates.io
cargo install scfs
使用
Usage: scfs <COMMAND>
Commands:
split Create a splitting file system
cat Create a concatenating file system
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
SplitFS
Usage: scfs split [OPTIONS] <MIRROR> <MOUNTPOINT> [-- <FUSE_OPTIONS_EXTRA>...]
Arguments:
<MIRROR> Defines the directory that will be mirrored
<MOUNTPOINT> Defines the mountpoint, where the mirror will be accessible
[FUSE_OPTIONS_EXTRA]... Additional options, which are passed down to FUSE
Options:
-b, --blocksize <BLOCKSIZE> Sets the desired blocksize [default: 2097152]
-o, --fuse-options <FUSE_OPTIONS> Additional options, which are passed down to FUSE
-d, --daemon Run program in background
--mkdir Create mountpoint directory if it does not exist already
-h, --help Print help
-V, --version Print version
要使用SplitFS挂载目录,请使用以下格式
scfs split <base directory> <mount point>
这可以通过使用专门的splitfs
二进制文件来简化
splitfs <base directory> <mount point>
指定的挂载点
目录将反映基础目录
的内容,将每个常规文件替换为包含该文件枚举分块的目录作为单独的文件。
可以使用自定义的块大小来处理文件片段。例如,要使用1 MB块而不是默认的2 MB大小,您可以使用
splitfs --blocksize=1048576 <base directory> <mount point>
其中1048576等于1024 * 1024,即1兆字节。
您甚至可以利用Shell的计算能力,例如在Bash中
splitfs --blocksize=$((1024 * 1024)) <base directory> <mount point>
自v0.9.0起新增:现在也可以用符号量词来指定块大小。允许的量词有“K”,“M”,“G”和“T”,每个量词都乘以1024。所以,为了设置与上面示例相同的1 MB块大小,现在可以这样做
splitfs --blocksize=1M <base directory> <mount point>
实际上,您甚至可以将块大小设置为1字节,但请做好准备,因为元数据表会变得非常大,可能需要处理大量的开销,甚至可能导致系统冻结。
CatFS
Usage: scfs cat [OPTIONS] <MIRROR> <MOUNTPOINT> [-- <FUSE_OPTIONS_EXTRA>...]
Arguments:
<MIRROR> Defines the directory that will be mirrored
<MOUNTPOINT> Defines the mountpoint, where the mirror will be accessible
[FUSE_OPTIONS_EXTRA]... Additional options, which are passed down to FUSE
Options:
-o, --fuse-options <FUSE_OPTIONS> Additional options, which are passed down to FUSE
-d, --daemon Run program in background
--mkdir Create mountpoint directory if it does not exist already
-h, --help Print help
-V, --version Print version
要使用CatFS挂载目录,请使用以下格式
scfs cat <base directory> <mount point>
这可以通过使用专门的catfs
二进制文件来简化
catfs <base directory> <mount point>
请注意,基础目录
必须是SplitFS生成的目录结构。否则,CatFS将拒绝挂载该目录。
指定的挂载点
目录将反映基础目录
的内容,将目录中的每个分块文件替换为单个文件。
额外的FUSE挂载选项
可以将额外的挂载选项传递给底层的FUSE库。
SCFS支持两种指定选项的方式,一种是使用“-o”选项,另一种是使用“--”分隔符后的额外参数。这与其他基于FUSE的文件系统如EncFS相一致。
这两个调用是等效的
scfs split -o nonempty mirror mountpoint
scfs split mirror mountpoint -- nonempty
当然,这些方法也适用于splitfs
和catfs
二进制文件。
守护进程模式
最初,SCFS旨在在前景运行。如果想要在同一个终端中继续工作,这会显得有些麻烦。当然,您可以使用Shell的功能将进程发送到后台,但这样您就有一个可能会在用户关闭终端时意外被杀死的后台进程。此外,SCFS最初在外部卸载时不会干净地终止。
自v0.9.0起,SCFS原生支持守护进程模式,即程序将其工作目录更改为"/"/"/"
,然后将其自身作为真正的守护进程进程派生出来,独立于运行中的终端。
splitfs --daemon mirror mountpoint
请注意,在更改工作目录之前,会解析mirror
和mountpoint
,因此它们仍然可以相对于当前工作目录给出。
要卸载,可以使用fusermount
fusermount -u mountpoint
限制
我认为这个项目已经不再是“原始原型”,我正在吃自己的狗粮,这意味着我正在将它们用于自己的备份策略,并基于个人需求创建功能。
然而,这可能无法满足典型用户的需求,如果没有反馈,我可能甚至不会考虑一些初始场景。
具体来说,这些是SCFS当前的限制
-
它应该在所有基于UNIX的系统上工作,如Linux和一些MacOS版本,但不包括MacOS特定的文件属性。但肯定不在Windows上,因为这需要处理系统调用的特殊处理,我还没有时间处理。
-
它只能与目录、常规文件和符号链接一起工作。其他文件类型(设备文件、管道等)将被静默忽略。
-
基础目录将在新的挂载点上以只读方式挂载,SCFS期望在挂载期间基础目录不会被修改。
依赖项
~25–34MB
~557K SLoC