您的位置  > 互联网

维基百科:文件系统中比较常见的操作系统的定义

维基百科对文件系统的定义是:

在 中,文件是一个 和 数据,用于确定数据的形式和 。

简单来说,文件系统的工作就是管理存储介质(如磁盘、SSD、CD、磁带等)上的数据。 文件系统中最基本的概念是文件和目录。 所有的数据都会对应一个文件,这些数据通过目录以树形结构进行管理和组织。 基于文件和目录的组织结构,可以进行一些更高级的配置,例如配置文件的权限、统计文件大小、修改时间、限制文件系统容量上限等。

下面列出了不同操作系统中常见的一些文件系统:

(图片来源:《》第10.2.5节)

上图展示了Linux内核的架构。 左边的文件区域是虚拟文件系统,简称VFS。 其功能旨在帮助Linux适应不同的文件系统。 VFS提供了通用的文件系统接口,不同的文件系统实现需要适应这些接口。

日常使用Linux时,所有的系统调用请求都会先到达VFS,然后VFS再向下请求实际使用的文件系统。 文件系统设计者需要遵守VFS接口协议来设计文件系统。 接口是共享的,但是文件系统的具体实现不同,每个文件系统可以有自己的实现。 不同的存储介质有自己的组织和存储数据的方式。

一次写操作的请求过程(图片来源:《Linux》第13层)

上图是一次写操作的请求流程。 在Linux中写文件实际上是一个write()系统调用。 当调用write()操作请求时,首先会到达VFS,然后VFS调用文件系统,最后文件系统将实际数据写入本地存储介质。

目录树(图片来源:《》第4.2.2节)

上图显示了目录树的结构。 在文件系统中,所有的数据都是以这样的树的结构来组织的。 从顶部根节点向下,有不同的目录和不同的文件。 这棵树的深度是不确定的,相当于目录的深度,是由每个用户决定的。 树的叶节点是每个文件。

文件描述符和inode(图片来源:《》第10.6.3节)

最右边的inode是各个文件系统的内部数据结构。 这个inode可以是一个目录,也可以是一个普通文件。 inode会包含文件的一些元信息,比如创建时间、创建者、属于哪个组、权限信息、文件大小等。此外,每个inode还会有一些指向文件上数据块的指针或索引。实际的物理存储介质。

以上是实际访问独立文件系统时可能涉及到的一些数据结构和流程。 作为介绍,让大家对文件系统有一个更直观的认识。

分布式文件系统架构设计

独立的文件系统已经可以满足我们大部分使用场景的需求,管理日常需要存储的大量数据。 然而,随着时代的发展,数据的爆发式增长,对数据存储的需求也越来越大,分布式文件系统应运而生。

上面列出的是一些大家都比较熟悉或者使用较多的分布式文件系统。 公司内部使用的有开源文件系统和闭源产品。 从这张图中,我们可以看到一个非常集中的时间点。 2000年左右,大量分布式系统诞生。 这些分布式文件系统在我们的日常工作中还是或多或少的与我们接触过。 2000年之前,已经有各种共享存储、并行文件系统、分布式文件系统,但它们基本上都是基于一些专用且相对昂贵的硬件构建的。

自2003年GFS(File)论文发表以来,极大地影响了大量分布式系统的设计理念和思路。 GFS证明我们可以使用相对便宜的通用计算机来构建功能强大、可扩展且可靠的分布式存储,并定义完全基于软件的文件系统,而无需依赖许多专有或昂贵的硬件资源。 构建分布式存储系统。

因此GFS大大降低了分布式文件系统的使用门槛,因此在后续的各种分布式文件系统中或多或少都能看到GFS的影子。 比如雅虎开源的HDFS,基本上就是按照GFS论文实现的。 HDFS是目前大数据领域应用最广泛的存储系统。

上图第四列的“POSIX ”表示这个分布式文件系统与POSIX标准的兼容性。 POSIX(POSIX)是一组用于标准化操作系统实现的标准,其中包括与文件系统相关的标准。 所谓POSIX兼容性,是指它满足该标准中定义的文件系统应具备的所有特性,而不是仅仅满足GFS等少数几个特性。 虽然它是一个突破性的分布式文件系统,但它实际上并不是一个 POSIX 兼容的文件。 系统。

当时设计GFS时做了很多权衡。 它抛弃了传统独立文件系统的很多特性,保留了当时搜索引擎场景的一些分布式存储需求。 所以严格来说,GFS并不是一个兼容POSIX的文件系统,但是它给大家一个启发,分布式文件系统也可以这样设计。

接下来,我将重点以几个比较有代表性的分布式文件系统架构为例,向大家介绍一下如果要设计一个分布式文件系统,需要哪些组件以及可能遇到的一些问题。

政府财政司司长

(图片来源:档案纸)

首先,我们以最被提及的GFS为例。 虽然它是在 2003 年发布的,但我认为它的设计仍然很流行,并且有很多值得学习的地方。 GFS的主要组件可以分为三个块。 最左边的GFS是它的客户端,然后中间的GFS是它的元数据节点。 最下面的两个块是GFS,它是实际存储数据的节点。 之间通过网络进行通信,因此它是一个分布式文件系统。 随着数据量的增长可以继续水平扩展。

其中GFS的两个核心部分是sum。 如果我们要实现一个文件系统,我们需要维护文件目录、属性、权限、链接等信息。 这个信息就是文件系统的元数据,这个元数据信息需要保存在中心节点中。 还包含树形结构的元数据设计。

当涉及到存储实际的应用程序数据时,最终落在每个节点上,然后依赖本地操作系统的文件系统来存储这些文件。

和 之间会有联系。 例如,当客户端发起请求时,需要首先获取当前文件的元数据信息,与其通信,然后获取实际数据。 GFS 中的所有文件都存储在块中。 例如,对于1GB的大文件,GFS会按照固定大小(64MB)对文件进行分块。 分块后,会分发到不同的服务器上。 所以当你读取同一个文件时,它实际上可能涉及不同的通信。

同时,每个文件的chunk都会有多个副本,以保证数据的可靠性。 这是一个非常经典的分布式文件系统设计。 现在很多开源的分布式系统实现都或多或少有GFS的影子。

这里不得不提一下,GFS的下一代产品:。 由于GFS的架构设计存在明显的可扩展性问题,内部基于GFS的研发仍在继续。 它不仅为谷歌内部的各种产品提供存储能力,而且作为谷歌云服务的存储基地,向公众开放使用。 该设计增强了存储可扩展性并提高了可用性,以应对数据需求的大规模增长。 下面介绍的也是一个基准存储系统。 由于篇幅限制,本博客不再进一步介绍。 有兴趣的朋友可以阅读官方博客。

(图片来源:来自纸上)

它是目前Meta()内最大的分布式文件系统。 该项目于 2014 年左右启动(之前称为 Warm),但直到 2021 年才发表论文介绍整个分布式文件系统的架构设计。

Meta公司在研发之前主要使用HDFS,内部使用f4来存储数据。 HDFS用于数据仓库场景(受限于单集群存储容量,部署了几十个集群),f4用于非结构化数据存储。 场景。 定位就是满足集群中这三类存储支持的业务场景需求。 与GFS一样,它主要由三部分组成,即Store和Chunk Store。

比较创新的一点是,它在这一层进行了分层处理,以及存储与计算分离的架构设计。 从架构图中我们可以看到它分为三层:Name层、File层和Block层。

传统的分布式文件系统将所有元数据视为同一类型的数据,并没有明确区分它们。 设计中,Name层是与文件或目录结构的名称相关的元数据,File层是与当前文件本身的一些属性相关的数据,Block层是各个数据块在文件中的位置的元数据。大块商店。

之所以采用这样的分层设计,是因为它是一个非常大规模的分布式文件系统,尤其是Meta级别(EB级别的数据)。 如此规模,对Store的负载能力和可扩展性都有非常高的要求。

第二个创新在于元数据存储与计算分离的设计。 前面提到,这三层实际上是无状态的,可以根据业务负载进行水平扩展。 但上图中的Key-value Store是一个有状态的存储,层和Key-value Store通过网络进行通信。

Key-value Store并不是完全自己开发的,而是利用Meta内部的分布式KV存储来支持元数据存储。 它是一个基于Paxos共识算法的分布式KV存储。 依赖的KV存储及其提供的事务保证了整个文件系统元信息的一致性和原子性。

这里的交易功能是非常重要的一点。 为了实现大规模的分布式文件系统,我们必须横向扩展元数据存储。 水平扩展引入了数据碎片的问题。 众所周知,强一致性是文件系统中至关重要的语义。 然而,在实现数据分片的同时保持强一致性是分布式文件系统设计的关键挑战。 例如,当重命名包含多个子目录的目录时,我们需要找到一种在整个重命名过程中既高效又一致的方法。

实现上是依靠底层的事务特性,保证在只涉及单个分片的元数据时,文件系统操作必须是事务性的、强一致的。 但由于不支持跨分片事务,因此在处理跨目录元数据请求(例如将文件从一个目录移动到另一个目录)时无法保证原子性。

Chunk Store层也有创新。 如上所述,GFS通过多副本保证数据的可靠性和安全性。 多个副本的最大缺点是其存储成本。 例如,您可能只存储1TB的数据,但传统上您会保留三份,因此至少需要3TB的空间来存储,这会导致存储成本增加一倍。 对于小规模的文件系统来说可能还好,但是对于Meta这样的EB级别的文件系统来说,三副本的设计机制会带来非常高的成本,所以他们在Chunk Store层使用了EC(Code),也就是擦除。 代码来实现它。 这样,只需要大约1.2到1.5倍的冗余空间就可以保证整个集群数据的可靠性和安全性。 与三副本冗余机制相比,节省了大量的存储成本。 EC设计非常详细,可以针对每个chunk进行配置,非常灵活。

它还支持多副本,具体取决于上层业务需要什么存储形式。 EC不需要特别大的空间来保证整体数据的可靠性。 但EC的缺点是当数据损坏或丢失时,重建数据的成本非常高,需要额外消耗更多的计算和IO资源。

从论文中我们了解到,Meta最大的集群目前拥有约4000个存储节点,总容量约100亿个文件。 这个文件大小对于分布式文件系统来说也是一个比较大的规模了。 在实际应用中,百亿级别基本可以满足目前大部分的使用场景。

(图片来源:来自纸上)

我们来看看各层的设计。 Name、File、Block三层实际上对应的是底层KV存储中的数据结构如上图所示。 例如Name层使用目录ID作为key进行分片,File层使用文件ID进行分片,Block层使用块ID进行分片。

将分布式文件系统的元数据抽象成简单的KV模型,这样可以很好的进行水平扩展和负载均衡,并且可以有效防止数据访问的热点。

它诞生于2017年,晚于GFS和GFS。 与前两个系统的诞生年代相比,外部环境发生了翻天覆地的变化。

首先,硬件资源突飞猛进。 作为对比,当年机房的网络带宽只有(数据来源:The File论文),但现在AWS上机器的网络带宽已经达到了过去的1000倍!

其次,云计算已进入主流市场。 无论是公有云、私有云还是混合云,企业已经进入“云时代”。 云时代给企业基础架构带来了新的挑战。 基于IDC环境设计的传统基础设施一旦想要迁移到云端,可能会面临各种问题。 如何最大限度地发挥云计算的优势,是基础设施更好地融入云环境的必要条件。 固守旧习惯只会事半功倍。

同时,GFS和GFS是只服务于公司内部业务的系统。 虽然规模较大,但要求相对单一。 它的定位是服务大量外部用户,满足多样化场景的需求,因此其架构设计也与这两种文件系统有很大不同。

基于这些变化和差异,我们再来看一下架构。 同样,它也由3部分组成:元数据引擎、数据存储和客户端。 虽然总体框架类似,但各个部分的设计其实还是有些不同的。

首先是数据存储部分。 与GFS以及使用自研数据存储服务相比,架构设计符合云原生时代的特点,直接使用对象存储作为数据存储。 前面我们看到有4000多台服务器用来存储EB级别的数据。 可想而知,如此大规模的存储集群的运维成本一定不小。 对于普通用户来说,对象存储的好处是开箱即用、容量灵活、运维复杂度大幅降低。 对象存储还支持对象存储中使用的EC特性,因此与一些多副本分布式文件系统相比,存储成本可以降低很多。

但对象存储的缺点也很明显,比如不支持对象的修改、元数据性能较差、无法保证强一致性、随机读性能较差等。这些问题通过设计独立的元数据引擎、三层Chunk、Slice、Block的数据架构设计以及多级缓存。

第二个是元数据引擎,可以使用一些开源数据库作为元数据的底层存储。 这与上一个非常相似,但更进一步。 它不仅支持分布式KV,还支持Redis、关系数据库等存储引擎,让用户根据自己的使用场景灵活选择最适合的解决方案。 这是基于通用文件系统的架构设计定位。 使用开源数据库的另一个好处是,这些数据库通常完全托管在公有云上,因此用户的运维成本几乎为零。

前面提到,为了保证元数据的强一致性,选择了这种支持事务的KV存储。 但只能保证单分片元数据操作的事务性,并且对事务性有更严格的要求,需要保证全局强一致性。 性能(即需要跨分片事务性)。 因此,目前支持的所有数据库都必须具有单机或分布式事务特性,否则没有办法将它们连接为元数据引擎(一个例子是Redis不支持跨槽事务)。 基于可水平扩展的元数据引擎(如TiKV),目前单个文件系统可存储超过200亿个文件,满足企业海量数据的存储需求。

上图是使用 KV 存储(如 TiKV)作为元数据引擎时的数据结构设计。 如果比较这些设计,就会发现有相似之处,但也有一些很大的差异。 例如,第一个键在设计中不区分文件和目录。 同时,值中不放置文件或目录的属性信息。 相反,有一个单独的键用于存储属性信息(即第三个键)。

第二个key用于存储数据对应的块ID。 由于它是基于对象存储的,所以不需要那样存储特定的磁盘信息。 您只需要通过某种方式获取对象的密钥即可。 在存储格式[3]中,元数据分为三层:Chunk、Slice、Block。 Chunk是固定大小64MiB,所以第二个key可以直接通过文件大小计算出来。 通过这个key得到的值是一组Slice信息,包括Slice的ID、长度等。 结合这些信息,可以计算出对象存储上的键,最终可以读取或写入数据。

最后,需要特别注意的一点是,为了减少执行分布式事务带来的开销,第三个key需要设计得靠近前两个key,以保证事务尽可能在单个元数据引擎节点上完成尽可能。 但如果无法避免分布式事务,底层元数据引擎也支持(性能略有下降),以保证元数据操作的原子性。

最后,我们来看看客户端的设计。 与其他两个系统最大的区别在于,这是一个同时支持多种标准访问方式的客户端,包括POSIX、HDFS、S3、CSI等。GFS客户端基本上可以认为是非标准协议客户端。 它不支持POSIX标准,只支持追加写入,因此只能在特定场景下使用。 客户端类似于GFS。 它不支持POSIX标准,仅支持追加写入。 但它采用了丰富的客户端设计,在客户端实现了很多功能,这也使得客户端拥有了最大的灵活性。 性别。 此外,客户端还提供了缓存加速功能,这对于云原生架构下的存储分离场景非常有价值。

结论

文件系统诞生于 20 世纪 60 年代。 随着时代的发展,文件系统也在不断发展。 一方面,由于互联网的普及,数据规模爆发式增长,文件系统经历了从单机到分布式的架构升级。 像 Meta 这样的公司是领导者。

另一方面,云计算的诞生和普及推动了云存储的发展。 企业使用云进行备份归档已逐渐成为主流。 一些在本地机房进行的高性能计算和大数据场景也开始迁移到云端。 这些对性能要求更高的场景对文件存储提出了新的挑战。 诞生于这个时代,作为一个基于对象存储的分布式文件系统,希望为更多不同规模、更多样化场景的企业提供可扩展的文件存储解决方案。