数据同步
juicefs sync
是强大的数据同步工具,可以在所有支持的存储之间并发同步或迁移数据,包括对象存储、JuiceFS、本地文件系统,你可以在这三者之间以任意方向和搭配进行数据同步。除此之外,还支持同步通过 SSH 访问远程目录、HDFS、WebDAV 等,同时提供增量同步、模式匹配(类似 rsync)、分布式同步等高级功能。
特别地,在两个存储系统之间同步数据,如果其中一方是 JuiceFS,推荐直接使用 jfs://
协议头,而不是先挂载 JuiceFS,再访问本地目录。这样便能跳过挂载点,直接读取或写入数据(该过程依然需要读取客户端配置文件,可以使用 juicefs auth
命令提前做好认证、生成配置文件),在大规模场景下,绕过 FUSE 挂载点将能节约资源开销以及提升数据同步性能。
juicefs sync
用法如下:
juicefs sync [command options] SRC DST
# 从 OSS 同步到 S3
juicefs sync oss://mybucket.oss-cn-shanghai.aliyuncs.com s3://mybucket.s3.us-east-2.amazonaws.com
# 从 S3 直接同步到 JuiceFS
juicefs sync s3://mybucket.s3.us-east-2.amazonaws.com/ jfs://VOL_NAME/
# 源端: a1/b1,a2/b2,aaa/b1 目标端: empty 同步结果: aaa/b1
juicefs sync --exclude='a?/b*' s3://mybucket.s3.us-east-2.amazonaws.com/ jfs://VOL_NAME/
# 源端: a1/b1,a2/b2,aaa/b1 目标端: empty 同步结果: a1/b1,aaa/b1
juicefs sync --include='a1/b1' --exclude='a[1-9]/b*' s3://mybucket.s3.us-east-2.amazonaws.com/ jfs://VOL_NAME/
# 源端: a1/b1,a2/b2,aaa/b1,b1,b2 目标端: empty 同步结果: a1/b1,b2
juicefs sync --include='a1/b1' --exclude='a*' --include='b2' --exclude='b?' s3://mybucket.s3.us-east-2.amazonaws.com/ jfs://VOL_NAME/
结尾符号
SRC
和 DST
如果以 /
结尾将被视为目录,例如:movies/
。没有以 /
结尾则会被视为「前缀」,将按照前缀匹配的规则进行匹配,例如,当前目录下有 test
和 text
两个目录,使用以下命令可以将它们同步到目标路径 ~/mnt/
:
juicefs sync ./te ~/mnt/te
使用这种方式,sync
命令会以 te
前缀匹配当前路径下所有包含该前缀的目录或文件,即 test
和 text
。而目标路径 ~/mnt/te
中的 te
也是前缀,它会替换所有同步过来的目录和文件的前缀,在此示例中是将 te
替换为 te
,即保持前缀不变。如果调整目标路径的前缀,例如将目标前缀改为 ab
:
juicefs sync ./te ~/mnt/ab
目标路径中同步来的 test
目录名会变成 abst
,text
会变成 abxt
。
增量同步与全量同步
juicefs sync
默认以增量同步方式工作,对于已存在的文件,仅在文件大小不一样时,才再次同步进行覆盖。在此基础上,还可以指定 --update
,在源文件 mtime
更新时进行覆盖。
如需全量同步,即不论目标路径上是否存在相同的文件都重新同步,可以使用 --force-update
。
模式匹配
类似 rsync,你可以用 --exclude
、--include
来过滤需要同步的文件,并通过多个规则的组合实现任意集合的同步,规则如下:
- 以
/
结尾的模式会仅匹配目录,否则会匹配文件、链接或设备; - 包含
*
、?
或[
字符时会以通配符模式匹配,否则按照常规字符串匹配; *
匹配任意非空路径组件,在/
处停止匹配;?
匹配除/
外的任意字符;[
匹配一组字符集合,例如[a-z]
或[[:alpha:]]
;- 在通配符模式中,反斜杠可以用来转义通配符,但在没有通配符的情况下,会按字面意思匹配;
- 始终以模式作为前缀递归匹配;
- 在使用包含/排除规则时,位置在前的选项优先级更高。
--include
应该排在前面,如果先设置--exclude '*'
排除了所有文件,那么后面的--include 'xxx'
包含规则就不会生效。
例如,同步所有文件,但排除隐藏文件(以 .
为开头命名均被视为隐藏文件):
# 排除隐藏文件
juicefs sync --exclude '.*' /tmp/dir/ s3://ABCDEFG:HIJKLMN@aaa.s3.us-west-1.amazonaws.com/
重复该选项匹配更多规则,例如,排除所有隐藏文件、pic/
目录 和 4.png
:
juicefs sync --exclude '.*' --exclude 'pic/' --exclude '4.png' /tmp/dir/ s3://ABCDEFG:HIJKLMN@aaa.s3.us-west-1.amazonaws.com
使用 --include
选项设置要包含的目录或文件,例如,只同步 pic/
和 4.png
两个文件,其他文件都排除:
juicefs sync --include 'pic/' --include '4.png' --exclude '*' /tmp/dir/ s3://ABCDEFG:HIJKLMN@aaa.s3.us-west-1.amazonaws.com
多线程和带宽限制
juicefs sync
默认启用 10 个线程执行同步任务,可以根据需要设置 --threads
选项调大或减少线程数。
另外,如果需要限制同步任务占用的带宽,可以设置 --bwlimit
选项,单位 Mbps
,默认值为 0
即不限制。
目录结构与文件权限
默认情况下,空目录不会被同步。如需同步空目录,可以使用 --dirs
选项。
另外,在本地、SFTP、HDFS 等文件系统之间同步时,如需保持文件权限,可以使用 --perms
选项。
拷贝符号链接
在本地目录之间同步时,支持通过设置 --links
选项开启遇到符号链时同步其自身而不是其指向的对象的功能。同步后的符号链接指向的路径为源符号链接中存储的原始路径,无论该路径在同步前后是否可达都不会被转换,注意:
- 符号链接自身的
mtime
不会被拷贝; --check-new
和--perms
选项的行为在遇到符号链接时会被忽略。
分布式同步
在两个对象存储之间同步数据,就是从一端拉取数据再推送到另一端,同步的效率取决于客户端与云之间的带宽:
在同步大量数据时,单机带宽往往会被占满出现瓶颈,针对这种情况,考虑使用多机并发同步:
Manager 作为主控执行 sync
命令,通过 --worker
参数定义多个 Worker 节点(Manager 自身也参与同步),JuiceFS 会根据 Worker 的总数量,动态拆分同步任务并分发给各个节点并发执行,单位时间内能处理的数据量更大,总带宽也成倍增加。
在配置多机并发同步任务时,需要提前配置好 Manager 节点到 Worker 节点的 SSH 免密登录,如果 Worker 节点的 SSH 端口不是默认的 22,请在 Manager 节点的 ~/.ssh/config
设置其端口号。Manager 会将 JuiceFS 客户端程序分发到 Worker 节点,为避免兼容性问题,Manager 和 Worker 应使用相同类型和架构的操作系统。
举例说明,用分布式同步的方式进行对象存储间的数据同步:
juicefs sync --worker bob@192.168.1.21,tom@192.168.1.22 s3://ABCDEFG:HIJKLMN@aaa.s3.us-west-1.amazonaws.com oss://ABCDEFG:HIJKLMN@bbb.oss-cn-hangzhou.aliyuncs.com
这样一来,当前节点与两个 Worker 节点 bob@192.168.1.21
和 tom@192.168.1.22
将共同分担数据同步任务。