什么是文件系统
当提到文件系统,大部分人都很生疏。但咱们每个人简直每天都会应用到文件系统,比方大家关上 Windows、macOS 或者 Linux,不论是用资源管理器还是 Finder,都是在和文件系统打交道。如果大家有本人入手装过操作系统的话,第一次装置的时候肯定会有一个步骤就是要格式化磁盘,格式化的时候就须要抉择磁盘须要用哪个文件系统。
维基百科上的对于文件系统的定义是:
In computing, file system is a method and data structure that the operating system uses to control how data is stored and retrieved.
简而言之,文件系统治理的是某种物理存储介质(如磁盘、SSD、CD、磁带等)上的数据。在文件系统中最根底的概念就是文件和目录,所有的数据都会对应一个文件,通过目录以树形构造来治理和组织这些数据。基于文件和目录的组织构造,能够进行一些更高级的配置,比方给文件配置权限、统计文件的大小、批改工夫、限度文件系统的容量下限等。
以下列举了一些在不同操作系统中比拟常见的文件系统:
- Linux:ext4、XFS、Btrfs
- Windows:NTFS、FAT32
- macOS:APFS、HFS+
上图是 Linux 内核的架构,右边 Virtual file system 区域,也就是虚构文件系统简称 VFS。它的作用是为了帮忙 Linux 去适配不同的文件系统而设计的,VFS 提供了通用的文件系统接口,不同的文件系统实现须要去适配这些接口。
日常应用 Linux 的时候,所有的零碎调用申请都会先达到 VFS,而后才会由 VFS 向下申请理论应用的文件系统。文件系统的设计者须要恪守 VFS 的接口协议来设计文件系统,接口是共享的,然而文件系统具体实现是不同的,每个文件系统都能够有本人的实现形式。文件系统再往下是存储介质,会依据不同的存储介质再去组织存储的数据模式。
上图是一次写操作的申请流程,在 Linux 里写文件,其实就是一次 write()
零碎调用。当你调用 write()
操作申请的时候,它会先达到 VFS,再由 VFS 去调用文件系统,最初再由文件系统去把理论的数据写到本地的存储介质。
上图是一个目录树的构造,在文件系统外面,所有数据的组织模式都是这样一棵树的构造,从最下面的根节点往下,有不同的目录和不同的文件。这颗树的深度是不确定的,相当于目录的深度是不确定的,是由每个用户来决定的,树的叶子节点就是每一个文件。
最左边的 inode 就是每个文件系统外部的数据结构。这个 inode 有可能是一个目录,也有可能是一个一般的文件。Inode 外面会蕴含对于文件的一些元信息,比方创立工夫、创建者、属于哪个组以及权限信息、文件大小等。此外每个 inode 外面还会有一些指针或者索引指向理论物理存储介质上的数据块。
以上就是理论去拜访一个单机文件系统时,可能会波及到的一些数据结构和流程。作为一个引子,让大家对于文件系统有一个比拟直观的意识。
分布式文件系统架构设计
单机的文件系统曾经可能满足咱们大部分应用场景的需要,治理很多日常须要存储的数据。然而随着时代的倒退以及数据的暴发增 对于数据存储的需要也是在一直的增长,分布式文件系统应运而生。
下面列了一些大家绝对比拟相熟或者应用比拟多的分布式文件系统,这外面有开源的文件系统,也有公司外部应用的闭源产品。从这张图能够看到一个十分集中的工夫点,2000 年左右有一大批的分布式系统诞生 ,这些分布式文件系统至今在咱们日常工作中或多或少还是会接触到。在 2000 年之前也有各种各样的共享存储、并行文件系统、分布式文件系统,但基本上都是 基于一些专用的且比拟低廉的硬件来构建的。
自 2003 年 Google 的 GFS(Google File System)论文公开发表以来,很大水平上影响了前面一大批分布式系统的设计理念和思维。GFS 证实了咱们能够用绝对便宜的通用计算机,来组建一个足够弱小、可扩大、牢靠的分布式存储,齐全基于软件来定义一个文件系统,而不须要依赖很多专有或者昂扬的硬件资源,能力去搭建一套分布式存储系统。
因而 GFS 很大水平上升高了散布文件系统的应用门槛,所以在后续的各个分布式文件系统上都能够或多或少看到 GFS 的影子。比方雅虎开源的 HDFS 它基本上就是依照 GFS 这篇论文来实现的,HDFS 也是目前大数据畛域应用最宽泛的存储系统。
上图第四列的「POSIX 兼容」示意这个分布式文件系统对 POSIX 规范的兼容性。POSIX(Portable Operating System Interface)是用于标准操作系统实现的一组规范,其中就蕴含与文件系统无关的规范。所谓 POSIX 兼容,就是满足这个规范外面定义的一个文件系统应该具备的所有特色,而不是只具备个别,比方 GFS,它尽管是一个开创性的分布式文件系统,但其实它并不是 POSIX 兼容的文件系统。
Google 过后在设计 GFS 时做了很多取舍,它舍弃掉了很多传统单机文件系统的个性,保留了对于过后 Google 搜索引擎场景须要的一些分布式存储的需要。所以严格上来说,GFS 并不是一个 POSIX 兼容的文件系统,然而它给了大家一个启发,还能够这样设计分布式文件系统。
接下来我会着重以几个绝对有代表性的分布式文件系统架构为例,给大家介绍一下,如果要设计一个分布式文件系统,大略会须要哪些组件以及可能会遇到的一些问题。
GFS
首先还是以提到最多的 GFS 为例,尽管它在 2003 年就颁布了,但它的设计我认为至今也是不过时的,有很多值得借鉴的中央。GFS 的次要组件能够分为三块,最右边的 GFS client 也就是它的客户端,而后就是两头的 GFS master 也就是它的元数据节点,最上面两块是 GFS chunkserver 就是数据理论存储的节点,master 和 chunkserver 之间是通过网络来通信,所以说它是一个分布式的文件系统。Chunkserver 能够随着数据量的增长一直地横向扩大。
其中 GFS 最外围的两块就是 master 和 chunkserver。咱们要实现一个文件系统,不论是单机还是分布式,都须要去保护文件目录、属性、权限、链接等信息,这些信息是一个文件系统的元数据,这些元数据信息须要在核心节点 master 外面去保留。Master 也蕴含一个树状构造的元数据设计。
当要存储理论的利用数据时,最终会落到每一个 chunkserver 节点上,而后 chunkserver 会依赖本地操作系统的文件系统再去存储这些文件。
Chunkserver 和 master、client 之间相互会有连贯,比如说 client 端发动一个申请的时候,须要先从 master 获取到以后文件的元数据信息,再去和 chunkserver 通信,而后再去获取理论的数据。在 GFS 外面所有的文件都是分块(chunk)存储,比方一个 1GB 的大文件,GFS 会依照一个固定的大小(64MB)对这个文件进行分块,分块了之后会散布到不同的 chunkserver 上,所以当你读同一个文件时其实有可能会波及到和不同的 chunkserver 通信。
同时每个文件的 chunk 会有多个副原本保证数据的可靠性,比方某一个 chunkserver 挂了或者它的磁盘坏了,整个数据的安全性还是有保障的,能够通过正本的机制来帮忙你保证数据的可靠性。这是一个很经典的分布式文件系统设计,当初再去看很多开源的分布式系统实现都或多或少有 GFS 的影子。
这里不得不提一下,GFS 的下一代产品: Colossus。因为 GFS 的架构设计存在显著的扩展性问题,所以 Google 外部基于 GFS 持续研发了 Colossus。Colossus 不仅为谷歌外部各种产品提供存储能力,还作为谷歌云服务的存储底座凋谢给公众应用。Colossus 在设计上加强了存储的可扩展性,进步了可用性,以解决大规模增长的数据需要。上面行将介绍的 Tectonic 也是对标 Colossus 的存储系统。篇幅关系,这篇博客不再开展介绍 Colossus,有趣味的敌人能够浏览官网博客。
Tectonic
Tectonic 是 Meta(Facebook)外部目前最大的一个分布式文件系统。Tectonic 我的项目大略在 2014 年就开始做了(之前被叫做 Warm Storage),但直到 2021 年才公开发表论文来介绍整个分布式文件系统的架构设计。
在研发 Tectonic 之前,Meta 公司外部次要应用 HDFS、Haystack 和 f4 来存储数据,HDFS 用在数仓场景(受限于单集群的存储容量,部署了数十个集群),Haystack 和 f4 用在非结构化数据存储场景。Tectonic 的定位即是在一个集群里满足这 3 种存储撑持的业务场景需要。和 GFS 一样,Tectonic 也次要由三局部形成,别离是 Client Library、Metadata Store 和 Chunk Store。
Tectonic 比拟翻新的点在于它在 Metadata 这一层做了分层解决,以及存算拆散的架构设计。从架构图能够看到 Metadata 分了三层:Name layer、File layer 和 Block layer。传统分布式文件系统会把所有的元数据都看作同一类数据,不会把它们显式辨别。在 Tectonic 的设计中,Name layer 是与文件的名字或者目录构造无关的元数据,File layer 是跟以后文件自身的一些属性相干的数据,Block layer 是每一个数据块在 Chunk Store 地位的元数据。
Tectonic 之所以要做这样一个分层的设计是因为它是一个十分大规模的分布式文件系统,特地是在 Meta 这样的量级下(EB 级数据)。在这种规模下,对于 Metadata Store 的负载能力以及扩展性有着十分高的要求。
第二点翻新在于元数据的存算拆散设计,后面提到这三个 layer 其实是无状态的,能够依据业务负载去横向扩大。然而上图中的 Key-value Store 是一个有状态的存储,layer 和 Key-value Store 之间通过网络通信。
Key-value Store 并不齐全是 Tectonic 本人研发的,而是用了 Meta 外部一个叫做 ZippyDB 的分布式 KV 存储来反对元数据的存储。ZippyDB 是基于 RocksDB 以及 Paxos 共识算法来实现的一个分布式 KV 存储。Tectonic 依赖 ZippyDB 的 KV 存储以及它提供的事务来保障整个文件系统元信息的一致性和原子性。
这里的事务性能是十分重要的一点,如果要实现一个大规模的分布式文件系统,势必要把 Metadata Store 做横向扩大。横向扩大之后就波及数据分片,然而在文件系统外面有一个十分重要的语义是强一致性,比方重命名一个目录,目录外面会波及到很多的子目录,这个时候要怎么去高效地重命名目录以及保障重命名过程中的一致性,是分布式文件系统设计中是一个十分重要的点,也是业界普遍认为的难点。
Tectonic 的实现计划就是依赖底层的 ZippyDB 的事务个性来保障当仅波及单个分片的元数据时,文件系统操作肯定是事务性以及强一致性的。但因为 ZippyDB 不反对跨分片的事务,因而在解决跨目录的元数据申请(比方将文件从一个目录挪动到另一个目录)时 Tectonic 无奈保障原子性。
在 Chunk Store 层 Tectonic 也有翻新,上文提到 GFS 是通过多正本的形式来保证数据的可靠性和安全性。多正本最大的弊病在于它的存储老本,比如说你可能只存了 1TB 的数据,然而传统来说会保留三个正本,那么至多须要 3TB 的空间来存储,这样使得存储老本成倍增长。对于小数量级的文件系统可能还好,然而对于像 Meta 这种 EB 级的文件系统,三正本的设计机制会带来十分昂扬的老本,所以他们在 Chunk Store 层应用 EC(Erasure Code)也就是纠删码的形式去实现。通过这种形式能够只用大略 1.2~1.5 倍的冗余空间,就可能保障整个集群数据的可靠性和安全性,相比三正本的冗余机制节俭了很大的存储老本。Tectonic 的 EC 设计细到能够针对每一个 chunk 进行配置,是非常灵活的。
同时 Tectonic 也反对多正本的形式,取决于下层业务须要什么样的存储模式。EC 不须要特地大的的空间就能够保障整体数据的可靠性,然而 EC 的毛病在于当数据损坏或失落时重建数据的老本很高,须要额定耗费更多计算和 IO 资源。
通过论文咱们得悉目前 Meta 最大的 Tectonic 集群大略有四千台存储节点,总的容量大略有 1590PB,有 100 亿的文件量 ,这个文件量对于分布式文件系统来说,也是一个比拟大的规模。 在实践中,百亿级基本上能够满足目前绝大部分的应用场景。
再来看一下 Tectonic 中 layer 的设计,Name、File、Block 这三个 layer 理论对应到底层的 KV 存储里的数据结构如上图所示。比如说 Name layer 这一层是以目录 ID 作为 key 进行分片,File layer 是通过文件 ID 进行分片,Block layer 是通过块 ID 进行分片。
Tectonic 把分布式文件系统的元数据抽象成了一个简略的 KV 模型,这样能够十分好的去做横向扩大以及负载平衡,能够无效避免数据拜访的热点问题。
JuiceFS
JuiceFS 诞生于 2017 年,比 GFS 和 Tectonic 都要晚,相比前两个零碎的诞生年代,外部环境曾经产生了天翻地覆的变动。
首先硬件资源曾经有了突飞猛进的倒退,作为比照,当年 Google 机房的网络带宽只有 100Mbps(数据起源:The Google File System 论文),而当初 AWS 上机器的网络带宽曾经能达到 100Gbps,是当年的 1000 倍!
其次云计算曾经进入了支流市场,不论是私有云、公有云还是混合云,企业都曾经迈入了「云时代」。而云时代为企业的基础设施架构带来了全新挑战,传统基于 IDC 环境设计的基础设施一旦想要上云,可能都会面临种种问题。如何最大水平上施展云计算的劣势是基础设施更好融入云环境的必要条件,猛攻陈规只会事倍功半。
同时,GFS 和 Tectonic 都是仅服务公司外部业务的零碎,尽管规模很大,但需要绝对繁多。而 JuiceFS 定位于服务宽广内部用户、满足多样化场景的需要,因此在架构设计上与这两个文件系统也大有不同。
基于这些变动和差别,咱们再来看看 JuiceFS 的架构。同样的,JuiceFS 也是由 3 局部组成:元数据引擎、数据存储和客户端。尽管大体框架上相似,但其实每一部分的设计 JuiceFS 都有着一些不太一样的中央。
首先是数据存储这部分,相比 GFS 和 Tectonic 应用自研的数据存储服务,JuiceFS 在架构设计上适应了云原生时代的特点,间接应用对象存储作为数据存储。后面看到 Tectonic 为了存储 EB 级的数据用了 4000 多台服务器,可想而知,如此大规模存储集群的运维老本也必然不小。对于普通用户来说,对象存储的益处是开箱即用、容量弹性,运维复杂度陡然降落。对象存储也反对 Tectonic 中应用的 EC 个性,因而存储老本相比一些多正本的分布式文件系统也能升高不少。
然而对象存储的毛病也很显著,例如不反对批改对象、元数据性能差、无奈保障强一致性、随机读性能差等。这些问题都被 JuiceFS 设计的独立元数据引擎,Chunk、Slice、Block 三层数据架构设计,以及多级缓存解决了。
其次是元数据引擎,JuiceFS 可应用一些开源数据库作为元数据的底层存储。这一点和 Tectonic 很像,但 JuiceFS 更进了一步,不仅反对分布式 KV,还反对 Redis、关系型数据库等存储引擎,让用户能够灵便地依据本人的应用场景抉择最适宜的计划,这是基于 JuiceFS 定位为一款通用型文件系统所做出的架构设计。应用开源数据库的另一个益处是这些数据库在私有云上通常都有全托管服务,因而对于用户来说运维老本简直为零。
后面提到 Tectonic 为了保障元数据的强一致性抉择了 ZippyDB 这个反对事务的 KV 存储,但 Tectonic 也只能保障单分片元数据操作的事务性,而 JuiceFS 对于事务性有着更严格的要求,须要保障全局强一致性(即要求跨分片的事务性)。因而目前反对的所有数据库都必须具备单机或者分布式事务个性,否则是没有方法作为元数据引擎接入进来的(一个例子就是 Redis Cluster 不反对跨 slot 的事务)。基于能够横向扩大的元数据引擎(比方 TiKV),JuiceFS 目前曾经能做到在单个文件系统中存储 200 多亿个文件,满足企业海量数据的存储需要。
上图是应用 KV 存储(比方 TiKV)作为 JuiceFS 元数据引擎时的数据结构设计,如果比照 Tectonic 的设计,既有相似之处也有一些大的差别。比方第一个 key,在 JuiceFS 的设计里没有对文件和目录进行辨别,同时文件或目录的属性信息也没有放在 value 里,而是有一个独自的 key 用于存储属性信息(即第三个 key)。
第二个 key 用于存储数据对应的块 ID,因为 JuiceFS 基于对象存储,因而不须要像 Tectonic 那样存储具体的磁盘信息,只须要通过某种形式失去对象的 key 即可。在 JuiceFS 的存储格局中元数据分了 3 层:Chunk、Slice、Block,其中 Chunk 是固定的 64MiB 大小,所以第二个 key 中的 chunk_index
是能够通过文件大小、offset 以及 64MiB 间接计算得出。通过这个 key 获取到的 value 是一组 Slice 信息,其中蕴含 Slice 的 ID、长度等,联合这些信息就能够算出对象存储上的 key,最终实现读取或者写入数据。
最初有一点须要特地留神,为了缩小执行分布式事务带来的开销,第三个 key 在设计上须要凑近后面两个 key,确保事务尽量在单个元数据引擎节点上实现。不过如果分布式事务无奈防止,JuiceFS 底层的元数据引擎也反对(性能略有降落),确保元数据操作的原子性。
最初来看看客户端的设计。JuiceFS 和另外两个零碎最大的区别就是这是一个同时反对多种规范拜访形式的客户端,包含 POSIX、HDFS、S3、Kubernetes CSI 等。GFS 的客户端根本能够认为是一个非标准协议的客户端,不反对 POSIX 规范,只反对追加写,因而只能用在繁多场景。Tectonic 的客户端和 GFS 差不多,也不反对 POSIX 规范,只反对追加写,但 Tectonic 采纳了一种富客户端的设计,把很多性能都放在客户端这一边来实现,这样也使得客户端有着最大的灵活性。此外 JuiceFS 的客户端还提供了缓存减速个性,这对于云原生架构下的存储拆散场景是十分有价值的。
结语
文件系统诞生于上个世纪 60 年代,随着时代的倒退,文件系统也在一直演进。一方面因为互联网的遍及,数据规模爆发式增长,文件系统经验了从单机到分布式的架构降级,Google 和 Meta 这样的公司便是其中的引领者。
另一方面,云计算的诞生和风行推动着云上存储的倒退,企业用云进行备份和存档已逐步成为支流,一些在本地机房进行的高性能计算、大数据场景,也曾经开始向云端迁徙,这些对性能要求更高的场景给文件存储提出了新的挑战。JuiceFS 诞生于这样的时代背景,作为一款基于对象存储的分布式文件系统,JuiceFS 心愿可能为更多不同规模的公司和更多样化的场景提供可扩大的文件存储计划。
如有帮忙的话欢送关注咱们我的项目 Juicedata/JuiceFS 哟!(0ᴗ0✿)