关于人工智能:AI-场景的存储优化之路

51次阅读

共计 3293 个字符,预计需要花费 9 分钟才能阅读完成。

人工智能是数据的耗费小户,对存储有针对性的需要。这次咱们讲讲面向 AI 场景的存储性能优化思路。

谈优化之前,咱们先剖析一下 AI 拜访存储的几个特点:

  • 海量文件,训练模型的精准水平依赖于数据集的大小,样本数据集越大,就为模型更准确提供了根底。通常,训练任务须要的文件数量都在几亿,十几亿的量级,对存储的要求是可能承载几十亿甚至上百亿的文件数量。
  • 小文件,很多的训练模型都是依赖于图片、音频片段、视频片段文件,这些文件基本上都是在几 KB 到几 MB 之间,对于一些特色文件,甚至只有几十到几百个字节。
  • 读多写少,在大部分场景中,训练任务只读取文件,把文件读取上来之后就开始计算,两头很少产生两头数据,即便产生了大量的两头数据,也是会抉择写在本地,很少抉择写回存储集群,因而是读多写少,并且是一次写,屡次读。
  • 目录热点,因为训练时,业务部门的数据组织形式不可控,系统管理员不晓得用户会怎么存储数据。很有可能用户会将大量文件寄存在同一个目录,这样会导致多个计算节点在训练过程中,会同时读取这一批数据,这个目录所在的元数据节点就会成为热点。跟一些 AI 公司的共事交换中,大家常常提到的一个问题就是,用户在某一个目录下寄存了海量文件,导致训练的时候呈现性能问题,其实就是碰到了存储的热点问题。

综上,对于 AI 场景来说,分布式存储面临三大挑战:

  1. 海量文件的存储
  2. 小文件的拜访性能
  3. 目录热点

海量文件的存储

首先探讨海量文件存储的问题。海量文件存储的外围问题是什么,是文件的元数据管理和存储。为什么海量文件会是一个难题,咱们看下传统的分布式文件存储架构,以 HDFS,MooseFS 为例,他们的元数据服务都是主备模式,只有一组元数据。这一组 MDS 就会受限于 CPU,内存,网络以及磁盘等因素,很难反对海量文件的存储,也很难给高并发拜访业务提供对应的存储性能。MooseFS 单集群最大只能反对 20 亿的文件数量。传统的分布式文件存储都是针对大文件进行设计的,如果依照每个文件 100MB 计算,只须要 1 千万的文件,其总容量就有 1PB 了,所以对于大文件场景,集群容量是首要思考的问题。但在 AI 场景中状况则不同,咱们后面剖析到,AI 场景中 80% 以上是小文件,一个文件只有几十 KB,文件数量动辄就几十亿,文件的数量成为了文件系统要解决的首要矛盾。

针对这个问题,该如何解决呢?咱们第一反馈就是做横向程度扩大,把单点的 MDS 集群化。横向扩大的元数据集群能够很好地解决单 MDS 的问题。第一,缓解了 CPU,内存的压力;第二,多个 MDS 也能够存储更多的元数据信息;第三,元数据的解决能力也可能程度扩大,进而晋升海量文件并发拜访的性能。

分布式 MDS 的支流架构有三种:

第一种是 动态子树,目录的寄存地位是固定的,目录和文件的元数据以及他们数据都放在该节点上。NFS 是一个典型的动态子树用法,每个 NFS Server 代表了一个元数据节点,只有可能保障各个挂载点的程序和地位统一,多个 NFS Server 能够组成一个分布式的文件存储集群。它的长处是形式简略,不须要代码实现,只须要把多个 NFS Server 拼凑起来,保障挂载点统一就行。对应的,毛病也很显著,一个是运维不不便,各个客户端节点须要保障挂载点统一,须要人工干预,换个说法,这个计划并不是对立的命名空间,会带来保护上的复杂度;另外一个是会有数据热点问题,当一批数据进来后,基本上都会落在同一个 NFS server 上。训练任务读取这批数据的时候,所有的压力也都会集中在这个 NFS server 上,这个节点就会成为热点。

第二种是 动静子树,目录元数据会随着拜访的热度在不同的 MDS 节点上进行迁徙,保障 MDS 之间的负载是平衡的。CephFS 就是采纳的这种形式,动静子树这个概念也是 Ceph 的作者提出来的。实践上来说这是一种绝对完满的架构,打消了热点问题,元数据集群扩容也很不便。然而现实很饱满,事实很骨感,它的工程复杂度比拟高,很难做到稳固。

第三种是Hash,GlusterFS 采纳的是这种形式,当然了 GlusterFS 是采纳的基于门路的 hash 形式。它的长处是文件地位扩散的比拟平均,不会有热点问题。然而劣势也很显著,元数据不足本地性,查问类的操作会很慢(例如对目录进行检索),须要遍历整个集群。

YRCloudFile 采纳的是动态子树 + 目录 Hash 两者联合的形式。这种形式有三个因素:

  1. 根目录在固定的 MDS 节点;
  2. 每一级目录都会依据 Entry name 进行 hash 再次抉择 MDS,保障横向扩大的能力;
  3. 目录下文件的元数据进行寄存时,不进行 hash,而是跟父目录在同一个节点,保障肯定水平的元数据本地性。

这种做法带来两个益处,其一是实现了元数据的散布存储,从而通过扩大元数据节点即可反对百亿级别的文件数量,其二是在肯定水平上保障了元数据的检索性能,缩小在多个节点上进行元数据检索和操作。

小文件的拜访性能

其次,咱们探讨小文件性能拜访。对于小文件,咱们须要晓得几点:第一,为什么关注小文件,前边咱们提到,AI 训练中,大的图片,语音文件通常会切片后进行剖析,有助于剖析特色,训练的文件大小通常在几 KB 到几 MB 之间,小文件的吞吐性能间接影响了 AI 训练效率;第二,小文件的性能瓶颈在哪里,读取一个小文件,须要屡次元数据操作加一次数据操作。通常的改良思路,小文件内联,小文件聚合和客户端读缓存。这部分内容,本文先卖个关子,后续再通过独自的文章论述。

目录热点

最初咱们重点来探讨下目录热点的问题。

从这个图中,咱们能够看到,如果 dir3 目录中有大量文件,比如说几百万,上千万文件,训练的时候,多个计算节点须要同时读这批文件的时候,dir3 所在的 MDS 节点就会变成一个热点。

如何去解决热点问题呢?直观的想法,既然目录变成了一个热点,那就对目录进行拆分。对目录进行拆分有两种思路,一种是目录的镜像扩大,另一种是减少虚构子目录。两种都能解决热点所引发的性能问题。

目录的镜像扩大,就是对指定的目录进行设置,这个目录及其下的文件元数据会在指定的几个 MDS 节点上存在,具体的这些 MDS 节点的地位信息会记录在目录的 inode 中,对这个目录内的文件进行 open/close/unlink 等操作的时候,会依据 filename 进行 hash,找到对应 MDS 节点,再对文件进行操作,这样就把热点问题摊派到了指定的几个 MDS 节点上。整个思路相似于 web 架构中的负载平衡,如图所示。

咱们采纳的是第二种,减少虚构子目录的形式。这种形式尽管多了一层目录的查问操作,然而足够灵便,能够把热点摊派到集群中所有的元数据节点,同时也能够解决另外一个问题,就是单目录的文件数量问题。减少虚构子目录能够很好的解决这个问题,使单目录能够撑持 20 亿左右的文件数量,并且能够依据虚构子目录的数量灵便调整。

咱们通过拜访 /dir1/dir2/file1 举例来看看虚构子目录是如何实现的。假如 dir2 是开启了 dirStripe 性能。拜访流程:

  1. 在 MDS1 上拿到根目录的 inode 信息,查看没有开启 dirStripe
  2. 在 MDS1 上获取 dir1 的 dentry 信息,找到所属 owner(mds2)
  3. 在 MDS2 上拿到 dir1 的 inode 信息,查看没有开启 dirStripe
  4. 在 MDS2 上获取 dir2 的 dentry 信息,找到所属 owner(mds3)
  5. 在 MDS3 上拿到 dir2 的 inode 信息,查看开启了 dirStripe
  6. 依据 file1 的 filename,hash 到虚拟目录 2 上
  7. 在 MDS3 上获取虚拟目录 2 的 dentry 信息,找到所属 owner(mds4)
  8. 在 MDS4 上拿到 file1 的 inode 信息,返回给客户端

测试模仿了 AI 训练中,多个客户端并发拜访同一个目录的场景。图中的后果是减少目录拆分前后的性能比照,从图中能够看到,无论是 hard read, hard write,还是 stat delete,目录拆分后,都有10 倍以上的性能晋升

总结

本文针对海量文件存储、小文件拜访性能、热点拜访三个维度,剖析了面向 AI 场景下,分布式文件系统面临的挑战,以及咱们的应答思路,也心愿借此文和更多技术专家交换如何对 AI 场景下的存储计划进行针对性的优化。

正文完
 0