云知声从一家专注于语音及语言处理的技术公司,现在技术栈已经发展到具备图像、自然语言处理、信号等全栈式的 AI 能力,是国内头部人工智能独角兽企业。公司拥抱云计算,在智慧医疗、智慧酒店、智慧教育等方面都有相应的解决方案。

Atlas 是云知声的底层基础技术平台,支撑着云知声所有模型的迭代:

第一层是业务层,主要是公司的业务如语音处理、图像处理、自然语言处理等。

第二层是控制中心,从数据生产、数据接入到模型发布都可以一站式完成。

第三层是核心的计算层,主要支持深度学习,以及数据预处理。

最底层是基础架构层,主要是由 GPU 集群、CPU 集群以及分布式存储构成,所有的机器都是用 100Gbps 的 InfiniBand 高速网互联。

存储场景与需求

云知声初期的建设目标就是要建成一站式的 AI 平台,包含 AI 模型的生产,数据预处理,模型开发,模型训练以及最后模型的上线。

如上图所示,每个步骤都需要跟数据交互,其中数据预处理和模型训练需要比较大的 IO

• 数据预处理,主要是语音处理会提取语音特征,会把语音特征转成 numpy 格式的文件;图像处理的过程中,会对图像做预处理,做训练数据的格式转换;

• 模型开发,主要是算法工程师做代码的编辑,模型算法的调试;

• 模型训练,途中会需要做多轮数据读取,以及模型会输出到相应的存储上,这个步骤所需要的 IO 非常大;在模型上线的时候,服务会去读取存储系统中的模型文件。总结一下我们对存储的需求:

  1. 能够对接整个模型开发的的全链路,在几个比较核心的功能块中都要能够支持;
  2. 支持 CPU、GPU 的数据读取的任务;
  3. 我们的场景主要是语音、文本和图像数据,这些场景的特点是文件大小都比较小,所以要支持小文件场景下的高性能处理。
  4. 我们的业务场景主要是读多入写少,模型训练的时候大部分是在读取数据,基本不会写入数据。

    基于以上这些需求点,我们需要一套高性能可靠的分布式存储系统。

云知声存储建设历程

早期的时候,我们的 GPU 只有十几台左右,当时使用 NFS 做了一个小规模的集群。同时在 2016 年引入了 CephFS 的测试环境,当时那个版本的 CephFS 在小文件场景下性能不太好,所以就没有把 CephFS 带入到生产环境。

后来我们继续做了调研,发现 Lustre 在 HPC 领域是最为常用的高性能文件系统。测试表明 Lustre 在规模化的构建以及性能方面表现都不错,于是从2017 年到 2022 年,我们全部是用 Lustre 来承载所有的数据业务。

但是随着使用的 GPU 越来越多,现在有 5.7 亿亿次/秒左右的浮点处理能力,底层存储的 IO 已经跟不上上层计算能力。于是,我们开始探索新的存储,为后续的存储扩容做升级,同时在使用 Lustre 的过程中也遇到了一些问题。

第一:运维方式,Lustre 主要是基于内核的,直接嵌在内核,有时候定位问题会涉及到机器的重启之类的操作;

第二:技术栈,因为我们的云平台的开发主要是以 golang 为主,所以比较偏向于使用与开发语言比较契合的存储。Lustre 使用的是 C 语言,在定制优化方面需要有较多人力精力。

第三:数据的可靠性,Lustre 主要依赖硬件可靠性(比如 RAID 技术),软件层面主要是实现元数据节点和对象跟数据节点的 HA 方案。相比这些,我们还是更希望使用三副本或者是纠删码这类更可靠的软件方案。

第四:多级缓存的功能的需求,在 2021 年的时候,我们用了 Fluid + Alluxio 来作为 Lustre 的分布式加速,Alluxio 能够较好的为我们的集群做计算提速,减轻底层存储的压力。但是我们一直在探索希望直接从存储系统来进行客户端缓存,这样操作对用户来说能够更加透明一点。

在 2021 年的时候 JuiceFS 刚开源时,我们就对它的特性做了调研。

第一,产品特性:JuiceFS 支持 POSIX 接口,能够以 HostPath 的方式去挂载,这种方式跟我们在使用 NAS 的方式是一模一样的,用户在使用时基本不用做任何改变;JuiceFS 元数据以及对象存储,都有比较多的可选方案,像Redis、 TiKV在AI领域是比较合适的。底层 Ceph、MinIO 还有一些公有云的对象存储用户都可以自行选择。

第二,上层调度:JuiceFS 除了支持 HostPath,同时也是支持CSI 驱动方式,能够以更加云原生的方式让用户去接入相应的存储。

第三,业务框架适配:POSIX 接口适配深度学习框架。第四,运维:元数据引擎以及对象存储,业界方案都比较成熟,选择也比较多,而且 JuiceFS 有元数据自动备份以及回收站功能。JuiceFS 与业务比较契合,因此我们进行了 POC 测试。

测试环境如上图所示,结果发现 Lustre 跟 JuiceFS 来相比,由于JuiceFS 直接用到了内核页缓存,相比 Lustre 直接访问机械盘,性能有很大提升(如下图所示,越小越好)。

经过了 POC 测试,我们决定把JuiceFS 带入生产环境。目前整个Atlas 的集群所有 GPU 的计算节点,以及所有的开发调试节点,都安装了 JuiceFS 客户端。

JuiceFS 直接对接redis 集群和ceph,计算节点大部分用的 HostPath 方式接入。同时 Atlas 集群也部署了 JuiceFS CSI Driver,用户可以以云原生的方式接入。

JuiceFS 在 Atlas 的使用方式

为了保证数据的安全性,超算平台上的每个组归属于不同的目录,每个目录下是各自组内或者部门内的成员,不同组之间的目录是不可见的

目录的权限是基于 Linux 的权限管控机制。用户在 Atlas 集群提交训练任务的时候,集群的任务提交工具会自动读取系统上用户的 UID 与 GID 信息,然后将其注入用户提交的任务 Pod 的 SecurityContext 字段,则 Atlas 集群上运行的容器 Pod 内所有容器的进程运行的 UID 与存储系统上的信息一致,保证权限不越界。

节点访问 JuiceFS,实现了多级缓存:

  • 第一级:缓存就是内存的页缓存。

  • 第二级:所有的计算节点的多块 SSD,提供二级的加速能力。

  • 第三级:使用 Ceph。如果 3 块 1t 的 SSD 还是不能支撑用户的数据,那它会从 Ceph 读取。

2021 年初的时候,云知声和 JuiceFS 团队一起把 JuiceFSRuntime 集成到 Fluid 上面。因为以裸机的方式去用缓存,我们发现用户对缓存的可见性比较不好,缓存的清理全部是系统自动做的,用户的可控性没那么高,所以才会把 JuiceFS 集成到 Fluid 。

Fluid 会启动 JuiceFS 相关的组件,包括 FUSE 和 Worker Pod。其中 FUSE Pod 提供了 JuiceFS 客户端的缓存能力,Worker Pod 则实现了对缓存生命周期的管理,Atlas 平台的 AI 离线训练任务通过与 FUSE Pod 客户端交互,进行 AI 训练数据的读取。

通过 Fluid 提供的缓存调度能力以及数据集的可观测性,平台的用户可以通过亲和调度将缓存部署在特定的计算节点上,同时用户能够直观的看到缓存的使用情况(例如缓存数据集的大小、缓存的百分比、缓存的容量等)。

JuiceFS 的建设实践

目前 Atlas 不能访问公网,是在专用的隔离网内,因此我们全部都是私有化部署。

我们生产环境的元数据引擎采用 Redis,2020 年的时候,TiKV 对接到 JuiceFS 还不是很成熟,我们计划首先用 Redis 来做过渡,对象存储的是用 Ceph。Redis 节点的系统盘做了 RAID1,同时 Redis 持久化的数据会定期同步到另一台备份节点上。Redis 的数据持久化我们采用 AOF + RDB 的方案,每秒进行一次数据持久化。

对象存储采用自建的 Ceph 集群,Ceph 集群采用 Cephadm 进行部署,目前生产环境用的是 Octopus 版本。我们当时借鉴了很多业界的方案,对存储器在存储器层面做了一些优化,以及在软件层面也做了相应的调优,主要如下:

服务器层面(参考)

• 42 Cores 256GB 2418T 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 副本

重点提下,要把 Ceph 集群的内核升到比较新的版本,然后开启 io_uring 功能,这样性能会有比较大的提升。在软件方面我们是直接调用了rados 的接口,就不走 S3 协议了,效率会稍微高一点,所有的节点用 100G 的 InfiniBand 高速网络去做互联。

云知声环境中 JuiceFS 对接的对象存储是 Ceph RADOS,JuiceFS 采用 librados 与 Ceph 进行交互,因此需要重新编译 JuiceFS 客户端,建议 librados 的版本要跟 Ceph 的对应,这点要注意一下。如果用 CSI Driver 的时候,在 PV/PVC 的创建,会读取 /etc/ceph/ceph.conf 也要注意版本的支持。

完善的监控体系

现在整个链路比较长了,底层有元数据引擎集群、Ceph 对象存储集群,还有上层的客户端以及业务,每层都要有相应的监控方案。

客户端节点,我们主要是做日志的收集,需要注意的是各个挂载点 JuiceFS 客户端日志要做汇聚,error 告警,避免日志将系统磁盘打爆或者节点无法写。

各个 JuiceFS 客户端也要有相应的监控手段,比如查看各挂载点的 .stat 文件和日志观察指标是否正常,然后看看 Redis 跟 Ceph 集群的 IO 与日志,要保证整个链路都是可控的,这样定位问题就比较方便。

上图是 Ceph 的监控图,因为我们的客户端节点用的是 SSD 的缓存,现在数据基本不会读取到 Ceph,大部分是缓存在读取,所以 Ceph 的流量不大。

上图是 JuiceFS 监控上截取的数据,可以看到节点的基本百分百至百分之九十几都能够命中,缓存命中率还是比较高的,大部分数据还是在走缓存的。

参与 JuiceFS 社区建设

云知声在使用 JuiceFS 社区版的过程中,一直积极参与社区建设。在 2021 年和 JuiceData 团队合作开发了上文中提到的 Fluid JuiceFS Runtime。近期, 我们发现社区版基于目录的配额还没有开发,于是在前几个月我们开发了一个版本,对目录的文件数跟文件大小做了限制, PR 目前已经提交,现在也正在跟 JuiceFS 社区一起进行合并的工作。

JuiceFS 在 Atlas 的使用场景与收益

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

收益一:加速 AI模型训练

1)语音降噪测试

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

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

2)文字识别场景

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

生成了一个 LMDB 的大数据文件,这时候 IO 对带宽的要求比较高,而不是对小文件的性能要求。200G 内存缓存是能支撑整个数据的,所以我们没有走底层的存储,而是直接从客户端读取,整体性能也有比较大的提升。

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

模型调试与数据处理

做代码调试时,多个用户会同时在一台调试机上去运行模型测试,以及代码的遍历,当时统计了大部分用户是会使用一些远程的 IDE,连接到调试节点,然后构建自己的虚拟环境,会把大量的安装包提前安装在Lustre上。

大部分都是几十k 或者几百k 的小文件,要把这些包导入在我们内存上。之前使用 Lustre 时,因为用户太多了所以需求吞吐较高,同时对小文件性能要求比较高,发现效果不是很好,在 import 包时会比较卡,导致代码调试的时候比较慢,整体效率比较低。

后来使用了JuiceFS 客户端的缓存,在第一次编译时也比较慢,但第二次的编译时因为数据已经全部落在缓存上,速度和效率就比较高了,代码跳转也就比较快,代码提示 import 也比较快。用户测试后大概有 2~4 倍的速度提升。

结语

从 Lustre 到JuiceFS

从 2017 年到 2021 的时候,我们用 Lustre 也是比较稳定的,集群存储量少于 50% 的时候,软件的稳定性都是比较高的。

Lustre 作为老牌 HPC 领域的存储系统,为许多全球最大的超算系统提供动力,具有多年的生产环境经验。其具有符合 POSIX 标准、支持各种高性能低时延的网络,允许 RDMA 访问的优点,适用于传统 HPC 领域的高性能计算,跟深度学习的接口是契合的,所有的业务都是不需要做代码修改。但是也有一些缺点:

第一,Lustre 无法支持云原生 CSI Driver。

第二,Lustre 对运维人员的要求比较高,因为全部是以 C 语言写的,有时候出一些 Bug 无法快速解决,整体社区的开放性和活跃度不是很高。

JuiceFS 有这样一些特点:

第一,JuiceFS 是一款云原生领域的分布式存储系统产品,提供了 CSI Driver 以及 Fluid 等方式使用能够更好地与 Kubernetes 进行结合。

第二,JuiceFS 的部署方案比较灵活,元数据引擎可选性高,对象存储如果用户网络允许,其实对接到公有云的对象存储会更好。

第三,在存储扩容运维方面较为简单。完全兼容 POSIX 标准使得深度学习的应用可以无缝迁移,但是由于后端对象存储的特点,使得 JuiceFS 在随机写方面会有较高的延迟。

第四,JuiceFS 支持本地缓存、内核页缓存,实现了冷热数据的分层和加速。这一点是我们比较看重的,在我们的业务场景是比较合适的,但是在随机写的时候就不太合适。社区版本目前分布式缓存的功能也还不提供。

后续规划

• 元数据引擎升级,TiKV 适合在 1 亿以上文件数量(最多可以支撑到百亿级文件),对性能以及数据安全都有较高要求的场景,目前我们已经完成了 TiKV 的内部测试也在积极跟进社区的进展,后续要将元数据引擎迁移到 TiKV。

• 目录配额优化,目前已经把基础版本的功能合入到了JuiceFS 社区版本,也跟 JuiceFS 社区进行了讨论,在一些场景上有些性能还需要优化。

• 希望去做一些 Nonroot 的功能,现在所有的节点都是 root 权限能访问所有的数据,权限太大我们希望只在特定节点去开放 root 的权限。

• 最后也会去看看社区这边的话是否有 QoS 的方案,比如基于 UID 或者 GID 的限速。

云知声: 基于 JuiceFS 的超算平台存储实践的更多相关文章

  1. 趣头条基于 Flink 的实时平台建设实践

    本文由趣头条实时平台负责人席建刚分享趣头条实时平台的建设,整理者叶里君.文章将从平台的架构.Flink 现状,Flink 应用以及未来计划四部分分享. 一.平台架构 1.Flink 应用时间线 首先是 ...

  2. Unity跨平台C/CPP动态库编译---可靠UDP网络库kcp基于CMake的各平台构建实践

    1.为什么需要动态库 a)提供原生代码(native code)的支持,也叫原生插件,但是我实践的是c/cpp跨平台动态库,这里不具体涉及安卓平台java库和ios平台的objectc库构建. b)某 ...

  3. Unity3D跨平台动态库编译---记kcp基于CMake的各平台构建实践

    一 为什么需要动态库 1)提供原生代码(native code)的支持,也叫原生插件,但是我实践的是c/cpp跨平台动态库,这里不具体涉及安卓平台java库和ios平台的objectc库构建. 2)某 ...

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

    云知声是一家专注于语音及语言处理的技术公司.Atlas 超级计算平台是云知声的计算底层基础架构,为云知声在 AI 各个领域(如语音.自然语言处理.视觉等)的模型迭代提供训练加速等基础计算能力.Atla ...

  5. 云知声 Atlas 超算平台: 基于 Fluid + Alluxio 的计算加速实践

    Fluid 是云原生基金会 CNCF 下的云原生数据编排和加速项目,由南京大学.阿里云及 Alluxio 社区联合发起并开源.本文主要介绍云知声 Atlas 超算平台基于 Fluid + Alluxi ...

  6. 乾象投资:基于JuiceFS 构建云上量化投研平台

    背景 乾象投资 Metabit Trading 成立于2018年,是一家以人工智能为核心的科技型量化投资公司.核心成员毕业于 Stanford.CMU.清北等高校.目前,管理规模已突破 30 亿元人民 ...

  7. 基于TFS的.net技术路线的云平台DevOps实践

    DevOps是近几年非常流行的系统研发管理模式,很多公司都或多或少在践行DevOps.那么,今天就说说特来电云平台在DevOps方面的实践吧. 说DevOps,不得不说DevOps的具体含义.那么,D ...

  8. Exadata 18.1新特性--云平台存储节点升级

    1.传统方式的存储节点升级流程: (1).将存储节点升级包下载到数据库服务器,通常是DB01上. (2).解压缩存储节点升级包. (3).用升级包中的patchmgr工具滚动或非滚动地升级每个存储节点 ...

  9. JuiceFS 在数据湖存储架构上的探索

    大家好,我是来自 Juicedata 的高昌健,今天想跟大家分享的主题是<JuiceFS 在数据湖存储架构上的探索>,以下是今天分享的提纲: 首先我会简单的介绍一下大数据存储架构变迁以及它 ...

  10. 白瑜庆:知乎基于Kubernetes的kafka平台的设计和实现

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文首发在云+社区,未经许可,不得转载. 自我介绍 我是知乎的技术中台工程师,现在是负责知乎的存储相关组件.我的分享主要基于三个,一个是简单 ...

随机推荐

  1. csv2ECharts,**一行命令查看数据趋势图 工具分享**

    csv2ECharts 一行命令查看数据趋势图! 联系:luomgf@163.com,欢迎交流提出建议 只有一个文件,基于shell,实现将CSV格式数据转化为数据图.运维中尝尝需要查看某个监控指标的 ...

  2. proxy解决跨域问题

    首先我们在本地开发,域名都是localhost,当我们需要请求后台数据时,就会出现跨域的问题 下面就是在vue.config.js配置文件里: devServer: {     proxy: {    ...

  3. 【pytest官方文档】解读- 插件开发之hooks 函数(钩子)

    上一节讲到如何安装和使用第三方插件,用法很简单.接下来解读下如何自己开发pytest插件. 但是,由于一个插件包含一个或多个钩子函数开发而来,所以在具体开发插件之前还需要先学习hooks函数. 一.什 ...

  4. Python模拟客户端

    本机客户端 import socket # 获取到socket sk = socket.socket() # 获取到地址 ip 和 端口号 server端的 address = ('127.0.0.1 ...

  5. 16.MongoDB系列之分片管理

    1. 查看当前状态 1.1 查看配置信息 mongos> use config // 查看分片 mongos> db.shards.find() { "_id" : & ...

  6. python关于Django搭建简单博客项目(详解一)

    上一篇我们说了如何搭建简易博客网站,下面我们来进行详细解答.本文没有特定顺序,请结合上一篇和源代码参照学习. 相关源代码和解析请参看:https://github.com/Cheng0829/mysi ...

  7. 5.github操作

      Github设置远程仓库 将我们github的https或者ssh远程仓库地址复制 git remote add https://xxxxxxxTest.git # 指定github仓库设置为远程 ...

  8. day02-HTML02

    4.HTML 4.3HTML基本标签 4.3.9表格(table)标签 基本语法: <table border="边框宽度" cellspacing="空隙大小&q ...

  9. 创建外部表步骤及解决ORA-29913:执行ODCIETTABLEOPEN调出时出错

    创建外部表步骤 建立目录对象(用sys用户创建.授权) 外部表所在路径一定要写对!!! create directory ext_data as 'D:\ORACLE'; grant read,wri ...

  10. 京东云开发者|ElasticSearch降本增效常见的方法

    Elasticsearch在db_ranking 的排名又(双叒叕)上升了一位,如图1-1所示;由此可见es在存储领域已经蔚然成风且占有非常重要的地位. 随着Elasticsearch越来越受欢迎,企 ...