JuiceFS Office Hours 近期问题回顾(2021 年 6 月及 7 月)

2021-08-05
高昌健

什么是 JuiceFS Office Hours?

JuiceFS Office Hours 是每周三 17:00-18:00 的线上交流活动,主要目的是通过每周一次线上交流的形式,介绍和演示 JuiceFS 的新特性、解答用户疑问、了解使用场景及相关技术交流等。

要怎么参加 JuiceFS Office Hours?

请在每周三 17:00 左右点击这个链接:https://meeting.tencent.com/dm/nVMnpAWkaFgu

哪里能看到历史收集的问题和回答?

历史收集的问题和回答会定期更新到 JuiceFS 官方博客,请订阅官方博客了解最新动态。

能否讲讲 JuiceFS 在大数据场景下的优势及特点,以及与其他友商产品对比分析,如阿里的 JindoFS 之类的。

JuiceFS 的优势:

  • 完全兼容 HDFS API,Hadoop 生态组件无缝适配。
  • 相比 HDFS:容量弹性伸缩;存储计算分离,计算资源可以灵活配置和伸缩;相比云上用云盘自建 HDFS,成本节省超过 60%,同时能提供与 HDFS 相当的读写性能;支持 POSIX、S3 接口,用一个存储适配不同业务的访问需求;JuiceFS 商业版提供全托管 SaaS 服务,零运维,且能在单一命令空间里支持百亿级的文件存储。
  • 相比对象存储:完整文件系统语义,大数据生态组件适配性好;强一致性;10 倍以上的元数据操作(list、rename 等)性能提升,综合读写性能也能提升数倍;支持 POSIX 接口。

JindoFS 的 block 模式更加类似 JuiceFS(缓存模式类似 Alluxio),具体性能对比可以参考我们之前的一篇博客:/zh-cn/blog/cache-system-of-hadoop-comparison

JuiceFS 元信息是记录什么内容?

  • 常规文件系统的元数据:文件名、文件大小、权限信息、创建修改时间、目录结构、文件属性、符号链接、文件锁等。
  • JuiceFS 独有的元数据:chunk 及 slice 映射关系、客户端 session 等。

JuiceFS 开源的代码有什么推荐的学习路径吗?

  • 了解基本的 Go 语言语法
  • 阅读 JuiceFS 技术架构JuiceFS 如何存储文件文档
  • cmd 目录是总入口,如 juicefs format 命令的入口是 cmd/format.go
  • pkg 目录是具体实现,核心逻辑都在这里,其中:
    • pkg/fuse/fuse.go 是 FUSE 实现的入口,基本是一个 wrapper,具体逻辑在下面。
    • pkg/vfs 是具体的 FUSE 接口实现,元数据请求会调用 pkg/meta 中的实现,读请求会调用 pkg/vfs/reader.go,写请求会调用 pkg/vfs/writer.go
    • pkg/meta/redis.go 是 Redis 版本的元数据引擎,pkg/meta/sql.go 是 SQL 版本的元数据引擎。
    • pkg/object 是与各种对象存储对接的实现
  • sdk/java 是 Hadoop Java SDK 的实现,底层依赖 sdk/java/libjfs 这个库(通过 JNI 调用)。

另外也推荐阅读网易存储团队的工程师写的这几篇博客:JuiceFS 调研(基于开源版本代码)JuiceFS 源码阅读-上JuiceFS 源码阅读-中

JuiceFS 现在的性能瓶颈是在哪里?最好的性能可以达到多少?

性能瓶颈主要在访问对象存储的延时和吞吐,元数据引擎如果用 Redis 性能已经足够好,用 SQL 数据库的话会有一定性能损失(参考元数据引擎 benchmark)。

最好的性能:元数据如果用 Redis 延时可以到微秒级,IOPS 可以到 5000+;单机并发顺序读吞吐能接近 3000MiB/s,结合缓存性能可以进一步提升。参考性能测试文档

JuiceFS 客户端打开一个文件,会更新文件的 slice 元信息,如果有另一个客户端更新了文件,这个客户端在没有重新打开文件的情况下,能够看到改动吗?

不保证能看到改动。JuiceFS 保证的是 close-to-open 一致性,也就是说一旦一个文件写入完成并关闭,之后的打开和读操作就可以访问之前写入的数据。但是如果是在同一个挂载点,所有写入的数据都可以立即读到。

如果把 JuiceFS 开源版本集成到商业产品中会有版权和法律问题吗,或者需要注意什么?

如果不是直接进行代码集成或者二次开发,仅仅作为一个内部组件使用,不直接分发给用户(包括网络分发),不会有版权和法律问题。如果有这部分需求可以联系我们申请单独的商业 license。

JuiceFS 是否可以实现跨数据中心部署方案(比如两地三中心金融级业务部署)?私有云部署推荐的对象存储是哪款?

可以实现跨数据中心部署方案,不过有几个注意事项:

  • 元数据引擎(如 Redis)需要支持跨数据中心同步。同时需要注意跨数据中心访问元数据的延时问题,如果数据是只读的可以考虑从当前数据中心的元数据引擎获取。
  • 对象存储需要支持跨数据中心同步

私有云部署的对象存储有多种方案可以选择,比如 Ceph、Swift、MinIO 等,它们适应的场景和规模各有不同,可以分别测试评估验证是否能够满足您的需要。此外还有很多支持私有化部署的商业存储(如金山云、七牛云、杉岩等)。

Attr 结构体中,Mode 字段低 9 位应该是表示本用户/本用户组/其他用户组的读/写/执行权限的,那高位表示什么呢?下面的代码中对 mode 的操作是什么意思?

低 12 位是权限,其中低 9 位是 owner/group/other 权限,其他 3 位是 sticky bit、SUID 和 SGID,高位保留。上面的代码就是在当用户修改 owner/group 时,要去掉 SUID 和 SGID(出于安全考虑)。

FUSE 有 low level 跟 high level 两套 API,如果选用 high level 的话,性能方面会有什么损耗吗?大概会有多少?

因为内核的 VFS 跟 FUSE 库交互的是 low level API,如果使用 high level API 的话,其实是在libfuse 内部做了 VFS 树的模拟,然后对外暴露基于路径的 API,适合元数据本身是基于路径提供的 API 的系统,比如 HDFS 或者 S3 之类。而如果元数据本身也是基于 inode 的目录树,这种 inode -> path -> inode 的多次转换会影响性能,所以 HDFS 的 FUSE 接口实现性能都不好。JuiceFS 的元数据是按照 inode 组织的,也直接提供基于 inode 的 API,那么使用 FUSE 的 low level API 就非常简单和自然,性能也很好。

重命名一个文件时 JuiceFS 只对文件进行加锁,但其它一些文件系统(如 BFS、CephFS)是会对所有父目录加读锁,这是为什么?

因为 JuiceFS 的元数据 API 是基于 inode 的,当原路径和目标路径的 inode 确定时,即可以完成 rename 操作,而不用担心别人是否会同时对这两个目录做 rename 操作。

JuiceFS 目前没有实现 forget 语义,如果删除某个 inode,但内核中的 lookup count 还不为 0,这个会有什么影响吗?

JuiceFS 的 inode 是 64 位的自增 ID,inode 一旦分配就不会复用,因此也不存在需要主动 forget 的问题。

Readdir 这个操作,目前会将所有的 entry 读到客户端缓存起来,供后续使用。如果 entry 项过多,可能会对内存有较大压力,这块会有问题吗?

会有压力,但是压力是可接受的。例如按单个 entry 占用 100 字节估算,1 千万个 entry 需要约 950MiB 内存,是可以存得下的。当然很多时候不推荐单目录存放太多 entry,这会对应用造成负面影响(比如 ls 卡住)。

听说 FUSE 的开销比较大,请问 JuiceFS 的性能怎么样?

FUSE 的确会有一定性能开销,但这个开销是属于可接受的,实际环境中性能瓶颈可能更多体现在对象存储。在和 S3FS、EFS 的 benchmark 中,JuiceFS 的性能都具有明显优势。

JuiceFS 上删除文件以后会回收对象存储上的数据吗?

会。删除文件时元数据会立即删除,但是对象存储上数据会由 JuiceFS 客户端在后台定期清理,同时用户也可以通过 juicefs gc 命令显式触发垃圾回收。

JuiceFS 更新文件的时候需要下载 block、重写、再重新上传吗?

不需要。JuiceFS 所有 block 生成以后都是不可变的,更新文件只会上传新写的 block 到对象存储,然后在原有 chunk 的 slice 列表里添加新的 slice,读取时通过合并 slice 列表得到最新的数据视图。这是 JuiceFS 与对象存储的显著区别之一。

关于什么是 chunk、slice 和 block,请查看文档

Chunk、slice、block 的作用是什么?

Chunk 是为了在读取大文件时快速定位(因为 chunk 是固定大小);slice 是为了优化覆盖写、随机写场景(参见上一个问题);block 是为了优化读写性能(可以并发),并提高本地缓存的置换效率。

CSI Driver 支持滚动升级吗?

支持。不过更新时需要提前将 node 上的业务 pod 都删除或者驱逐,下个版本的 CSI Driver(注:v0.10.0 及以上版本)会有所改进,支持在不停止业务 pod 的情况下直接升级 CSI Driver。

CSI Node 如果挂了用户 pod 要怎么恢复?

需要重新创建用户 pod,目前不支持原地恢复。

JuiceFS v0.15 新版本对小数据引入了 write-back 模式的优化,请问有遇到因为 rebalance dirty page 而导致的问题吗?另外,内核在下刷 dirty page 时,是一页一页下刷呢,还是会批量下刷连续的页?

还没碰到过;不同版本内核的性能估计不同。

TiKV 元数据引擎会在 0.16 版本支持吗?

会。0.16 的 milestone 就是支持 TiKV 作为 JuiceFS 的元数据引擎,具体 issue 是 #580(注:TiKV 元数据引擎已经在 v0.16.1 支持)。

Redis 应该不能保证不丢数据吧?

默认情况下 AOF 持久化到磁盘的时间周期是 1 秒,因此最坏情况下会丢失最近 1 秒的数据。不过可以调整 Redis 的配置将 AOF 改成每次执行命令都同步持久化到磁盘,但这会带来一定的性能损耗。

建议阅读「Redis 最佳实践」文档。

Redis 故障切换的时候是否会造成数据丢失?

有可能会。因为 Redis 的主从同步是异步的,因此当通过 Redis Sentinel 进行自动故障切换时不保证数据已经完全从 master 同步到 slave。关于这一点在 Redis 官方文档中也有说明。

建议阅读「Redis 最佳实践」文档。

TiKV 作为元数据引擎对比 MySQL 会有性能提升吗?

TiKV 相比 MySQL 在某些元数据操作上会有性能提升,比如 mkdirmvdirwrite,但某些操作会慢一些。总体来说两者性能相当。

详细对比数据请参考「元数据引擎性能对比测试」

CSI Driver 启动新容器进行挂载这个功能什么时候发布?

JuiceFS CSI Driver v0.10.0 即会包含这个特性,这个版本近期将会发布(注:本文发表时 v0.10.0 已经发布)。目前已经合到 master 分支,可以提前试用。

JuiceFS 允许多个 mount 用户同时修改同一个文件吗?如果可以,文件内容最终以谁为准呢?

JuiceFS 允许多客户端同时修改一个文件,每个客户端的写都是原子的,最新的写操作会覆盖前面的。可以通过锁来保证写入顺序,目前 JuiceFS 支持 BSD 锁(flock)和 POSIX 记录锁(fcntl)。

fcntl 的具体实现在代码的哪个位置?

具体代码位置在 pkg/meta/<XXX>_lock.go 文件,如 Redis 引擎对应的是 pkg/meta/redis_lock.go。文件中的 Getlk()Setlk() 函数即为 fcntl 文件锁的具体实现。

有测试过 SQLite 的性能吗?

没有。因为 SQLite 通常并不适用于生产环境,所以当前的「元数据引擎性能对比测试」不包含 SQLite。有兴趣的同学可以参考文档中列举的测试命令自行测试。

JuiceFS 商业版与社区版的区别是什么?

JuiceFS 的商业版服务本质上是一个全托管的 SaaS 服务,在核心功能上与社区版是一致的。二者的主要区别在于托管版使用了 JuiceFS 团队自研的分布式元数据存储引擎,它能够提供更好的性能、更大的数据规模以及可靠性,同时也提供了一系列管理功能。对于不想自己维护元数据引擎的企业来说,是很理想的选择。

JuiceFS 对存储的优化、对元数据管理的创新等等这些优化操作,会不会被底层存储吸收借鉴?这样 JuiceFS 竞争力就有所下降?或者说哪点是只有 JuiceFS 适合做而不适合底层存储做的工作那?

一部分优化可能会被底层存储借鉴,例如对象存储近几年也在尝试优化如一致性、rename 性能等问题。但是 JuiceFS 以一种新颖的架构设计解决了更多传统云上文件存储面临的问题,底层存储想要彻底解决这些问题势必需要对架构进行大的升级改造,因此我们也看到类似阿里云 JindoFS、腾讯云 GooseFS 这样的产品出现。

默认的 Zstandard 压缩是不是去掉了?

自 v0.12.0 版本开始,JuiceFS 默认关闭了文件系统压缩功能,如果需要可以在执行 juicefs format 命令时通过 --compress 选项设置。

抛开性能,在大数据场景下,JuiceFS 和 Alluxio 的区别在哪?

简单来说 JuiceFS 与 Alluxio 在存储格式、缓存粒度、POSIX 兼容性、原子元数据操作、一致性、运维复杂度这些方面都有很大区别,具体可以参考这篇文档

如果关注大数据场景下的性能比较,可以参考我们之前的一篇博客