乐趣区

关于云计算:深入浅出-Ext4-块和-Inode-分配器的优化上

作者 | Aneesh Kumar K.V、Mingming Cao、Jose R Santos、Andreas Dilger

翻译 | 焱融技术团队

以后,对于小文件和大文件来说,文件系统对块分配器的需要是抵触的。绝对小的文件应该在磁盘上紧挨着,使磁盘磁道缓存最大化并且能够防止寻道。为了防止碎片,文件的增长须要预留空间。Ext4 新的多块和提早分配器通过推延调配到刷新工夫,能够间断地打包小文件和在 RAID 设施对齐的边界上调配大文件并为增长保留空间,来尝试满足这些需要。在本文中,咱们探讨了 Ext4 的新多块分配器,并将其与基于预留 (reservation) 的调配进行了比拟。咱们同样探讨了将元数据块严密放在磁盘上的性能劣势,从而缩小元数据密集型工作负载的搜寻量。

什么是 Ext4 文件系统?

Ext4 文件系统是大概在两年前从 Ext3 文件系统中分化进去的,为了解决 Ext3 文件系统的容量和可扩展性瓶颈。Ext3 文件系统的大小在 x86 架构上被限度为 16TB,作为 32 位块编号的后果。目前全世界的企业都曾经达到了这个极限。同时,随着磁盘容量每年 100% 增长,以及对更大文件系统存储集体数字媒体的需要一直减少,桌面用户很快就会心愿打消对 Ext3 文件系统的限度。因而,在 Ext4 文件系统中做的第一个更改是,将最大文件系统大小从 232 个块(16TB 和 4KB 块大小)晋升到 248 个块。

Ext4 也应用了范畴映射 (extent mapping) 来实现新文件,而不是 Ext2/3 中两次三次的间接映射。Extent 在许多古代文件系统中都用到了 BEST, S. JFS 概述(http://jfs.sourceforge.net/pr…),家喻户晓,它是一种通过缩小解决大文件所需的元数据的形式,无效示意大型间断文件的办法。其中,Extent 无效晋升了程序文件读写的性能,次要是因为 Extent 写入的形容间断块元数据量要少得多,从而缩小了文件系统开销。随着元数据更新的缩小,它还大大减少了截断文件的工夫。Ext4 反对的 Extent 格局如图 1 和图 2 所示。Ext4 性能的残缺形容能够在 2007 年渥太华 Linux 研讨会上探讨的“新 Ext4 文件系统:以后状态和将来打算”(ols2007v2-pages-21-34.pdf (http://kernel.org))中找到。

大多数文件只须要很少的 Extents 来形容它们从逻辑到物理上的块映射,这能够包容在 Inode 或单个 Extent 映射块中。不过,一些极其的场景,例如具备随机分配模式的稠密文件,或十分重大的碎片文件系统,则不能应用 Extent 映射来高效地示意。在 Ext4 中,更重要的是领有一个高级块分配器来缩小文件碎片。一个设计良好的块分配器应将小文件彼此凑近打包以实现局部性,并将大文件间断搁置在磁盘上以进步 I/O 性能。

图一:Ext4 extent,头和索引构造

图二:Ext4 extent 树布局

如上,Ext3 文件系统中的块分配器无奈实现在雷同目录下,实现缩小小文件碎片,并且放弃组局部性的限度工作。Ext3 分配器尝试尽最大致力调配多个块,但不会进行智能搜寻,找到搁置大文件的更好地位。同时,它也无奈感知不同文件之间的关系,所以很可能将相干的小文件搁置在很远的中央,导致在加载大量相干文件时,呈现额定的搜寻。另外,Ext4 块分配器尝试应用新的多块分配器来解决这两个问题,并依然能够应用旧的块分配器,以及 -o mballoc 和 -o nomballoc 挂载选项来别离启用和禁用多块调配。以后,Ext4 文件系统的开发版本默认启用多块分配器。

尽管在块分配器上做了很多工作,但不要遗记,Inode 分配器决定了块从哪里开始调配。只管这些年来磁盘盘片密度急剧减少,但旧的 Ext3 Inode 分配器简直没有确保数据和元数据的局部性,以便利用该密度并防止大量寻道。目前,Ext4 曾经开始摸索压缩数据,以便于减少局部性并缩小寻道的可能性,并且带来更好的性能体验。在 Ext4 块组中受限删除的局部,可能须要重新考虑如何搁置元数据和如何调配 Inode,而这些形式在 Ext3 中是无奈实现的。

Ext3 和 Ext4 的异同

什么是 Ext3 文件系统块分配器?

块调配是文件系统设计的外围。在文件系统中,块调配的指标是通过缩小文件系统碎片和维持相干文件的局部性,以此缩小磁盘寻道工夫。另外,它还须要在大型文件系统和并行调配场景中,有较好的扩展性。

据理解,Ext3 文件系统为了不便扩大,被分为多个 128MB 的块组块(block group chunks)。每个块组维持一个独自的 block bitmap 来形容这个块组外部的数据块可用性。同时,这种形式能够并行实现不同块组上的调配。

当为文件调配一个块时,Ext3 文件系统块分配器总是从 Inode 构造存储所在的块组开始,以此来使元数据和数据块彼此凑近。当指标块组内没有闲暇的可用块时,它将搜寻所有块组的剩下局部来找到一个闲暇块。Ext3 总是试图让同一目录下的文件彼此凑近,直到父块组被填满。

为了缩小大文件碎片,Ext3 通过一个指标块来提醒它应该从哪里调配下一个块。如果应用程序正在执行程序 I/O,则指标是获取最初调配的块前面的块。当指标块不可用时,它会进一步搜寻一个至多领有 8 个块的闲暇范畴,并从那里开始调配。通过间断的形式,进行调配。

在多个文件并行调配块的场景中,Ext3 块分配器通过块保留 (block reservation) 的形式,来确保对特定文件的块的后续申请在与其余文件交织之前失去服务,以此满足后续申请的块保留,并使块分配器能够搁置与左近文件对应的块。同时,每个文件都有一个保留窗口,以此来示意为该文件保留的磁盘块范畴。

然而,因为每个文件的保留窗口是全副在内存中实现,所以每个块的调配都会首先查看文件本人的保留窗口,而后在位图上查找未保留的闲暇块。因为每文件系统的红黑树都会用于保护所有保留窗口,所以在确保应用位图调配块时,咱们不会将块调配到另一个文件的保留窗口之外。

Ext3 文件系统块分配器存在的问题

只管块预留使得在 Ext3 中调配多个块有了可能性,但这是十分无限的,并且是基于尽力而为的 (based on best effort basis),导致 Ext3 仍应用位图来搜寻保留的闲暇块。因为分配器仅在保留窗口内搜寻闲暇块,所以整个文件系统中短少闲暇范畴 (Extent) 信息,导致容易呈现多块分配模式不佳的状况。

Ext3 块分配器的另一个缺点是,它并不会辨别大小文件的调配。大目录,像 /etc,蕴含大量的小配置文件,这些文件都须要在启动时读取。如果文件搁置在磁盘上相距很远的中央,那么启动过程会因为在底层设施上进行低廉的寻道,导致呈现提早加载所有文件。如果块分配器能够将这些相干的小文件搁置得更近,那这将对读取性能有很大的益处。

咱们通过两个测试用例来阐明,Ext3 块分配器对小文件和大文件的性能特色。如图 3 和图 4 所示,在第一个测试中,咱们应用一个线程来程序地创立 20 个 12KB 的小文件;在第二个测试中,咱们并行地创立了单个大文件和多个小文件。大文件是由单线程创立,而小文件由另一个线程并行创立。该图片上用 x 轴上的逻辑块号和 y 轴上的物理块号绘制。为了更好地阐明局部性,绘制的物理块数是通过从理论调配的块数,减去第一个调配的块数来计算的。对于小文件,第四个逻辑块号是第二个文件的第一个逻辑块号,以便于更好地阐明小文件在磁盘上的地位有多近。

图三:Ext3 对小文件的块分配器

图四:Ext3 对大文件的块分配器

因为 Ext3 仅应用指标块来确定新文件的搁置地位,所以 Ext3 分配器无意将小文件离开,以防止在文件是大文件的状况下产生过多碎片。这次要是因为不晓得这些小文件是由同一过程生成的,而本应该彼此凑近。正如咱们在图三中看到的,只管文件自身没有碎片,然而这些小文件的局部性依然很差。

图四中,咱们出现了 Ext3 中大文件的碎片。因为 Ext3 不晓得大文件和小文件是无关的,只管块预留曾经在肯定水平上帮忙缩小了碎片,但仍旧会呈现大文件和小文件抢夺左近闲暇空间的状况。想要解决这个问题,更好的解决方案是,在一开始就将大文件的调配与无关的调配放弃间隔,以防止交织碎片。

Ext4 文件系统多块分配器退场

Ext4 多块分配器的呈现,次要是为了尝试解决上文探讨 Ext3 块分配器呈现的限度——为大小文件提供更好的调配。解决这个限度的方法是,通过对来自不同调配的申请,应用不同策略的形式。其中,对绝对小的调配申请,Ext4 能够让这些小文件彼此凑近,并尝试调配一个 Per-CPU 的部分组,部分组是被雷同 CPU 的所有调配共享的;而大的调配申请首先会从每个文件的预调配中调配。与 Ext3 预留一样,Ext4 为每个文件维护一个内存中的预调配范畴,并以此解决并发调配带来的碎片问题。

Ext4 多块分配器保护两个预调配空间,从中满足块的申请:一个 Per-Inode 的预调配空间;另一个 Per-CPU 的部分组预调配空间。其中,Per-Inode 预调配空间用于更大的申请。同时调配块的状况,则有助于确保更大的文件更少交织。而 Per-CPU 的部分组预调配空间则用于较小的文件调配,并有助于确保将小文件放在磁盘上更近的地位。

应用哪个预调配空间取决于,以后的文件大小和调配申请得出的总大小。分配器提供了一个可调的 /prof/fs/ext4//stream_req,默认为 16。如果总文件大小小于 s tream_req 个块,那么咱们能够应用每个 CPU 部分组预调配空间。

当从 Inode 预调配空间中调配块时,咱们能够通过随机写入的形式,缩小碎片抉择块。这是通过把逻辑块号存储设计为预调配空间的一部分,并应用该值来判断后续申请调配的物理块。

如果咱们无奈从预调配空间中调配块,那么咱们将查看每个块组的搭档缓存 (Buddy Cache)。搭档缓存由多个闲暇 Extent 映射和组位图形成。Extent 映射是在第一个调配时,通过扫描所有的闲暇块造成的。

当扫描一个块组中的闲暇块时,咱们将预调配空间中的块视为已调配,而不将它们视为闲暇块。以此确保从区段映射调配块时,咱们不会从预调配空间调配块,否则会导致文件碎片。

通过扫描块组取得的闲暇 Extent,映射如图五所示的格局存储,称为搭档位图。同时,还出现了块组位图和 Extent 图。此位图与磁盘上的块组位图的不同之处在于,它将预调配空间中的块已调配,而后闲暇 Extent 信息和位图存储在内核 Inode 的页面缓存中,并应用组号进行索引。另外,蕴含闲暇区段信息和位图的页面计算如图 6 所示。

图五:Ext4 搭档缓存布局

图六:搭档缓存 Inode 偏移映射

在从搭档缓存调配块之前,咱们将申请规范化,这有助于避免闲暇 Extent 映射的重大碎片化。该映射以 2 的幂对闲暇块进行分组。从搭档缓存中调配的额定块,随后会被增加到预调配空间,以便从预调配空间提供后续块申请。在大文件的状况下,规范化遵循基于文件大小的启发式列表 (list of heuristics based on file size);对于较小的文件,咱们将块申请规范化为条带大小(如果在挂载时指定)或 s_mb_group_prealloc。s_mb_group_prealloc 默认为 512,能够通过 /proc/fs/ext4/<partition group_prealloc=”” 进行配置。=”” <=”” div=””>

在搭档缓存中搜寻块包含:

  • 在 Extent 映射中搜寻申请数量的块;
  • 如果没找到,并且申请大小与条带大小雷同,则在条带对齐的块中搜寻闲暇块。搜寻条带对齐的块能够在 RAID 配置下更好地调配;
  • 如果未找到,在位图中搜寻闲暇块,并应用找到的最佳 extent。

每次搜寻都会从找到指标块的块组开始,并非所有块组都用于搭档缓存搜寻。如果咱们在 Extent 映射中查找块,咱们只查看具备申请的块程序块组。当搜寻条带大小对齐的闲暇块时,咱们只查看具备条带大小的闲暇块的块组。当位图中搜寻闲暇块时,咱们则会查看具备申请数量的闲暇块的块组。

后记

本篇文章简略地回顾了 Ext3 块分配器的原理和以后的限度,以及介绍了 Ext4 多块分配器和它是如何解决 Ext3 文件系统面对的限度的。接下来,咱们将持续给大家解读 Ext3 Inode 调配策略、Inode 调配对整体文件系统性能的影响、扭转块组的概念如何使性能晋升,以及新的 Inode 分配器在元数据调配中应用这个新概念来操纵磁盘上的块调配和数据局部性等内容,请大家继续关注。

原文起源:https://landley.net/kdocs/ols…

退出移动版