Skip to main content

数据同步

提示

升级至 JuiceFS 4.9 以使用 sync 子命令,或者直接使用 Juicesync

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/

结尾符号

SRCDST 如果以 / 结尾将被视为目录,例如:movies/。没有以 / 结尾则会被视为「前缀」,将按照前缀匹配的规则进行匹配,例如,当前目录下有 testtext 两个目录,使用以下命令可以将它们同步到目标路径 ~/mnt/

juicefs sync ./te ~/mnt/te

使用这种方式,sync 命令会以 te 前缀匹配当前路径下所有包含该前缀的目录或文件,即 testtext。而目标路径 ~/mnt/te 中的 te 也是前缀,它会替换所有同步过来的目录和文件的前缀,在此示例中是将 te 替换为 te,即保持前缀不变。如果调整目标路径的前缀,例如将目标前缀改为 ab

juicefs sync ./te ~/mnt/ab

目标路径中同步来的 test 目录名会变成 absttext 会变成 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.21tom@192.168.1.22 将共同分担数据同步任务。