XFS 文件系统 (一) :设计概览
文章目录
- 0 前言
- 1 设计背景
- 2. 需要解决的问题
- 2.1 异常恢复太慢
- 2.2 不支持大文件系统
- 2.3 不支持大型稀疏文件
- 2.4 不支持大型连续文件
- 2.5 不支持大目录
- 2.6 不支持过多文件个数
- 3 XFS 架构
- 4 痛点解决
- 4.1 Allocation Groups
- 4.2 Manging Free Space
- 4.3 大文件的支持
- 5 总结
0 前言
虽然工作精力主要是在 存储引擎方向上,但是目前业界大多数的存储引擎都是构建在 os fs上, 所以深入理解文件系统工作原理对于存储引擎的设计也有不少的帮助。
尤其是近期工作中遇到一些 engine on ape-xfs 的性能问题,发现文件系统的知识欠缺还是比较严重的。
举个例子,on aep 也就是 pmem 上做了一个fsdax 模式的pmem namespace,像使用磁盘一样使用它 需要格式化为对应的文件系统。因为 pmem 是插在内存插槽上(和cpu 更近),且libpmem 驱动仅只支持 dax 模式的挂载,用于加速访问pmem。所以 on pmem 的文件系统 是无法使用 page-cache 的,也就是像 inode/dentry 这样的文件/目录元数据 信息是没有办法缓存到 icache/dcache的,这样,针对这一些元数据的更新就需要直接落在pmem上,像存储引擎的 wal 是需要频繁写文件,那么文件的inode 元信息(file size)的更新就会非常频繁(除非预分配),没有预分配的情况下写性能就会非常之差。
这里如果能够深入了解文件系统的基本原理,这样的问题抓个栈就是一眼的事情,不需要消耗过多的时间。
本篇 以及 后续的文章还是以技术设计 为主 进行学习,不会太深入代码。
先以 xfs 设计实现为主,毕竟centos7/8 的默认文件系统,后面再逐个梳理 与其他文件系统的实现差异,毕竟文件系统过于庞大,这里仅仅做一些初步设计的记录
1 设计背景
xfs 是大名鼎鼎的 硅谷 图形图像高性能计算公司巨头 SiliconGraphic Inc 1993 年为自己内部 高性能服务器设计的文件系统。因为现在的 不少开发者 深度参与了 xfs 的设计开发,所以才成为今天centos 的主流文件系统。
XFS 被 SGI 设计出来的目的肯定是未来解决已有文件系统在大多数场景下的问题的,SGI 内部现有的文件系统 EFS(existing file system) 因为设计,无法发挥硬件性能,导致文件系统成为 os 的 i/o 瓶颈。还有很多其他功能上的限制,主要是以下几个方面。
- EFS 采用的是 extent 方式管理 磁盘块的分配 以及 调度磁盘IO,无法完全发挥磁盘介质性能。
- 单个文件系统的大小不能超过 8G (当时的磁盘已经有T级别的了,hdd),单个文件的大小不能超过2G。
- 在EFS 上解决一些功能上的限制和 性能问题,因为架构设计,工作量基本接近重写了。
因为SGI 提供给用户的服务器需要解决 用户大量的视频/图像 存储需求 以及 访问性能,这一些随着用户需求的不断增加(全球化时代 上层互联网应用在高速发展,单服务器的存储体量在不断增加,存储更大性能更快是当时的服务器存储的必然趋势。。。),满足不了需求的SGI 需要开辟新疆土,所以就有了XFS。
2. 需要解决的问题
这里新设计的 XFS 需要解决的问题基本就是前面设计背景中描述的EFS的现有功能/性能问题,会对每一个问题做一个展开描述。
2.1 异常恢复太慢
EFS 是基于 BSD的 Fast File System(不太熟) 设计的,在机器异常之后启动一个守护程序重新 从磁盘 load 文件系统的元数据,达到一个一致性状态。这个过程会需要 fsck 不断的检查一个 8G 的文件系统中 上百个inode 需要花费几分钟的时间(HDD的带宽应该有百M,这么慢的话大概率还是文件系统设计的问题),随着磁盘容量得不断增加, 当达到TB 级别以及 上万的 inodes,如果还是这样 recovery 速度是不能忍受的。
这里启动 fsck check 一致性的过程应该是 检查了全量文件,后面的XFS 设计中就只会检查元数据了。
2.2 不支持大文件系统
这里也就是 EFS 不支持 管理大文件系统容量。SGI 希望文件系统能够支持 PB级别的容量管理功能,但是当时业界主流的文件系统基本都是 GB 级别,像是EFS 就仅仅支持8GB。因为EFS 管理文件系统空间的数据结构是没有办法动态扩展的,它用 32bit的 bitmap指针管理磁盘空间,32bit 的指针最多能够管理40亿的block,即使每一个block 的大小是8K ,最多也只能管理32T 的空间。
2.3 不支持大型稀疏文件
当时的业界也没有支持全量 64bit 的 稀疏文件存储。稀疏文件便于压缩,这样的文件一般是针对大视频处理之后形成的。
2.4 不支持大型连续文件
EFS支持 超大连续块的存储下读性能不友好。EFS 使用的是 bitmap 数组结构来管理文件系统中的空间分配和释放记录。想要在一段超大连续空间中读取指定的部分区域,查找性能并不会特别好。因为写入的时候在连续的磁盘空间上写入(顺序写)本身对HDD性能非常友好,但是读的时候在超大文件下的查找(即使是二分) 因为bitmap 数组结构的限制 会产生多次i/o,而如果不分配连续块,那写性能将会巨差。
2.5 不支持大目录
EFS 并不支持一个目录下 上千的文件管理机制。还是性能问题,因为大多的文件系统当时从一个目录下找一个文件是需要顺序遍历这个目录下的文件(怀疑目录项下的文件管理用的链表),还有一些使用的是hash 数据结构,这对点查性能友好,但是大范围扫描整个目录文件的时候性能也会很差。
当时的 NTFS 则使用 Btree 对目录下的文件entries 进行管理。
2.6 不支持过多文件个数
当时的EFS 理论上在一个文件系统内支持超大数量的文件,但是实际过程中并非如此。因为E FS 在创建文件提供的时候就已经分配好了足量个数的 inodes,这在文件系统并没有太多文件的情况下对磁盘空间浪费较为严重。同样也为文件系统管理如此巨量 的inode 带来负担,尤其是写入了很少的文件却需要从如此巨量的inode 中查找。
总之,因为EFS 内部架构设计和各个小组件的数据结构选型,导致当前文件系统的各种功能并不完备,存在较多问题,所以 全新的文件系统 XFS 设计迫在眉睫。
3 XFS 架构
基本架构如下
这个当时 (1996)年最初的XFS 基本架构。
和其他传统文件系统一样,都有一个 transaction manager 以及 volumn manager。XFS 支持了标准的 UNIX 和 POSIX 的语义,在当时的 SGI 自己的内核 IRIX 中基本使用了内核所提供的有利特性,包括buffer/page cache,dcache(directory cache) 以及 icache(当时叫vnode cache)。
整个XFS 架构被模块化为了几部分:
- 最核心,最重要的就是 space manager。这个模块用来管理文件系统的空间释放和 inode的分配 以及 单个文件内部空间的分配。
- IO manager。用来管理文件系统下发的i/o请求,依赖space manager 进行请求空间的分配和释放,并且需要持续追踪每一个文件的空间。
- Directory manager。管理文件系统的 名字空间。
- Buffer Cache。用于缓存前面的管理数据结构,将本应该存储在磁盘上的这一些结构缓存到内存中,加速访问。而且 buffer cache 是 被整个os 所有进程访问的。
- Transaction manager。用于用户对一个文件元数据的原子更新需求。这有利于加速文件系统的crash recovery。
- Volumn manager 主要是 XFS 自己做的屏蔽不通 disk driver的组件,能够方便对接不同的磁盘驱动,简化文件系统的实现(不需要为每一个磁盘驱动实现对应的调度接口,当然后来linux kernel 的 generic block layer 更完备得做了这个事情,只是当时SGI 是自己的服务器,自己维护的os)。
因为XFS 全新的设计,更完备的功能和更高的性能支持,其复杂度也更高,SGI 第一版本的XFS 实现已经超过50000 行 代码,而对应其内部的EFS 才12000 行代码。
这里简单汇总一下 xfs 实现过程中对b+ tree 的钟爱:
- 追踪磁盘空闲空间的数据结构 从之前的bitmap 变更为了b+ tree。
- 目录项下的文件管理数据结构也从之前的线性查找数据结构变更为了 b+tree.
- B+tree 管理extent map,再由 extent map管理inodes,从而达到对整个文件系统inodes 的管理。
- B+tree 用于追踪文件系统 inodes 的动态分配
接下来看看 XFS 实现过程中如何解决之前 EFS 的问题的。
4 痛点解决
4.1 Allocation Groups
XFS 支持全64bits 的存储管理。内部用到的所有计数变量都是 64bits 长度(block address 以及 inode nubmer)。为了充分利用 64bits 的并行性和可伸缩性,且 避免XFS 内部所有的数据结构都扩展到64bits,这里XFS 将文件系统拆分成不同的 region,也就是 AGs,当然也会考虑磁盘访问的局部性来利用AG 设计存储方式(毕竟。。。HDD的随机I/O 实在是不忍直视)。
每一个AG 管理整个文件系统的一部分容量,且不通 AG 之间可以并行操作。每一个AG 大小是 500M --> 4G 之间(现在已经支持到了16M-- 1TB 之间)。每一个AG 有自己的独立数据存储区域,在自己的边界区域内,管理自己内部的空闲空间和inodes。
AG结构 的设计目的 就是前面提到的提升 64bits 的文件系统并发访问 以及 文件系统的可伸缩性, 但是要说提升磁盘访问的局部性 这个 很少,主要是用在目录项的存储中。因为文件系统创建的文件会分布在不同的AG内部,如果创建了目录,那针对这个目录下创建的文件 inodes 和 blocks 索引都会放在这个目录对应的AG内部,利用 磁盘访问的局部性 (os 预读)加速读性能。不同的AG 内部可以通过 文件系统全局的 ag 指针/files/directories 来访问整个文件系统其他 AG 的文件。
当然AG 设计最主要的目的是为了 提升64bits 下的并发访问性能 和 空闲空间管理以及 inodes 分配的性能。因为 SGI 的EFS 都是单线程处理 block 的分配和释放。这种方式随着文件系统的规模不断增加,可能成为性能瓶颈,通过设计 AG 内部 拥有独立的数据结构,这样XFS 文件系统可以 在不同AG 互不影响的情况下 并发调度 一些 释放/分配 磁盘空间的操作。
更详细的AG 设计后面的系列文章会展开。
4.2 Manging Free Space
空间分配/释放的性能 和 可扩展性 是衡量一个好的文件系统的基础。能够高效的分配和释放空间,并且能够很好得处理空间碎片问题 对文件系统的性能至关重要。
XFS 在空间管理的数据结构上 相比于 EFS 来说做了比较大的改动,在每个AG 内部 将EFS原本的 bitmap 换成了b+tree。其中空闲空间的 start block的维护有一个单独的b+ tree,同时 length(有多少个空闲块)的维护也有一个b+tree,这样想要查找 一个空闲块的时候可以根据传入的空闲块的个数以及 起始空闲块进行,极大得提升了空闲空间的索引效率。
4.3 大文件的支持
在64bits 下支持超大的稀疏文件,也就是允许大文件内部有空洞,而这一些空洞不应该占用磁盘空间。如果按照传统的磁盘block 方式来管理一个文件所占用空间的话,那在这种场景下需要管理大量的blocks。XFS 采用了Data extent 的方式,每一个 extent 都是一段连续的分配给当前文件的block 空间,由一个个block offset组成,这样对于超大文件的空间管理就更加高效了。原本 采用block 的方式 , 可能一个文件需要 百万级别的block,现在这一些block 都可以聚合成一个大的extent统一管理,在extent 内部会尽可能保持 block 的连续性,甚至随着文件大小的不断增加,不同的extent 之间也可以合并。
每一个 Data Extent 是128bits,其中1bits 用来记录标识,高54bits 存储block 的偏移地址,后52bits 存储 完整的 block number,后21 bits 存储block 个数 (一个extent中能够保存 200w的block,也就是8G 的磁盘空间)。
5 总结
还有更多 XFS 如何解决 EFS 前面提到的痛点方案,因为 整体的体系较为庞大,这里先做一个记录,更多的细节会慢慢展开。
相关文章:

WebApi2官网学习记录---异常处理
HttpResponseException 当WebAPI的控制器抛出一个未捕获的异常时,默认情况下,大多数异常被转为status code为500的http response即服务端错误。 HttpResonseException是一个特别的情况,这个异常可以返回任意指定的http status code࿰…

Java项目:资源下载工具(java+swing)
源码获取:博客首页 "资源" 里下载! 功能简介: 下载地址、保存位置、下载设置、下载进度 文件仓库控制器: /*** ClassName: FileStoreController* Description: 文件仓库控制器**/ Controller public class FileStoreC…

江南Style之---西湖
西湖古称“钱塘湖”,又名“西子湖”,古代诗人苏轼就对它评价道:“欲把西湖比西子,淡妆浓抹总相宜。西湖,是一首诗,一幅天然图画,一个美丽动人的故事,不论是多年居住在这里的人还是匆…

mimikatz
下载后,在目标机直接运行 常用命令: 提升权限:privilege::debug 获取用户登录明文账号密码:sekurlsa::logonPasswords 获取用户密码hash值:lsadump::sam 转载于:https://www.cnblogs.com/xiaoqiyue/p/10824169.html

通过 RDTSC 指令从 CPU 寄存器中直接获取系统时钟
很多时候我们使用函数 gettimeofday 以及 clock_gettime 作为我们获取 wall lock的时钟函数。 因为这两种函数是 glibc 提供的用户封装,简单易用,而且能够精确到 ns,对于大多数的时钟需求场景都已经够用了。 但是如果 我们的应用 调用时钟频…

Java项目:星际争霸游戏(java+swing+awt界面编程+IO输入输出流+socket+udp网络通信)
源码获取:博客首页 "资源" 里下载! 功能简介: 星际争霸游戏项目,该项目实现了单人模式和多人合作模式,可记录游戏进度,新建游戏,载入历史记录等功能,多人模式下可以创建一…

GTONE清理维护建议方案
1、日志清理/home/gtone/AppGov/analyzer/log//home/gtone/AppGov/analyzer/SRC/temp//home/gtone/AppGov/WAS/logs/ 2、扩容现有磁盘空间至200GB转载于:https://www.cnblogs.com/arcer/p/4461018.html

[C#]委托和事件(讲解的非常不错)
引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉…

BZOJ1460: Pku2114 Boatherds
题目链接:点这里 题目描述:给你一棵n个点的带权有根树,有p个询问,每次询问树中是否存在一条长度为Len的路径,如果是,输出Yes否输出No. 数据范围:\(n\le1e5\,,p\le100\,,长度\le1e5\) Solution: …

centos 自定义内核模块 编译运行
简单记录一下 centos 自定义内核模块的一些编译运行记录,代码如下: 主要功能是通过rdtsc 指令直接从 CPU MSR 寄存器中获取时钟,尝试获取两次,两次之间会做一些赋值操作什么的,并记录一下时差。 #include <linux/…

os.system() 和 os.popen()
1.os.popen(command[, mode[, bufsize]]) os.system(command)2.os.popen() 功能强于os.system() , os.popen() 可以返回回显的内容,以文件描述符返回。eg:t_f os.popen ("ping 192.168.1.1")print t_f.read()或者:for line in os.popen("dir"…

Java项目:医院管理系统(java+Springboot+Maven+Mybatis+Vue+Mysql)
源码获取:博客首页 "资源" 里下载! 一、项目简述本系统功能包括:医院挂号,退号,缴费,退费,检查申请单开立,科室管理,医生开单,挂号级别,…

任意阶幻方..
1 /*coder Gxjun*/2 #include<stdio.h>3 #include<string.h>4 #include<stdlib.h>5 #define maxn 1006 int map[maxn][maxn] ;7 void creat_magic(int n,int x,int y ,int sn) //奇阶幻方构造8 {9 int i,j,k;10 i0;11 jn/2;12 for(kn;k<…

UML与软件建模 第三次作业
1.单元测试的任务有哪些? 单元测试是对软件基本组成单元进行的测试,而且软件单元是与程序的其他部分相隔离的情况下进行独立的测试. 任务主要包括对单元功能、逻辑控制、数据和安全性等各方面进行必要的测试。具体地说,包括单元中所有独立执行路径、数据…

Pliops XDP(Extreme Data Processor)数据库存储设计的新型加速硬件
文章目录0 前言1 核心问题1.1 引擎的各方面性能受限于数据结构的选择1.2 压缩功能 导致的CPU瓶颈1.3 Crash-safe 崩溃异常的无奈选择1.4 当前主流 加速硬件 较难满足存储性能提升的要求2 XDP 设计原则2.1 数据结构上的优化2.2 解决 压缩引入的CPU消耗2.3 异常恢复的设计2.4 易于…

Java项目:潜艇大战项目(java+swing)
源码获取:博客首页 "资源" 里下载! 功能简介: Java swing实现的一款小游戏潜艇大战的项目源码 游戏界面: SuppressWarnings({ "unused", "serial" }) public class GameGUI extends JPanel {//卡…

可以发张图片做链接用吗
转载于:https://www.cnblogs.com/wasss/p/4466492.html

更改显示器的分辨率
1.桌面右击,如图1-1所示。2.点击屏幕分辩率,选择分辨率调大小,确定,如图1-2所示。转载于:https://blog.51cto.com/qikai/1367734

Java 处理0x00特殊字符
Java 处理0x00特殊字符 一、0x00字符 1,0x00是ascii码的0值:NUL 2,0x00在windows系统中显示: 3,0x00在Linux中显示: ctrlV ctrl可以打出此字符 二、Java解决0x00字符 str.replaceAll("\\u0000",&…

关于 并查集(union find) 算法基本原理 以及 其 在分布式图场景的应用
二月的最后一篇水文…想写一些有意思的东西。 文章目录环检测在图数据结构中的应用深度/广度优先 检测环并查集数据结构 (Union-Find)基本概念初始化合并 union查找祖先优化1: 合并过程 利用 rank 优化路径优化2: 路径压缩(Path Compression)并查集 解决图中检测环问题环检测在…

Java项目:智能制造生产管理平台(java+SSM+mysql+Maven+Easyui+JSP)
源码获取:博客首页 "资源" 里下载! 运行环境:jdk1.8、tomcat7.0/8.5、Mysql5.7/5.1、Maven3.6/3.5、 eclipse/STS 功能简介:计划进度、设备管理、工艺监控、物料监控、质量监控、人员监控等 访问注册控制层:…

JAVA-Eclipse快捷键
Ctrl1:快速修复。CtrlD:快速删除行。ShiftEnter:快速调到下一行。CtrlF11:快速运行。Alt上下方向键:快速移动。CtrlM:光标所在视图最大化。Alt/:智能补全。Ctrl/:快速注释代码。 转载于:https://www.cnblogs.com/bluewhy/p/44669…

Android RelativeLayout属性
// 相对于给定ID控件android:layout_above 将该控件的底部置于给定ID的控件之上;android:layout_below 将该控件的底部置于给定ID的控件之下;android:layout_toLeftOf 将该控件的右边缘与给定ID的控件左边缘对齐;android:layout_toRightOf 将该控件的左边缘与给定ID的控件右边缘…

详解Azure的权限控制
注意:本文档仅限于Azure国际版,国内版略有不同Azure中的角色分配相对来说是比较复杂的的,对于任何云组织来说,云的资源访问管理权限都是一项非常重要的功能,azure中的授权系统叫做基于角色的访问控制(RBAC&…

SNMP introduction
简单网络管理协议(SNMP)首先是由Internet工程任务组织(Internet Engineering Task Force)(IETF)的研究小组为了解决Internet上的路由器管理问题而提出的。许多人认为 SNMP在IP上运行的原因是Internet运行的是TCP/IP协议,然而事实并不是这样。 SNMP被设计成与协议无…

Java项目:在线考试系统(java+SSM+mysql+JSP)
源码获取:博客首页 "资源" 里下载! 运行环境:jdk1.8、Mysql5.7、Tomcat8.5、IDEA/Eclipse 功能简介:在线考试、历史回顾、个人成绩查询等。 管理员和教师功能有:学院管理、班级管理、课程管理、教师、学生…

Keil中使用宏编译来定义DEBUG输出
使用宏编译来格式化调试信息,是一个不错的方法,即可以在需要的时候打印出信息,还可以格式化我们所需要的输出。 #define DEBUG 1 #if (DEBUG 1) #define DBG(Args...) printf(##Args) #define DBGFL(s, Args...) printf("[%s:%d]&qu…

解决用户使用临时配置文件登陆WIN7的问题
用户登录Win7后,经常会遇到 “您已使用临时配置文件登陆” 的提示,忽略此提示的用户通常在桌面上保留的文件再次重启进入后发现文件丢失了,或者原有桌面上的文件不见了,这样一定程度上降低了工作的效率.这里主要说一下如何解决此问题。用户登…

chosen.jquery.js 有搜索功能、多选功能的下拉框插件
chosen.jquery.js 有搜索功能、多选功能的下拉框插件 官方源码: https://github.com/harvesthq/chosen 该源码中的样例index.html有该插件的详细使用介绍posted on 2019-05-09 14:40 三天打鱼,两天晒网 阅读(...) 评论(...) 编辑 收藏 转载于:https://w…

MIB in SNMP
管理信息库MIB指明了网络元素所维持的变量(即能够被管理进程查询和设置的信息)。MIB给出了一个网络中所有可能的被管理对象的集合的数据结构。SNMP的管理信息库采用和域名系统DNS相似的树型结构,它的根在最上面,根没有名字。图3画…