一个真正的场景,在 S3 兼容存储中,存储大量小文件,这些小文件又会更新迭代,而且需要保持本地目录和 S3 同步(不然多点备份相当困难),而传统的修改、确定、删除、上传步骤极为繁琐和易错,尤其是需要修改的目录过多时。
没错,这就是 ZSFT FontsAPI 所面临的。
一直以来,都使用一个 GUI 工具来在本地进行操作,但其效率极低,图形界面的资源消耗太大,而 GUI ≈ 手动。所以尝试寻找一个 CLI 工具,这可能需要一定的门槛。
#开始
一个开源的 CLI —— Rclone 。
首先,在 rclone.org/downloads/ 下载它。
将下载的包解压到为它准备好的目录(目录完全自定义),这个目录同时需要被添加到系统变量中才能够随处执行,在 Windows® 中,在 设置 / 系统 / 系统信息 / 高级系统设置 / 环境变量 / Path 添加即可。
打开 CMD 或 PowerShell 尝试直接输入 rclone
,如果输出 help 内容,则安装已经完成。
#配置
安装完成后的首要任务,就是添加 S3 兼容存储,需要运行 rclone config
进入交互式会话,输入 n
来新建一个。文档位于:rclone.org/commands/rclone_config/。
或者尝试在 C:\Users\<USER>\AppData\Roaming\rclone\rclone.conf
直接编辑:
[example]
type = s3
provider = Other
access_key_id = <密钥 ID>
secret_access_key = <机密访问密钥>
endpoint = <S3 API 终结点/端点>
region = <地域>
一个例子:
[example]
type = s3
provider = Other
access_key_id = XXXXXXXXXXXXXXX
secret_access_key = XXXXXXXXXXXXXXXXXXXXXX
endpoint = https://s3.example.com
region = us-west-1
这时候,就可以使用 example: 来连接到这个端点。
#同步
Rclone 有一个极其强大的功能: rclone sync ,它可以自动对比本地到云端的差异文件,并视本地为最新版本,自动删除和上传云端的文件。
假设,我要将本地目录 D:\dist\ 和云端的 bucket/dist/ 进行对比尝试,一个简单的使用方法:
rclone sync "D:/dist" example:/bucket/dist --dry-run
因为添加了 --dry-run
,这段命令实际上什么也不会做,只是模拟了一下,如果要实际对比和将本地同步到云端,则去掉 --dry-run
。
#实用标识
--checksum
:启用哈希校验,在大多数情况下,启用此选项会提高 sync 效率和找出差异的准确率。因为直接比较元数据中的 Etag 相较于对比修改时间和文件大小更快、更准确。
--no-update-modtime
:忽略修改时间不同,如果启用哈希校验,则修改时间通常不再作为准确检测项。
--progress
:显示进度。
--verbose
:输出更多信息。
--transfers=16
:上传并行数,可根据设备线程数调整,以略微提高效率,默认为 4。
--checkers=32
:检查器并行数,可根据 I/O 调整,以略微提高检查效率,默认为 8。
--buffer-size=32Mi
:缓存大小,根据内容调整,可以略微减少 I/O ,默认为 16Mi 。
#止步于此?
编写一个自动同步指定子目录的 PowerShell 程序,因为如果同步整个桶,可能会遇到性能瓶颈。(除非文件并不多)
# rclonesync
param(
[Parameter(Mandatory, ValueFromRemainingArguments)]
[string[]]$Ids,
[switch]$DryRun
)
$BaseLocal = "D:/dist"
$BaseRemote = "example:/bucket/dist"
$ArgsCommon = @(
"sync"
"--no-update-modtime"
"--progress"
"--verbose"
"--checksum"
"--transfers=16"
"--checkers=32"
"--buffer-size=32Mi"
)
if ($DryRun) { $ArgsCommon += "--dry-run" }
foreach ($id in $Ids) {
$local = "$BaseLocal/$id".Replace("", "/")
$remote = "$BaseRemote/$id"
rclone @ArgsCommon $local $remote
}
其中 BaseLocal、BaseRemote 和 ArgsCommon 应该根据自身情况和设备性能进行调整。
同样,可以添加 -DryRun
来试运行输出差异而不影响云端。
执行示例:
./rclonesync.ps1 sub
这将检查 example:/bucket/dist/sub
中的文件是否和本地 D:/dist/sub
一致,如果不一致,则执行同步。
./rclonesync.ps1 sub sub2
同样,这将检查 example:/bucket/dist/sub
中的文件是否和本地 D:/dist/sub
一致,如果不一致,则执行同步;然后再检查 example:/bucket/dist/sub2
中的文件是否和本地 D:/dist/sub2
一致 ...
可以检查无数个子目录:
./rclonesync.ps1 sub sub2 sub3 sub4 sub5
使用 -DryRun
来试运行:
./rclonesync.ps1 sub sub2 -DryRun
同样,如果要在全局可使用,其实可以直接放置在 Rclone 安装目录(如果 Rclone 安装目录已经添加到系统 Path 的话),这时候就可以在任何位置调用这个 PowerShell 脚本。
rclonesync sub sub2
这里的 rclonesync 命令完全取决于如何给这个 PowerShell 脚本命名,如果重命名为 rs.ps1 ,那么就可以使用更简洁的方式调用它。
rs sub