JuiceFS v0.15 发布,开放元数据备份和恢复功能,性能大幅提升!

Juicedata 2021.07.07

经过 1 个多月的开发,JuiceFS v0.15 正式发布。新版本涉及 60 多项变化,其中最吸引人的是实现了元数据的导入、导出和迁移功能。

与此同时,新版本利用内核的页缓存(page cache)及 FUSE 的缓存模式,实现了在高负载情况下读写性能的显著提升。

特别说明:JuiceFS v0.15 是向后兼容的,旧版程序可以安全的升级到该版本。

下面就让我们一起来看一看新版本发生了哪些变化吧:

元数据导出、导入和迁移

JuiceFS 是一个由数据库和对象存储共同驱动的文件系统,在存储文件时,数据会存储在对象存储,元数据会存储在专门的数据库中。

相比于直接操作对象存储上的文件,在独立的数据库中检索和处理元数据会获得更好的性能表现,特别是在处理大规模数据的场景下,操作独立存储的元数据会带来相当显著的效能提升。

但早前的版本在创建文件系统时,一旦指定了某种元数据引擎,之后就再也无法修改。另外,像 Redis 数据库,虽然性能强悍,但可靠性始终是用户的隐忧。

针对这些问题,v0.15 做了专门的研发,引入了 dumpload 两个子命令,前者可以将元数据导出到标准的 JSON 文件既可以用作备份也可用作迁移,后者则可以将 JSON 备份导入到数据库。

备份元数据到 JSON 文件

以下命令将 Redis 数据库中的元数据导出到名为 meta.json 的文件中:

$ juicefs dump redis://192.168.1.6:6379 meta.json

从 JSON 文件恢复元数据

以下命令将 meta.json 文件中的元数据恢复到 Redis 数据库中:

$ juicefs load redis://192.168.1.6:6379 meta.json

元数据迁移

JuiceFS 中所有的元数据引擎都能够识别 JSON 备份文件,从任何元数据引擎中导出的 JSON 备份文件,都可以被恢复到任何其他的引擎中。

比如,以下 2 条命令先从 Redis 数据库导出元数据,再将元数据导入到空的 MySQL 数据库中,完成元数据在两个数据库之间的迁移:

$ juicefs dump redis://192.168.1.6:6379 meta.json
$ juicefs load mysql://user:password@(192.168.1.6:3306)/juicefs meta.json

有关元数据管理的更多内容,请查阅文档

内核读缓存优化

通过内核读取文件时,内核会自动建立已经读过的数据的页缓存,即使文件关闭了也会继续保留,重复读取时速度将会非常快。

JuiceFS v0.15 增加了对内核中页缓存的复用能力,在打开一个文件时会检查它的 mtime 是否发生变化,如果没变则可以复用内核已有的页缓存。

以下是一个简单的测试。

首先通过 dd 命令在 JuiceFS 上生成一个大小为 1GB 的文件:

$ dd if=/dev/urandom of=/jfs/test.bin bs=1G count=1 iflag=fullblock

然后继续通过 dd 命令读取上一步生成的文件:

$ time dd if=/jfs/test.bin of=/dev/null bs=128K count=8192
8192+0 records in
8192+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 14.8655 s, 72.2 MB/s

real	0m14.870s
user	0m0.001s
sys	0m0.404s

可以看到读吞吐为 72.2MB/s,总耗时 14.87 秒。然后再运行一次相同的命令:

$ time dd if=/jfs/test.bin of=/dev/null bs=128K count=8192
8192+0 records in
8192+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.121848 s, 8.8 GB/s

real	0m0.126s
user	0m0.000s
sys	0m0.123s

此时的读吞吐已经提升到 8.8GB/s,相比第一次读性能提升了 125 倍!

对于明确知道数据不会变化的场景,还可以通过参数 --open-cache N 来指定检查文件是否更新的间隔,这样还可以进一步省去 open 时检查 mtime 的开销,对于 AI 训练等只读场景会非常有用。

小数据高频写入优化

对于频繁写入小数据量(如每次写入 128 字节)的场景,默认情况下 JuiceFS 的写性能较差,因为默认的 write-through 模式需要将每次写入的数据通过 FUSE 写入到 JuiceFS 的客户端,此时 FUSE 带来的开销会影响写入性能。从 v0.15 开始 JuiceFS 支持了 FUSE 的「writeback-cache 模式」,当开启这个模式以后 FUSE 会在内核中首先聚合写入的数据,当累计到一定量(如 128KB)以后才会将数据写入 JuiceFS 客户端,这样便能显著减少 FUSE 请求数提升写入性能。需要注意的是 FUSE 的 writeback-cache 模式依赖 3.15 版本及以后的 Linux 内核,同时需要在挂载 JuiceFS 文件系统时通过 -o writeback_cache 选项手动开启。

以下是一个简单的写入测试,借助 dd 命令每次写入 128 字节的数据,总共写入 10MB 数据。

先来看看不开启 writeback-cache 模式的写入性能:

$ time dd if=/dev/zero of=/jfs/small-write.bin bs=128 count=81920
81920+0 records in
81920+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 2.66483 s, 3.9 MB/s

real    0m2.669s
user    0m0.105s
sys     0m0.951s

可以看到写吞吐为 3.9MB/s,总耗时 2.669 秒。然后重新挂载 JuiceFS,开启 writeback-cache 模式,再次运行刚才的命令:

$ time dd if=/dev/zero of=/jfs/small-write.bin bs=128 count=81920
81920+0 records in
81920+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.297128 s, 35.3 MB/s

real    0m0.304s
user    0m0.050s
sys     0m0.062s

此时写吞吐为 35.3MB/s,相比未开启时写入性能提升了 9 倍!

其它变化

  • 新增命令自动补全功能(查看文档
  • bench 命令新增 -p 选项,支持并行基准测试。
  • 新增 PostgreSQL 数据库作为元数据引擎
  • 新增 WebDAV 作为对象存储(查看文档
  • 新增 --read-only 选项,实现只读挂载功能。
  • 新增 --subdir 选项,实现子目录挂载功能。
  • 新增 --log 挂载选项,可在后台运行模式下将日志写入指定的文件。

更多变更信息请查阅版本发布页面