AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

云知声是一家专注于语音及语言处理的技术公司。 Atlas 超级计算平台是云知声的计算底层基础架构,为云知声在 AI 各个领域(如语音、自然语言处理、视觉等)的模型迭代提供训练加速等基础计算能力。Atlas 平台深度学习算力超过 57 PFLOPS(5.7 亿亿次/秒,是的你没有看错,是亿亿次]

),深度学习算力是衡量一个 AI 平台计算性能的核心指标。除了满足公司内部的业务需求,平台也为外部企业和院校机构提供定制化计算服务。

AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

本文主要分享云知声 Atlas 超算平台(以下简称 Atlas)的存储建设历程以及基于 JuiceFS 建设高效存储的实践。

存储建设历程

一个性能卓越的超算平台,不仅需要充足的算力支持,也离不开高效的存储系统。结合 Atlas 上的任务特点和类型,高效存储系统应具备几个特点,如:满足多种类型的结构化与非结构化数据存储需求、兼容 POSIX 接口、海量小文件场景下具有较好的性能等。

在最早期进行 Atlas 超算平台建设的时候,我们尝试部署过 CephFS,开源版的 CephFS 在存储规模达到几千万小文件的时候,开始出现较为严重的性能问题,用户在操作文件时会遇到卡顿甚至在高 IO 的场景下整套存储系统会直接卡死,用户体验不太好。

后期,我们转到了 HPC 领域使用较为广泛的 Lustre 分布式文件存储系统, 构建了多套不同规模的 Lustre 集群,作为平台核心的存储系统,生产环境上目前主要有 40G 以太网与 100G InfiniBand 类型的集群,Lustre 分布式存储支持着用户在 Atlas 超算集群中进行数据处理、模型训练、源码编译与调试、数据归档等一系列数据操作。但是受限于 Lustre 在高并发请求下的性能瓶颈,无法满足对带宽与 IOPS 要求较高的场景需求。因此我们采用 Alluxio + Fluid 进行 IO 加速,分布式缓存给我们带来了 AI 模型训练速度上的提升以及存储系统总带宽的下降。

但是以上方案依然不是我们认为的最终方案,因此我们也在探索新的存储系统。在我们的场景上对这个新存储系统的核心需求是:

运维要足够简单:存储研发人员要能够较快的上手,运维人员后期的扩容、故障处理足够简单。Lustre 提供了 IML 一系列的自动化部署与监控工具,在运维方面较为方便。但是由于 Lustre 的软件代码是在内核上运行,如果出现故障,问题定位就显得不那么直观,需要从内核消息这边定位,大部分操作涉及重启操作系统;

数据可靠性:数据是 AI 公司宝贵的资产,算法工程师在存储上的数据要足够稳定与安全。Lustre 目前不支持文件系统级的冗余,只能通过硬件的 RAID 来抵御硬盘故障;

客户端多级缓存功能:构建大规模数据存储系统(PB 量级以上)为了考虑成本数据大部分会存储在 HDD 上,为了自动区分冷热数据,并充分利用我们 GPU 服务器的接近 TB 级的内存与大量的独立 SSD 盘,我们希望具备客户端多级自动缓存功能 ,以应对高密集 I/O 的读写场景;

社区活跃度:社区活跃度也是我们考虑的因素,活跃的社区在功能版本的迭代与 bug 的解决方面能有更快的响应。

初识 JuiceFS

云知声团队在 2021 年初了解到了 JuiceFS,并跟 Juicedata 团队进行了早期的方案对接、PoC 测试,目前 JuiceFS 已经上线到生产环境,我们也参与到 JuiceFS 开源社区的建设中。

JuiceFS 的架构与优势

JuiceFS 整体的架构由元数据引擎、对象存储集群以及 JuiceFS 客户端组成,其中元数据引擎与对象存储提供了多种方案供用户选择。通过 JuiceFS 存储的数据将持久化到对象存储(如 Amazon S3)中,相应的元数据可以根据场景和需求持久化到 Redis、MySQL、SQLite 以及 TiKV 等各种数据库引擎中。

AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

不管是元数据引擎还是对象存储都有很多成熟的方案可以选择,如果是在公有云上使用通常也有全托管的服务开箱即用。JuiceFS 的元数据自动备份、回收站等特性一定程度上保障了数据的可靠性,避免一些意外情况导致数据丢失,当然如果是自己运维元数据引擎和对象存储依然需要做好数据备份。JuiceFS 的本地缓存特性可以自动将频繁访问的数据缓存到内存以及磁盘中,同时也会对文件的元数据进行缓存。

PoC 测试

PoC 测试我们主要是在小规模环境上做可行性验证, 关注的点是产品特性、运维方式、与上游调度、业务框架对接是否可行等。

PoC 测试环境我们搭建了一个单节点的 Redis + 3 节点的 Ceph 对象存储集群,在环境搭建方面因为 Redis 跟 Ceph 都比较成熟,部署运维方案可以参考的资料也比较全,而 JuiceFS 客户端能够以较为简单的方式对接元数据引擎跟对象存储。

业务的适配方面,JuiceFS 完全兼容 POSIX 协议,我们上层的业务可以无缝切换与对接,业务使用无感,JuiceFS 也支持以 CSI Driver 这种云原生的方式调度,与我们整个平台的技术栈契合。

在性能测试方面,我们在测试环境进行了文字识别模型的训练,实验环境为:模型采用服务器版中文识别模型 backbone 为 ResNet-18,数据整体总量是 98G 采用 LMDB 格式存储,在 6 张 NVIDIA Tesla V100 进行了三组实验,分别是:

  • 直接在 Lustre 读
  • 在带有 200G 内存缓存的 JuiceFS 读
  • 在带有 960G SSD 缓存的 JuiceFS 上读

AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

JuiceFS 客户端拥有多级缓存功能,因而在性能测试中, 在数据读方面有较大性能提升,相比 Lustre 性能有1倍以上的提升,这与我们的业务特点比较契合。

综合考虑运维方式、业务契合度以及性能表现,我们决定将 JuiceFS 带上生产。

JuiceFS 在 Atlas 的使用场景与收益

JuiceFS 客户端多级缓存目前主要应用在我们的 文字识别、语音降噪以及语音识别场景。由于 AI 模型训练的数据读取特点是读多写少,我们充分利用 JuiceFS 客户端的缓存带来 IO 读取的加速收益。

收益一:加速 AI模型训练

语音降噪测试
降噪场景模型的测试中使用的是散文件,每个数据都是 wav 格式的小于 100k 的语音小文件,在降噪场景我们测试了数据 dataload 阶段的 I/O 数据,JuiceFS 客户端节点的内存缓存为 512G,在 500h 规模的数据下、以 40 的 batch size 进行测试。

AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

从测试结果来看,单从数据读取效率上,在 wav 小文件方面, JuiceFS 为 6.45 it/s,而 Lustre 为 5.15 it/s,性能提升25%。JuiceFS 有效加速了我们端到端的模型训练,整体缩短了模型的产出时间。

文字识别场景
在文字识别场景中,模型为 CRNN backbone 为 MobileNet v2 ,测试环境如下:

AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践
AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

在这个测试中,主要做了 JuiceFS 跟 Lustre 的速度对比,从实验的结果来看从 Lustre 读每个 batch 耗时 1.5s,从 JuiceFS 读每个 batch 耗时为 1.1s,提升36%。从模型收敛的时间来看,从 Lustre 的 96 小时下降到 JuiceFS 的 86 小时,使用 JuiceFS 能够将 CRNN 模型的产出时间缩短 10 小时。

收益二:加速 AI模型开发

AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

在算法工程师将 AI 模型训练任务正式提交到超算集群之前,其模型需要经过大量的调试,我们为用户提供了调试环境,Dev Node 跟 Atlas 正式训练集群一样都是使用相同的存储,开发节点与训练节点都挂载 JuiceFS 客户端,因此在开发机的修改能够无缝迁移到 Atlas 训练集群。

用户在开发机上可以灵活地选择开发环境,既可以在宿主机搭配 Anaconda 进行远程调试,也可以使用容器的方式运行开发环境。用户的调试模型大部分是 PyTorch 跟 TensorFlow 类型的框架,我们发现在调试的时候需要频繁地 import Python 包,例如 numpy、torch 等,这种包都是大量的小文件组成的,基于旧的存储系统,用户 import 包的耗时需要几秒或者几十秒。算法人员反馈模型调试的效率比较低。 作为统一开发环境,伴随着大量的安装包导入、代码编译、日志读写、样本下载,这要求调试机既能有较高的吞吐量,又能快速处理大量小文件。

通过引入 JuiceFS,我们在开发机上挂载了 JuiceFS 客户端,客户端挂载时候使用元数据缓存以及数据读缓存机制。在元数据缓存方面,当 JuiceFS 客户端使用 open() 操作打开一个文件的时候,其文件属性(attribute)就会自动缓存在客户端内存中,只要缓存未失效则随后执行的 getattr() 跟 open() 操作都会从内存缓存中立即返回结果。在执行 read() 操作的时候文件的 chunk 和 slice 信息也会自动缓存在客户端内存。数据缓存方面我们使用内存作为缓存介质,采用该方式用户调试的 Python 包在经过第一次 import 之后会全部缓存在内存上,第二次调试的时候,直接从内存缓存读取文件。 相比之前的方式,整体速度有 2-4 倍的提速 ,极大地提高了用户的调试效率,用户的体验也更加好。

JuiceFS 在 Atlas 的使用方式

在数据的存放管理方式上,我们采用兼容现有分布式存储系统的管理方式,JuiceFS 集群的节点也都是对接 LDAP,每个节点会通过 LDAP 的客户端与 LDAP Server 集群进行交互认证。

超算平台上的每个组归属于不同的目录,每个目录下是各自组内或者部门内的成员,不同组之间的目录是不可见的。目录的权限是基于 Linux 的权限管控机制。用户在 Atlas 集群提交训练任务的时候,集群的任务提交工具会自动读取系统上用户的 UID 与 GID 信息然后将其注入用户提交的任务 Pod 的 securityContext 字段,则 Atlas 集群上运行的容器 Pod 内所有容器的进程运行的 UID 与存储系统上的信息一致,保证权限不越界。

AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

在数据的访问方式上,云知声目前有 2 种使用方式:

  • 一种是通过计算节点的 HostPath 访问数据;
  • 另一种是更加云原生的方式,通过结合 Fluid + JuiceFS 对利用 JuiceFS 客户端为 Atlas 的应用提供数据的访问与加速。

HostPath Volume

AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

第 1 种还是沿用之前的访问分布式文件存储系统的方式,通过 Kubernetes HostPath 的方式直接访问本地的存储系统客户端,我们在所有的 CPU 与 GPU 计算节点都部署了 JuiceFS 的客户端,用户提交计算任务的时候需要指定 Kubernetes volume 为 HostPath 的方式,将 JuiceFS 的目录映射。这种方式的缓存管理就比较裸,在用户侧是无法对缓存进行管理的。

Fluid + JuiceFS

第 2 种方式是结合 Fluid + JuiceFS 的方式,关于如何使用的具体方式可以参考我们之前的文章(点击此处查看) ,这里仅对架构做个简单的说明。

AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

Fluid 会启动 JuiceFS 相关的组件包括 FUSE 跟 Worker pod,其中 FUSE Pod 提供了 JuiceFS 客户端的缓存能力,Worker Pod 则实现了对缓存生命周期的管理,Atlas 平台的 AI 离线训练任务通过与 FUSE Pod 客户端交互,进行 AI 训练数据的读取,通过 Fluid 提供的缓存调度能力以及数据集的可观测性,平台的用户可以通过亲和调度将缓存部署在特定的计算节点上,同时用户能够直观的看到缓存的使用情况(例如缓存数据集的大小、缓存的百分比、缓存的容量等)。

JuiceFS 存储生产环境建设

元数据引擎

目前我们生产环境的元数据引擎采用 Redis,Redis 节点的系统盘做了 RAID1,同时 Redis 持久化的数据会定期同步到另一台备份节点上。Redis 的数据持久化我们采用 AOF + RDB 的方案,每秒进行一次数据持久化,相关配置如下:

appendonly yes
appendfsync everysec
aof-load-truncated yes

由于我们节点采用的是 100G InifiBand,IB 的 网卡驱动[3] 需要用户根据自己的操作系统版本下载对应的 ISO。目前我们的节点是采用 Kernel 5.4 的版本,由于 IB 驱动跟操作系统还有 Kernel 版本有较强的耦合性,当我们 Kernel 升级到 5.4 版本,驱动需要重新编译安装,驱动版本 MLNX_OFED_LINUX-5.5-1.0.3.2-rhel7.6-x86_64.iso 注意 GCC 的版本一定要是 GCC 9 的才行,否则编译过程会出现各种莫名其妙的问题。

安装 gcc9 yum --enablerepo=extras install centos-release-scl-rh yum install devtoolset-9-gcc scl enable devtoolset-9 bash # 进行 IB 驱动编译 mount /dev/sr0 ib ./mlnx_add_kernel_support.sh -m /root/ib -k (kernel 版本)

对象存储

对象存储采用自建的 Ceph 集群,Ceph 集群采用 Cephadm 进行部署,目前生产环境用的是 Octopus 版本。Cephadm 是随着 Ceph 新版本 v15.2.0(Octopus)发布的安装工具,并且不支持 Ceph 的旧版本,Cephadm 不依赖于外部配置工具,如 Ansible、 Rook 和 Salt,它通过 SSH 将管理器守护进程连接到主机来实现这一点。管理器守护进程可以添加、删除和更新 Ceph 容器。通过 Cephadm 引导一个单节点的集群,Cephadm 会在执行 bootstrap 引导的节点部署 mgr 跟 mon 服务,当添加其他节点的时候,会自动在其中一台部署 mgr 管理节点,目前我们生产采用 2 个管理节点 3 个监控节点。在 Ceph 调优方面我们借鉴了社区其他用户分享的方案,感谢携程的工程师在我们调优过程中提供的帮助 (点击此处查看),主要做了以下实践:

服务器层面

  • 42Cores 256GB 24*18T HDD
  • 系统盘: 2* 960G SAS SSD
  • BlueStore
  • 关闭 NUMA
  • 升级 kernel: 5.4.146 开启 io_uring
  • Kernel pid max,修改 /proc/sys/kernel/pid_max

Ceph 配置方面

  • Ceph RADOS:直接调用 librados 接口,不走 S3 协议
  • Bucket shard
  • 关闭 pg 的自动调整功能
  • OSD 日志存储(采用 bluestore,建议裸容量配比—— block : block.db :
  • block.wal = 100:1:1,后两者建议采用 SSD 或 NVMe SSD)
  • 3 副本

JuiceFS 客户端

我们环境中 JuiceFS 对接的对象存储是 Ceph RADOS,JuiceFS 采用 librados 与 Ceph 进行交互,因此需要重新编译 JuiceFS 客户端,建议 librados 的版本要跟 Ceph 的对应,例如在我们的环境 Ceph 版本是 Octopus(v15.2. ),librados 的版本建议为 v15.2.,CentOS 自带的 librados 版本比较低,因此我们可以在官网自己下载对应的包,我们的环境上只需要下载 librados2-15.2.10-0.el7.x86_64.rpm 和 librados-devel-15.2.10-0.el7.x86_64.rpm。然后运行如下命令安装:

yum localinstall -y librad*

安装 librados 后即可编译 JuiceFS 客户端了(推荐 Go 1.17+ 、GCC 5.4+):

make juicefs.ceph

编译完 JuiceFS 即可创建文件系统并在计算节点进行 JuiceFS 客户端的挂载了。目前 JuiceFS 在我们的生产环境使用还是有一大部分是直接通过 Kubernetes 的 HostPath 进行挂载,因此我们在各个 GPU、CPU 节点中都挂载了 JuiceFS 客户端,并通过 systemctl 管理 JuiceFS 的挂载进程,实现开机自动挂载与故障的恢复。

未来展望与规划

最后归纳下 Lustre 与 JuiceFS 的特点与适用场景,企业可以根据自身的业务场景、运维能力以及存储规模做出相应的选择。

  • Lustre 作为老牌 HPC 领域的存储系统,为许多全球最大的超算系统提供动力,具有多年的生产环境经验。其具有符合 POSIX 标准、支持各种高性能低时延的网络,允许 RDMA 访问的优点,适用于传统 HPC 领域的高性能计算,但是在云原生场景的适配上还不够完善,目前只能采用 HostPath Volume 对接,而且其软件运行在 Linux 内核之上,对运维人员要求更高;
  • JuiceFS 是一款云原生领域的分布式存储系统产品,提供了 CSI Driver 以及 Fluid 等方式使用能够更好地与 Kubernetes 进行结合。在运维部署方面为用户提供了更多灵活的选择,用户既可以选择在云上也可以选择私有化部署,在存储扩容运维方面较为简单。完全兼容 POSIX 标准使得深度学习的应用可以无缝迁移,但是由于后端对象存储的特点其在随机写方面会有较高的延迟,在只读的场景可以使用客户端的多级缓存进行加速较为符合我们的业务特点。

Atlas 平台未来与 JuiceFS 相关的规划是

  • 元数据引擎升级:TiKV 适合在 1 亿以上文件数量(最多可以支撑到百亿级文件),对性能以及数据安全都有较高要求的场景,目前我们已经完成了 TiKV 的内部测试也在积极跟进社区的进展,后续要将元数据引擎迁移到 TiKV。
  • 基于目录(项目)的文件配额:开源版本目前还不支持基于目录的配额,目前我们每个部门是归属在 JuiceFS 的不同的目录下,需要对目录的配额做限制。JuiceFS 社区版已经在规划实现这个特性,会在 v1.0.0 之后的版本正式发布。

感谢 JuiceFS 开源社区在云知声 Atlas 计算平台高效存储建设的过程中提供的技术支持,云知声也在积极地进行内部测试,争取后续将开发的功能以及改进回馈到开源社区。

如有帮助的话欢迎关注我们项目 Juicedata/JuiceFS 哟! (0ᴗ0✿)

Original: https://www.cnblogs.com/JuiceData/p/16424461.html
Author: JuiceFS
Title: AI场景存储优化:云知声超算平台基于 JuiceFS 的存储实践

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/611164/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 十一、服务介绍及端口

    服务管理简介服务器的作用主要是什么?主要是通过网络来提供服务,比如apache提供一个web服务,mysql提供一个数据库服务,dns提供一个域名解析服务,ftp提供一个文件服务器…

    Linux 2023年6月7日
    098
  • linux添加磁盘及分区挂载

    磁盘管理 1.为什么要添加磁盘 2.系统添加磁盘并分区 磁盘管理 1.为什么要添加磁盘 随着系统的使用,磁盘的内容会越来越少,所以有必要添加磁盘来增加空间。 [En] With t…

    Linux 2023年5月27日
    079
  • Shell脚本监控线上端口服务是否正常开启

    前言: 线上服务正常可用是至关重要的,当正在运行的某个端口服务异常停止,我们期望定时脚本可以自动启动,而无需遇到问题再人为的启动。 例如:监听Mysql服务是否正常,我们通常的思路…

    Linux 2023年5月28日
    087
  • 001.AD域控简介及使用

    一 AD概述 域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系。 当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还…

    Linux 2023年6月7日
    0116
  • 一文聊透 Netty IO 事件的编排利器 pipeline | 详解所有 IO 事件的触发时机以及传播路径

    欢迎关注公众号:bin的技术小屋,本文图片加载不出来的话可查看公众号原文 本系列Netty源码解析文章基于 4.1.56.Final版本 1. 前文回顾 在前边的系列文章中,笔者为…

    Linux 2023年6月6日
    088
  • 【git】合并分支到主干master

    分支合并到master主干上 1.当前为其他分支切换到主分支上: git checkout [主分支&#x…

    Linux 2023年6月13日
    0104
  • MSF生成木马实现远控

    思路 使用kali工具msf制作exe木马文件靶机通过点击开启后门进行监听 原理 靶机执行木马文件后,向攻击机中发送信息建立session会话,本机打开监听状态,收到信息后进行操作…

    Linux 2023年6月13日
    053
  • Docker Compose

    https://m.runoob.com/docker/docker-compose.html https://www.cnblogs.com/minseo/p/11548177….

    Linux 2023年6月13日
    088
  • [转载]C++中new和malloc的区别

    new与malloc的10点区别 1. 申请的内存所在位置 new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储…

    Linux 2023年6月7日
    070
  • linux DMA接口

    1.1. 一致性DMA映射(Consistent DMA mappings ) 主要用于映射长时间使用的区域。 CPU和DMA controller不需要考虑cache的影响。 1…

    Linux 2023年6月6日
    057
  • 使用 ssmtp 於 shell 透過 Gmail 寄信

    有很多程式於 bash shell 執行, 執行完要自動寄信出去, 但是最近都被 Google 退信, 最好的方法是透過 Gmail 直接寄信. 本來是要另外寫隻 script 來…

    Linux 2023年5月28日
    074
  • 如何使用CMake构建c++项目

    1. c++项目构建与CMake简介 在Windows系统上我们通常使用 Visual Studio(VS)来生成我们的c++项目。我们只需在VS相应的层次目录中添加相应的文件即可…

    Linux 2023年6月14日
    0100
  • Python闭包

    前言 学习Python的单例实现的时候,遇到了下面这样的代码。很不理解为什么局部变量 _instance没有重新初始化。后来看到有人说这是闭包,于是又去了解了下 闭包。没想到闭包竟…

    Linux 2023年6月7日
    086
  • 代码中的软件工程复习

    编写高质量代码的基本方法 通过控制结构简化代码 通过数据结构简化代码 一定要有错误处理 注意性能优先的代价 拒绝修修补补不断重构代码 性能优先策略带来的隐藏代价 软件工程师的人力成…

    Linux 2023年6月8日
    088
  • 聊一聊如何搭建高性能网站哪一些事

    在开发中经常会遇到网站的性能平静下来,打开慢的情况。我们平常开发中怎么 一步一步排查这些问题并 解决问题呢 在快节奏的时代中,慢是个不容忍受的事情。 一、 为什么会’慢…

    Linux 2023年6月14日
    0118
  • 阿里云ddns shell 脚本

    https://files-cdn.cnblogs.com/files/ahuo/aliyun-ddns.sh Original: https://www.cnblogs.com/…

    Linux 2023年5月28日
    087
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球