关于分布式:百亿级分布式文件系统之元数据设计

9次阅读

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

前言

在上一篇《如何实现反对百亿级文件的分布式文件存储》中,咱们简略“鸟瞰”了实现反对海量文件的分布式文件存储的要害思路,本文咱们开始探讨各个模块的设计思路和局部细节。先从元数据服务开始,元数据服务个别被简称为 MDS,示意 MetaData Service,或 MetaData Server。

MDS 数据在磁盘中如何治理

当咱们说要做反对百亿文件的 MDS 时,咱们要做什么?

咱们先从业务需要说起。绝大多数业务,尤其是传统业务,都是习惯应用文件系统的,因为各种编程语言都提供了丰盛的文件接口 SDK,不同的业务依据数据规模应用本地文件系统或 NAS。

咱们先以本地文件系统 ext4 为例,来看一下 ext4 文件系统的特点。

  1. ext4 是针对 HDD 设计的,基于内核 VFS 框架。为了实现更好的性能,ext4 提供给用户应用的接口个别是 buffered IO 接口,读写都通过 pagecache,写数据并不间接落盘,且元数据(inode)也不间接落盘。更进一步地,ext4 应用了 journal jbd2,默认模式是 ordered,示意仅记录元数据的变动,这个 journal 也不是实时落盘的。ext4 这么做是为了提供更好的 IO 性能,但在机器掉电时是可能丢数据的
  2. 如下面提到的,ext4 是 HDD 时代的产物,面对 SATA SSD 甚至是 PCIe SSD 时力有不逮,施展不出硬件的全副性能
  3. ext4 会对硬盘预格式化,格式化后 inode 数量固定,能反对的文件数量也随之固定。当面对海量小文件场景时,inode 率先耗尽,而硬盘理论仍有大量空余空间。
  4. ext4 是没有“原子读写机制”的,即如果业务有一个操作,须要 read file1, write file2, write file3 都胜利才认为胜利,则业务须要本人去做这个组合的原子逻辑,ext4 无奈提供现成的回滚机制。

不少分布式文件系统是基于本地文件系统的,它们都将面临以上提及的这些问题。市面上大多分布式文件系统的 MDS 是基于本地文件系统的,例如 ext4。而有的分布式文件系统则间接用本地文件示意业务文件,即用户视角的一个文件,对应 MDS ext4 里的一个或多个文件,这种形式要面对下面提到的所有问题。还有的分布式文件系统是在 ext4 之上有本人的封装,比方将文件信息形象为 KV,运行时在内存中用 std::map 之类的数据结构示意,并实现 LRU 机制,换入换出到底下 ext4 中,这种形式会面临下面问题的第 1、2、4 点,同时引入了不少工程复杂度,能够了解为这种形式做到极致就是 RocksDB 的特定实现。

通过以上剖析,设计 MDS 时,能够不应用本地文件系统,而是抉择应用 RocksDB。大家晓得 RocksDB 也是基于文件模型的,如果 MDS 应用 RocksDB,但 RocksDB 应用 ext4,那么整个 MDS 依然会受到 ext4 带来的性能限度。咱们理解到 RocksDB 并不强依赖文件系统,因而现实的 MDS 并不应用 ext4,而是间接治理裸盘,并提供一个薄层文件模型去满足 RocksDB 的运行须要。这块内容较多,咱们在下一篇文章来专门探讨 MDS 基于裸盘的 RocksDB 计划的细节。

MDS 如何切片

咱们之所以探讨 MDS 的切片问题,实际上是探讨如何将整个文件系统的元数据通过肯定逻辑搁置在一台或多台 MDS 节点中。

当应用单台服务器做 MDS 时,基于裸盘应用 RocksDB 的计划,相比于间接应用本地文件系统,曾经能治理更多的文件了,但单 MDS 仍有其限度,比方单 MDS 反对的文件数量始终存在下限,单 MDS 对并发申请的解决能力也存在下限。

所以为了设计和实现一个能承载百亿文件的 MDS,必然要做元数据切片,应用多台服务器组成 MDS 集群,每个 MDS 节点治理局部元数据。

接下来,如何对元数据进行切片就成为外围问题。通过调研和积攒,咱们认为,实践上“动态”切片的办法是不能满足所有场景的需要的。直观上这十分好了解,正如上一篇提到的,咱们做大型零碎面临的都是抉择,不会有银弹式完满解法。这里“动态”切片办法是指不思考动静平衡的切片办法,比方通过哈希将新目录定位到指定 MDS 节点。

咱们先来探讨切片计划面临的挑战:

挑战 1:每个切片的数据量是否平衡?

挑战 2:每个切片的 IO 性能是否平衡?

挑战 3:每个切片的访问量是否平衡?

挑战 4:如何无效实现 range query,如 ls 等罕用文件系统操作?

对于挑战 1,在实践中,咱们认为元数据量是否严格地平衡并不那么重要,咱们只有能做到不要让某个 MDS 空间被撑爆,而同时其余 MDS 节点残余大量空间就行。但如果元数据节点的存储空间耗费差距大,可能会影响到 MDS 的拜访性能,这次要是因为数据量大之后内存 LRU 的影响和数据索引的影响。

所以,咱们尽量去放弃元数据空间耗费的平衡。但元数据空间耗费是动态变化的,咱们个别会按目录去定位以及分片,比方通过哈希将某个目录定位到指定的某个 MDS,目录刚开始为空,但随着时间推移,该目录下的文件会逐渐越写越多。

另一个麻烦的问题是如何解决拜访热点。元数据切片固定之后,可能呈现热点目录刚好都在同一 MDS 节点的状况,如果某个切片下的某个目录或某些目录被高频拜访,就会造成热点,如果该 MDS 不能反对这么大的访问量,而其余 MDS 却非常闲暇,这样既浪费资源,又影响性能。

至于挑战 4,ls 等操作是用户常见操作,当目录下文件很多时,ls 操作耗时会很长,本地文件系统如此,个别分布式文件系统更甚之。如果咱们的切片策略尽量让一个目录的元数据搁置于单个 MDS 上,那么切片并不会带来更多的 ls 耗时。

那么现实的分布式文件系统应该采取什么样的元数据分片计划?咱们深刻思考下面的挑战,正如咱们重复提到的一点,大型零碎通常须要在各种问题和挑战之间寻找平衡点,或者做动静的均衡。因而咱们给出的外围设计思路是,给定对立命名空间的目录树,以目录为单位,将目录树拆分到不同 MDS 上,这样保障了数据本地化。至于拆分时的策略是通过 hash,还是通过指定,其实曾经无所谓了,咱们能够采取 hash 策略,即对于给定目录的元数据,通过 hash 为其指定一个所属 MDS。

对于 MDS 切片这一主题,Ceph SC04 发表的论文”Dynamic Metadata Management for Petabyte-scale File Systems”也做了探讨(关注本公众号,回复“SC04”获取论文),通过浏览这篇论文,并延展浏览它援用的一些论文,咱们发现基于目录树并以目录为根本单位的切片计划,不失为一个直观的、正当的切片计划。这篇论文采取了雷同的思路,但采纳了不同的细节办法,也做了更为谨严的试验和剖析,值得大家去扩大浏览。

当然采纳 hash 的形式对元数据依照目录进行划分,也不是万能计划,咱们还须要通过其余伎俩去解决这个计划带来的问题:

每个 MDS 节点优化到极致,使得其可能反对足够多的数据,这样,即便单目录的元数据被 hash 到某个节点,元数据“动态”划分的计划,仍能反对海量文件。此外,通过对共享读写要害门路的 lock critical section 的优化,能够反对高并发拜访,从而应答“热点”目录拜访的挑战。这些都依赖于基于裸盘和 RocksDB 的设计,具体细节咱们将在下一篇探讨。

手动触发的热点迁徙、热点切分机制。反对百亿级别小文件的文件系统设计指标是被海量 (thousands of) 客户端共享拜访的通用型文件系统,个别状况下,不会呈现极其的热点场景,单个目录或几个目录的热点问题,通过单 MDS 的优化曾经可能解决,但万一某个 MDS 治理的所有目录都是热点怎么办,咱们须要设计通过命令触发的热点迁徙机制,将热点迁徙到闲暇 MDS。另外,如果万一某个 MDS 治理的所有目录下都有海量文件,那单 MDS 仍然存在被撑爆的危险,咱们还要设计热点切分机制,将该目录外部划分为多个虚构子目录,将寄存海量文件的目录或热点目录的元数据摊派到其余 MDS 下来。

MDS 多正本机制

下面探讨了 MDS 设计中最重要的两大部分思路,MDS 的数据搁置和治理,以及元数据的切片形式。

除了这两大部分之外,作为一个分布式文件存储,必定还要保证数据的牢靠。咱们应用的也是数据冗余机制,思考到数据特点,咱们举荐 2 正本,因为这在性能、性能和老本间有一个很好的折中。

应用正本机制有两大思考点,一是正本搁置策略,二是正本间数据一致性。

正本搁置策略方面,联合 MDS 目录树切片计划,咱们提供的是将 MDS 节点分组,每组依据正本数设置能够有多台服务器。每组 MDS 之间做正本冗余。这么做一是满足需要,二是设计和实现简略,三是能够起到物理隔离的作用,单台服务器故障的影响面更小。

正本间数据一致性 是分布式畛域常见的问题之一,业界有两大做法,别离是 Paxos 系和主从复制 (Primary Copy Replication)。Paxos 系个别用于低频更新的外围数据的多正本机制,比方在一致性哈希零碎中保护集群视图。MDS 多正本这样的场景个别应用的是主从复制,这样既保证了一致性,也能保障肯定的性能。IO 先从 client 发给主 MDS,主 MDS 写本地的同时,再发给从 MDS,只有主从 MDS 都写胜利,才认为本次 IO 胜利并返回给 client。

一样常见地,咱们应用本地 journal 来保障本地的原子写,应用 transaction log 来保障故障下的主从复原,同时基于 transaction log 咱们也不便做主从同步写或是主从异步写的策略。

须要特地提出,相比应用 ext4 等本地文件系统,基于裸盘治理 +RocksDB 计划,实现本地 journal 和 transaction log 更为不便,效率也更高。

MDS 设计要点总结

上一篇《如何实现反对百亿级文件的分布式文件存储》咱们抽象地探讨了设计反对百亿级文件的分布式文件存储的思路,本文咱们探讨了元数据集群 MDS 三大方面的设计思维:元数据管理计划、元数据切分计划和多正本机制。下一篇咱们将探讨本地裸盘治理 +RocksDB 计划的设计和实现细节,后续咱们还将一直地做其余组件的设计思路、计划和实现方面的探讨。

当然,文字表白不如当面探讨直观,文章再具体,也总会漏掉不少信息。咱们次要探讨外围思路和模块,外部的各个小方面的实现抉择和细节,不同实现都会有很多出彩之处,但出于篇幅和宗旨,在文章里,咱们就疏忽了。咱们十分欢送有趣味的敌人们留言探讨,也十分欢送有趣味的敌人们来实高空基,更是十分欢送有趣味的敌人们退出咱们,一起去探讨、抉择和实现更好的计划、更好的代码。

咱们下一篇见。

正文完
 0