基于 JuiceFS 构建高校 AI 存储方案:高并发、系统稳定、运维简单

juicefs,ai · 浏览次数 : 0

小编点评

本文主要介绍了中山大学iSEE实验室在选择替代存储方案时,经过评估后选择了JuiceFS作为深度学习场景下的存储解决方案。文章详细讨论了JuiceFS的优势、搭建过程以及在实践中遇到的挑战和解决方案。 1. **深度学习场景存储需求**: - 实验室集群主要用于深度学习训练,存在大量小文件读取需求。 - 存储系统需具备高并发稳定性、消除单点故障、友好运维特性以及POSIX接口。 2. **为何选择JuiceFS**: - JuiceFS支持POSIX接口,易于迁移和用户使用。 - 缓存功能对于深度学习模型训练非常重要。 - 提供数据恢复可能性,简化运维。 3. **搭建基于JuiceFS的存储系统**: - 使用TiKV作为元数据引擎,SeaweedFS作为对象存储。 - 用户文件目录和数据集目录分别挂载,以提高性能。 - 配置了专门的元数据引擎和数据节点,以实现高可用性和数据安全性。 4. **为什么使用对象存储SeaweedFS**: - SeaweedFS易于操作,适合AI领域学生组成的集群管理团队。 - 提供数据冗余备份,提高数据安全性。 - 实现负载均衡,提高系统稳定性。 5. **方案实践中遇到的挑战**: - 客户端异常退出问题,通过添加--no-bgjob选项解决。 - 首次读取大文件速度慢,通过指定--storage s3选项优化。 - 解压数据集较慢,考虑使用write-back加速功能。 总的来说,JuiceFS凭借其高性能、易用性和稳定性,成功解决了实验室在深度学习存储方面遇到的问题,为AI领域的研究提供了有力的支持。

正文

中山大学的 iSEE 实验室(Intelligence Science and System) Lab)在进行深度学习任务时,需要处理大量小文件读取。在高并发读写场景下,原先使用的 NFS 性能较低,常在高峰期导致数据节点卡死。此外,NFS 系统的单点故障问题也导致一旦数据节点宕机,该机器上的数据将完全不可用。扩容问题同样棘手,每增加一台数据节点,就需要在所有计算节点上进行多次挂载。而新增的数据节点由于数据量较小,并不能有效分担读写压力。

为解决这些问题,经过初步评估,实验室选择了JuiceFS 作为替代的存储方案。当前,结合TiKV 的 JuiceFS 已成功管理超过 5 亿个文件。新方案显著提升了在高并发场景下的性能和系统稳定性,确保了深度学习训练过程中计算节点的连续运行,同时基本解决了单点故障的问题。

此外,JuiceFS 的操作简便易学,甚至不需要专职的存储管理人员来维护,这对于主要由 AI 领域学生组成的实验室集群管理团队来说,极大减轻了他们的运维负担。本文将详细介绍新方案的选型与实践历程。

01 深度学习场景存储需求

实验室集群主要用于深度学习的训练和方法验证。在训练过程中,我们面临四种主要的读写需求。

  1. 训练过程中需要读取大量的数据集文件。

  2. 在模型训练的初始阶段,我们需要加载一个 Conda 的环境,这涉及读取众多不同大小的库文件。

  3. 在训练过程中,随着模型参数的调整,我们需要频繁地写入不同大小的模型参数切换文件,这些文件的大小可能从几十兆字节到数几字节不等,具体取决于模型的大小。

  4. 我们还需要记录(每次训练的)训练日志,这主要涉及到少量数据的频繁写入。

基于上述需求,我们对存储系统有以下四个主要期望:

  • 首要的是,系统在高并发的读写环境下应具备出色的稳定性。在确保稳定性的基础上,我们再追求性能的提升。

  • 其次,我们希望系统能够消除单点故障,即任何节点的故障都不应影响整个集群的训练进程。

  • 第三,我们期望系统具有友好的运维特性。考虑到我们实验室团队成员主要专注于 AI 深度学习,对存储系统的专业知识了解有限,因此我们需要一个运维简便、维护频率较低的存储系统。

  • 最后,我们希望系统能够提供一个 POSIX 接口。由于我们使用 PyTorch 框架进行模型训练,如果系统支持 POSIX 接口,将极大地降低用户的学习成本,同时减少对现有代码的改动。

实验室现有的硬件配置

首先,我们的硬件系统主要包括三类设备。

第一类是数据节点,我们目前拥有大约三四台这样的数据节点。这些节点主要由大量机械硬盘构成,每个节点的机械硬盘都搭建RAID6阵列,所有节点加起来的总存储容量近 700TB。

第二类是我们的计算节点,这些节点主要搭载了 GPU,用于处理计算密集型任务。在存储方面,由于 JuiceFS 具有缓存功能,我们为这些节点配备了 1 至 3 个 SSD 缓存盘,每个盘的大小约为 800GB。尽管这些缓存盘的大小看起来并不庞大,但它们通常能够缓存多个完整的数据集,前提是数据集的大小适中。

第三类是基于我们使用 TiKV 作为元数据引擎的考量,我们配置了三个 TiKV 节点,专门用于作为元数据引擎运行。这些节点的数据盘容量大约为 2TB,内存则主要配置了 512GB。根据目前的使用情况,当处理大约 5 至 6 亿的文件量时,每台节点大约使用了 300 多 GB 的内存。

NFS 的存储解决方案所面临的挑战

在初期,当计算节点数量较少时,我们采用了在数据节点上构建单机文件系统的策略,并通过简单的 NFS 挂载方式,将这些文件系统挂载到各个计算节点的目录上。这样,当需要添加第二台数据节点时,我们只需将其挂载到新的目录上,即可实现数据在所有节点间的共享。此方案在运维上相对简单,但随着节点数量的增加,我们逐渐发现基于 NFS 的存储系统性能显著下降。

在高并发训练高峰期,系统常出现明显的卡顿甚至卡死现象,这极大地影响了我们的工作效率。为了缓解这一问题,我们曾尝试将集群划分为两个小集群,以减少每个节点的数据压力。然而,这一临时措施并未带来显著的改进,反而带来了新的问题,如不同集群间数据的互通性受限。

总的来说,我们在处理大量小文件读取的场景下,原有的 NFS 存储方案表现出了较低的读取性能和较高的宕机风险。此外,整个系统缺乏缓存机制,而深度学习数据集在训练过程中需要频繁读取,这无疑增加了读写压力。因此,我们需要寻找一种更为高效、稳定的存储解决方案,以应对这些挑战。

02 为何选择 JuiceFS

以下是我们选择 JuiceFS 的主要原因:

  • JuiceFS 支持 POSIX 接口,这意味着在迁移系统时,用户几乎不会感受到任何影响,实现了无感的迁移体验。

  • JuiceFS 的缓存功能对于深度学习模型的训练尤为重要。尽管在首轮数据加载时可能无法直接命中缓存,但随着训练的进行,后续轮次几乎能够百分之百地利用缓存,从而显著提升训练过程中的数据读取速度。

  • JuiceFS 的回收站功能为用户提供了数据恢复的可能性,我们设置的为期一天的回收站使得误删的文件在一天内得以恢复,这在实际应用中已帮助用户及时恢复了误删的数据。

  • JuiceFS 还配备了一系列特有的文件管理命令,这些命令不仅方便用户使用,而且相较于传统文件系统,其功能更为快速和高效。

  • 值得一提的是,在运维层面,JuiceFS 的表现格外出色。由于我们实验室没有专职的人员负责存储,我们期望的存储系统应具备简单性和低运维频率的特点,而 JuiceFS 恰好满足了这些需求。它提供了丰富的文档资源,使得我们在上手和解决问题时能够迅速找到解决方案。JuiceFS 能够自动备份元数据,为数据提供了额外的保护层,增强了我们的安全感。JuiceFS 自带的 Prometheus 和 Grafana 监控功能使得我们能够方便地在网页端查看整个系统的状态,包括文件数量的增长情况、文件使用量以及整个系统的大小等关键信息,这为我们提供了及时的系统监控和管理的便利。

03 搭建基于 JuiceFS 的存储系统

首先,我们的 JuiceFS 采用了 TiKV 作为元数据引擎,同时利用 SeaweedFS 作为对象存储。

总体来看,JuiceFS 分为两个目录进行挂载。第一个目录用于存储用户文件,采用独立挂载的方式使我们能够灵活调整挂载参数,以满足不同目录的特定需求。在用户文件目录方面,我们主要沿用了默认的挂载参数,以确保稳定性和兼容性。

第二个在数据集目录方面,鉴于其几乎只读的特性,我们特别增加了元数据缓存的失效时间。这样做可以在多次读取过程中多次命中元数据缓存,从而避免重复访问原始数据,显著提升数据访问的速度。正是基于这一改动,我们选择了将数据集和用户文件分别挂载于两个不同的目录。

此外,我们还进行了一项实践上的优化。考虑到计算节点的主要任务是处理计算任务而非后台任务,我们在一台相对空闲的节点上配备了较大的内存,专门用于处理后台任务,如备份元数据。随着文件数量的增加,备份元数据对内存的需求也逐渐增大,因此这种分配方式既确保了计算节点的性能,又满足了后台任务对资源的需求。

元数据引擎选型:Redis vs TiKV

起初,我们使用了两个数据引擎:Redis 和 TiKV。在数据量相对较小,即上千万级别的阶段,我们选择了 Redis。当时,由于我们对这些软件并不十分熟悉,我们参考了相关文档,并考虑到 Redis 的上手难度较低、性能较高,且相关资料丰富,因此决定采用它。然而,随着文件数量的迅速增长,Redis 的性能出现了显著的下降。

具体来说,由于我们为 Redis设 置了 RDB 持久化,当内存占用量增加时,Redis 几乎持续处于 RDB 备份状态,这导致了性能的明显下滑。另外,我们当时采用了哨兵模式,并启用了主从复制以增加可用性,但这也带来了问题。由于是异步复制,主节点宕机后,从节点的数据一致性难以保证。

此外,我们了解到客户端并不会从 Redis 的从节点上读取元数据,而是主要依赖主节点进行读写操作。因此,随着文件数量的增加,Redis 的性能进一步下降。

随后,我们考虑并测试了 TiKV 作为元数据引擎的替代方案。从官方文档来看,TiKV 的性能仅次于 Redis,并且在实际使用中,用户层面的体验与 Redis 相差不大。在数据量达到 5 至 6 亿文件的情况下,TiKV 的表现相当稳定。

TiKV 的另一个优势在于其负载均衡和冗余存储的能力。我们采用了三台节点的配置,每个节点都具备多个副本,确保了数据的安全性和可用性。对于运维团队来说,这些特性极大地减轻了工作负担,提高了系统的稳定性和可靠性。

元数据迁移 :从 Redis 到 TiKV

我们于今年一月份左右进行了系统迁移,并已经稳定使用 TiKV 近半年,期间未出现宕机或任何重大问题。

在迁移初期,由于 Redis 难以支撑高达 5 至 6 亿文件的元数据负载,我们决定采用导出与导入的方法来实现迁移。具体地,我们使用了特定的命令将 Redis 中的元数据导出为统一的 JSON 文件,并计划通过 load 命令将其加载到全新的 TiKV 系统中。

然而,在迁移过程中,我们遇到了一个挑战。我们注意到,某个用户的目录由于文件深度过深或其他原因,在导出时遇到了失败。为了解决这个问题,我们采取了一种创新的方法。我们将除问题目录外的其他所有目录分别导出,并手动打开和拼接这些 JSON 文件,以重新构建完整的元数据结构。

在手动处理这些文件时,我们发现元数据的 JSON 文件结构清晰,拼接操作相对简便。其嵌套结构与目录结构基本一致,这使得我们能够高效地处理元数据。最终,我们成功地将这些文件导入到 TiKV 中,完成了迁移过程。

04 为什么使用对象存储 SeaweedFS?

总体而言,我们遵循了 SeaweedFS 官方文档中推荐的主要组件和基本功能,并未涉及过多新颖或高级特性。在具体部署上,我们采用了 CPU 节点作为核心,并在其上运行了 master 服务器。而数据节点则分布运行在不同的物理节点上,每个节点均运行 volume 服务以处理数据存储。此外,我们在相同的 CPU 节点上运行了 filer 服务器,该服务器为 JuiceFS 提供 S3 服务接口,负责与 JuiceFS 进行对接。从目前的运行情况来看,CPU 节点的负载并不重,主要的数据读写和处理任务均分散在各个 worker 节点上。

在数据冗余和备份方面,我们充分利用了 SeaweedFS 的冗余特性。逻辑上,我们将数据节点划分为两个 Rack。当数据写入时,它会在两个 Rack 中都进行写入,确保在 Rack 0 和 Rack 1 中各有一份备份。只有当两个 Rack 都成功写入数据时,才视为写入成功。虽然这种策略使得我们的硬盘容量在逻辑上几乎减半(因为每份数据都要写两份),但它确保了系统的高可用性和数据安全性。即使其中一个 Rack 中的某个节点出现故障或宕机,也不会影响整体的读写操作和数据安全。

SeaweedFS 的优缺点

首先,从上手难度来看,SeaweedFS 相较于工业界广泛使用的 Ceph,显得更为容易操作。其 master、volume 和 filer 等核心组件均可通过编写脚本来轻松启动。用户只需浏览对应的命令参数,并根据实际需求进行配置,随后通过脚本即可完成启动过程。尽管 SeaweedFS 的文档资料相对较少,但其易用性依然值得肯定。

此外,与另一款常用的对象存储系统 Minio 相比,尽管我们未曾直接使用过 Minio,但根据以往案例和介绍,Minio 在处理大量小文件时可能存在一定的不足。因此,我们在选择时并未考虑 Minio。

SeaweedFS 的另一个显著优点在于其安全性和可用性。通过将数据节点划分为两个 Rack,系统实现了数据的冗余备份,从而提高了数据安全性。同时,其master服务器具备自动调度数据写入的功能,能够自动将数据分配到各个 worker 节点上,实现了负载均衡。此外,SeaweedFS 的扩容过程也相对简单,只需新增机器并连接到 master 节点,系统即可自动进行扩容。

此外,SeaweedFS 官方还推荐了一款 master 管理脚本,该脚本配置简单,仅需编写少量配置即可实现定期自动修复数据冗余和平衡数据分布的功能,极大地提高了系统的维护效率。然而,SeaweedFS 的缺点也不容忽视。其文档资料相对较少且较为陈旧,这可能会给新用户带来一定的学习难度。尽管我们在使用过程中并未遇到其他明显的缺点,但这也是未来需要改进的地方。

05 方案实践中遇到的挑战

使用过程中客户端会异常退出

首先,我们曾遭遇客户端异常退出的情况,经过分析发现这是由于内存溢出(OOM)导致的。随着原数据的不断增长,当计算节点未启用 --no-bgjob 选项时,特定节点因执行高内存消耗任务(主要是自动元数据备份)而导致剩余内存不足,进而无法备份原数据,最终引发 OOM 并导致客户端退出。为了解决这个问题,我们在所有计算节点上添加了--no-bgjob 选项,并利用闲置的数据节点作为专门的后台任务处理节点。

首次大文件的读取较慢

其次,我们在使用初期发现了一个性能问题。特别是在首次读取大文件时,发现读取速度远低于千兆网络带宽的极限。经过深入调查,我们发现这是由于在测试对象存储性能时,未正确配置 JuiceFS 命令的参数。我们没有指定 --storage s3 选项,导致测试默认为本地硬盘性能,而非实际的对象存储性能。这一误解导致了我们对对象存储性能的误判。通过进一步检查,我们发现 SeaweedFS Filer 元数据引擎的性能瓶颈,这主要是因为底层使用的是单个机械硬盘。因此,我们将考虑优化这一环节以提升性能。

解压数据集较慢(大量小文件写入)

最后,我们在日常使用中偶尔需要解压数据集,这涉及到大量小文件的写入操作。我们发现这一过程相较于本地解压明显较慢。在与 JuiceFS 官方沟通后,他们建议我们尝试使用 write-back 加速功能。这一功能允许在文件写入后立即返回,而后台则负责将数据上传到对象存储。我们计划在未来实施这一建议以优化解压性能。

希望这篇内容能够对你有一些帮助,如果有其他疑问欢迎加入 JuiceFS 社区与大家共同交流。

与基于 JuiceFS 构建高校 AI 存储方案:高并发、系统稳定、运维简单相似的内容:

基于 JuiceFS 构建高校 AI 存储方案:高并发、系统稳定、运维简单

中山大学的 iSEE 实验室(Intelligence Science and System) Lab)在进行深度学习任务时,需要处理大量小文件读取。在高并发读写场景下,原先使用的 NFS 性能较低,常在高峰期导致数据节点卡死。此外,NFS 系统的单点故障问题也导致一旦数据节点宕机,该机器上的数据将

稳定、省钱的 ClickHouse 读写分离方案:基于 JuiceFS 的主从架构实践

Jerry 是一家位于北美的科技公司,利用人工智能和机器学习技术,简化汽车保险和贷款的比价和购买流程。在美国,Jerry 的应用在其所属领域排名第一。 随着数据规模的增长,Jerry 在使用 AWS Redshift 时遇到了一些性能与成本的挑战。Jerry 重新设计了系统架构,使用 ClickHo

基于 Three.js 的 3D 模型加载优化

作为一个3D的项目,从用户打开页面到最终模型的渲染加载的时间也会比普通的H5项目要更长一些,从而造成大量的用户流失。为了提升首屏加载的转化率,需要尽可能的降低loading的时间。这里就分享一些我们在模型加载优化方面的心得。

基于MindSpore实现BERT对话情绪识别

本文分享自华为云社区《【昇思25天学习打卡营打卡指南-第二十四天】基于 MindSpore 实现 BERT 对话情绪识别》,作者:JeffDing。 模型简介 BERT全称是来自变换器的双向编码器表征量(Bidirectional Encoder Representations from Trans

基于 Vagrant 手动部署多个 Redis Server

环境准备 宿主机环境:Windows 10 虚拟机环境:Vagrant + VirtualBox Vagrantfile 配置 首先,我们需要编写一个 Vagrantfile 来定义我们的虚拟机配置。假设已经在 D:\Vagrant\redis 目录下创建了一个 Vagrantfile,其内容如下:

基于EF Core存储的Serilog持久化服务

前言 Serilog是 .NET 上的一个原生结构化高性能日志库,这个库能实现一些比内置库更高度的定制。日志持久化是其中一个非常重要的功能,生产环境通常很难挂接调试器或者某些bug的触发条件很奇怪。为了在脱离调试环境的情况下尽可能保留更多线索来辅助解决生产问题,持久化的日志就显得很重要了。目前Ser

基于EF Core存储的国际化服务

前言 .NET 官方有一个用来管理国际化资源的扩展包Microsoft.Extensions.Localization,ASP.NET Core也用这个来实现国际化功能。但是这个包的翻译数据是使用resx资源文件来管理的,这就意味着无法动态管理。虽然官方有在文档中提供了一些第三方管理方案,但是都不太

基于FileZilla上传、下载服务器数据的方法

本文介绍FileZilla软件的下载、配置与使用方法。 在之前的博客中,我们提到了下载高分遥感影像数据需要用到FTP(文件传输协议,File Transfer Protocol)软件FileZilla;这一软件用以在自己的电脑与服务器之间相互传输数据,在进行下载科学数据、网站开发等等操作时,经常需要

Vite5+Electron聊天室|electron31跨平台仿微信EXE客户端|vue3聊天程序

基于electron31+vite5+pinia2跨端仿微信Exe聊天应用ViteElectronChat。 electron31-vite5-chat原创研发vite5+electron31+pinia2+element-plus跨平台实战仿微信客户端聊天应用。实现了聊天、联系人、收藏、朋友圈/短

基于 .net core 8.0 的 swagger 文档优化分享-根据命名空间分组显示

之前也分享过 Swashbuckle.AspNetCore 的使用,不过版本比较老了,本次演示用的示例版本为 .net core 8.0,从安装使用开始,到根据命名空间分组显示,十分的有用