初探云原生下的AI分布式文件系统-JuiceFS

648 阅读6分钟

前言

Kubernetes已经成为事实的应用编排标准,越来越多的应用在不断的向云原生靠拢,实现弹性伸缩、故障自愈等特性,这其中也包括了大数据、AI等应用,此类应用通常使用大规模的非结构数据,在传统场景下已经有各自的解决方案,如HDFS、对象存储,然而当它们迁上云端,对存储架构也提出了新的挑战。

大数据应用上云,由于云端的动态迁移特性,通常需要支持存算分离,这也是数据湖架构发展的趋势,而标准的HDFS计算存储耦合架构以及其NameNode所带来扩展性困难都让其不再适用云端存储, 与HDFS相比而言,对象存储采用了key-value的存储方式,简化了文件系统中数据与数据之间的组织结构,具备云原生所提倡的易伸缩、高可用等特点,但也依然存在一些不足:

  • List/Rename慢:对象存储按照目录进行list/Rename性能较差。
  • 缺少强一致性: 多客户端并发读写可能出现问题。
  • 数据管理困难: 非原生目录结构不利于管理员维护。
  • 应用对接复杂: 必须使用SDK或HTTP API,对应用开发有限制。

那么在这种场景下,我们所需要的云原生文件系统存储是什么样的呢:

  1. 多协议互通: 包括POSIX、HDFS、S3,其POSIX 是最久经考验,生态丰富的文件访问接口,同时支持多种协议,让各类应用可以无缝对接至平台,避免数据迁移所带来的开销;
  2. 高性能元数据: 解决对象存储在计算、分析场景中的痛点;
  3. 小文件管理能力,无论在大数据场景还是 AI 训练场景,十亿、百亿甚至千亿文件的管理需求被越来越多的提起;
  4. Kubernetes友好: 支持kubernetes接口与生态,容易被运维人员所管理。

面对这样的需求,我们现有的CephFS、GlusterFS都有着或多或少的不足,像CephFS已经有了Rook项目,可以很好的集成到Kubernetes之中,其本身的统一存储架构,支持块存储、文件存储、对象存储,虽然非常吸引人,但架构的复杂,以及独立的MDS元数据服务器带来了较高的维护成本,而Glusterfs没有元数据服务器的设计让其更容易扩展,但其性能在大规模小文件下会出现线性衰减,这一点是我们在机器学习场景下所难以接受的。

为了解决上述问题,在这里我们介绍一个基于对象存储服务的分布式POSIX文件系统-JuiceFS,其使用对象存储作为底层的块存储,使用数据库中(如redis)作为元数据服务,借助数据库的低时延以及对象存储的高带宽特性实现了一个高性能的分布式文件系统。

整体架构图 1.png uiceFS 文件系统由三个部分组成:

  • JuiceFS 客户端:协调对象存储和元数据存储引擎,以及POSIX、Hadoop、Kubernetes、S3 Gateway 等文件系统接口的实现;
  • 数据存储:存储数据本身,支持本地磁盘、对象存储;
  • 元数据引擎:存储数据对应的元数据,支持 Redis、MySQL、SQLite 等多种引擎;

客户端的Posix协议兼容通过fuse层实现,其代码入口在pkg/fuse/fuse.go中,可以看到其接口实现的比较全,包括了Fallocate(稀疏文件)、Symlink(符号链接)、CopyFileRange(内核态的文件拷贝)、SetLk(POSIX 文件锁)、Flock(BSD 文件锁)、SetXAttr(文件扩展属性)等。

2.png 数据存储引擎对接主流的对象存储,在pkg/object目录下可以看到基本上市面可见的对象存储都有实现对接,如S3、MinIO、Ceph、Azure Blob、OSS等,其接口实现如下。

3.png 元数据引擎,juicefs与其他对象存储实现的文件系统如S3FS、Alluxio等最大区别在于独立维护的元数据引擎,实现了完整的POSIX协议,也是其性能更优的主要原因。第一版的元数据引擎只支持redis,目前官方新加了MYSQL、TIKV的引擎支持,其代码实现在pkg/meta目录下,其中redis使用了lua脚本来实现lookup加速。

4.png JuiceFS的文件存储架构:

5.png 任何存入 JuiceFS 的文件都会被拆分成固定大小的 "Chunk",默认的容量上限是64MiB。每个Chunk由一个或多个"Slice"组成,Slice 的长度不固定,取决于文件写入的方式。每个 Slice 又会被进一步拆分成固定大小的 "Block",默认为 4 MiB。最后,这些 Block 会被存储到对象存储。与此同时,JuiceFS 会将每个文件以及它的 Chunks、Slices、Blocks等元数据信息存储在元数据引擎中。因此,你会发现在对象存储平台的文件浏览器中找不到存入 JuiceFS 的源文件,存储桶中只有一个 chunks 目录和一堆数字编号的目录和文件。

6.png 最终存储对象存储的文件名生成规则如下:

7.png

私有化Kubernetes平台集成方案

Juicefs的架构更多的偏向于在公有云上部署,但我们也有不少需要在内网环境的使用需求,好在juicefs的实现已经支持对接各类可以私有化的组件,以下为我们私有化部署的架构:

8.png 整个平台运行于Kubernetes之上

  • Minio集群: 采用分布式启动模式。提前规划容量需求,支持扩容但需要停机。
  • Redis-Sentinel: redis主从模式,使用哨兵自动切换,AOF设置每秒同步。
  • Juicefs-CSI: Juicefs社区开源的CSI组件,在v0.10版本前,juicefs的客户端fuse进程运行在CSI-Node的POD中,这样有POD和Fuse Daemon同生命周期问题,一旦CSI-Node挂掉会导致此节点上使用juicefs卷的POD全部需要重建,在v0.10版本重构后,juicefs的客户端进程在单独的POD中运行,与CSI node解耦,实现了更好的资源隔离,也支持CSI组件平滑升级。

fsmnt-csi-operator.jpg

未来

目前梯度容器云正在深入调研测试JuiceFS中,后续将会与Juicefs社区有更多的合作,在大数据、AI场景下提供更好的存储支撑,为应用打造高效的一体化云原生平台。

参考

  1. github.com/juicedata/j…
  2. aspirer.wang/?p=1560
  3. github.com/juicedata/j…
  4. github.com/juicedata/j…
  5. docs.minio.org.cn/docs/master…