主文件系统 vs 二级文件系统 (微软篇)

本文主要基于FAST11和FAST12的两篇论文:A study of practical deduplication和Characteristics of backup workloads in production systems。前者来自微软,主要分析的是用于主存储系统的文件系统;后者来自EMC,分析的是用于二级存储系统(如备份、归档)的文件系统。两篇论文共同的特点是实验的数据集都非常庞大,因此分析的结果对于系统设计具有参考价值。而且从数据中我们也可以发现主存储系统和二级存储系统在使用方式等方面有很多区别。

先来看看微软的实验。

1. 实验方法

作者的数据来源是微软员工(包括开发、测试、管理、销售、支持等各种角色的员工)正在使用的PC机,包括857个文件系统,共162TB的数据。这些参与测试的员工都是随机选出来的,每个人的PC上都会安装一个文件系统扫描器,扫描器在09年9月18日至10月16日期间每礼拜自动运行一次,共运行了四次。

扫描器运行的时候会对文件系统创建快照,接着:记录文件系统自身的元数据,包括容量、利用率等;分析每一个文件,将文件元数据(路径、文件名、后缀等)写入日志;记录检索指针和分配指针,依次用于分析文件系统的碎片情况和稀疏度;记录整个系统的信息,包括硬件信息、软件配置信息、碎片整理程序上次的运行时间。

在扫描的过程中,扫描器分别使用两种分块算法(定长分块和基于Rabin指纹的变长分块)和四种块长(8KB、16KB、32KB、64KB)将文件分块,并且计算每个数据块的指纹。除了读取文件的正常数据外,作者还用BackupRead API(该函数用于备份文件)读取文件的一些元数据。指纹算法用的是MD5,但是为了减少数据集规模,指纹被截断为6个字节(MD5摘要为16个字节)。使用8KB平均块长的Rabin分块算法会产生最多的指纹(768M个指纹),作者预期大约2000个指纹(占0.0003%)会由于截断指纹而被误判(猜测了下作者的计算方法:假设MD5摘要截断后的6字节摘要是完全随机分布的,那么1对数据块碰撞的概率为1/2^48,那么碰撞指纹数的期望大约是1/2^48*(768M*768M/2)*2=2000个,这应该是期望的上限)。

每周一个随机的晚上,会有另外一个进程将日志文件上传到作者的服务器上。大日志文件相比小日志文件更容易不完整传输,因此大日志文件更容易被排除在分析数据外,这就导致数据有一些偏差:大文件系统以及小块长分块的日志文件更容易丢失。

最终收集到的数据集经过压缩有4.12TB,导入数据库需要很长的时间。作者注意到非重复数据块的指纹对于分析是无用的,可以删去进行优化。为了找出这些无用的指纹,作者遍历了两遍数据集。第一次遍历,每遇到一个指纹就插入bloom filter A中,如果该指纹已经存在,就将其插入bloom filter B。第二遍扫描,不在bloom filter B中的指纹可以被判断为非重复指纹(只被引用一次)。虽会漏掉部分非重复指纹,但并不影响实验结果。

2. 文件系统元数据

2.1 文件系统

图1 文件系统容量

图1是微软实验文件系统容量的累计密度函数,平均容量为194GB。与2000年和2004年的实验结果相比,容量上升趋势明显,基本遵从物理磁盘容量每年翻番的规律。

图2 文件系统利用率

虽然容量自2000年来上升了2个数量级,文件系统的利用率却轻微下跌了,目前平均利用率为43%,而2000年是53%。如图2所示,现在50%的用户存储利用率不超过40%,当然也有15%的用户存储利用率超过70%。用户的空闲存储空间是一笔可观的资源。

图3 文件数和目录数

图3所示是文件系统中的文件数和目录数,相比前几年出现显著增长,平均有225K个文件和36K个目录。

图4 目录文件数


图5 目录子目录数

另一方面,图4显示了每个目录包含的文件数变化趋势,可以看到出现了轻微下降,平均每个目录包含6.25个文件。而图5中,一个目录所包含的子目录数也出现了轻微下降,这意味着目录树结构变的更深了。

图6 目录深度和字节数的关系

图7 目录深度和文件数的关系

图6展示了目录深度和存储之间的关系,在五级目录之后存储的字节数出现了大幅下降,大部分数据存储在五级目录之上。图7展示了目录深度和文件之间的关系,结合图6可以发现深层次目录的文件要比高层次目录的文件小一些。

作者还分析了磁盘的碎片情况。早年的研究表明,由于磁盘碎片,文件系统的性能会越来越差,然而现在碎片的问题得到了显著改善,大约只有4%的文件出现了碎片的情况。碎片倾向于聚集在一些文件里,25%的碎片出现在有170+碎片的文件,碎片最严重的文件是日志文件。

2.2 文件

图8 文件大小

文件大小的分布几乎没有变化,文件平均大小仍是4KB,这个数据至少从1981年开始就没有变化了。仔细观察,实际上4KB大小左右的文件增多了,而且512KB至8MB的文件也增多了。


图9 字节分布

图9告诉我们大多数字节存储在什么样的文件里了。大多数字节存储在大文件里,即使大文件数量不多,这启发我们设计重复数据删除时,应该更加重视大文件,而小文件不仅占用资源较多,而且提供的压缩率很少。

图10 文件修改时间

图10展示了文件的修改时间,大部分文件的修改时间是1月到1年以前,大约20%的文件在最近一个月被修改了。最右边的图比较了文件修改时间和文件系统的寿命,x轴表示文件自上次修改以来的时间除以自文件系统上次格式化以来的时间,超过100%的文件表示这些文件在安装文件系统之前就存在了,是复制过来的;在100%附近有一个凸起,代表了安装系统过程修改的文件;0%至100%的曲线逐渐下降。

图11 最流行的后缀名

图11显示了最流行的10个后缀名,现在后缀名的种类更加多样了,最流行的10个后缀名占据了文件总数的45%,而2000年这个数字是50%。

图12 最消耗存储的后缀名

图12显示了10个最消耗存储的后缀名。无后缀名的文件所占比重增长明显,取代dll文件拔得头筹;VHD和ISO文件是磁盘镜像文件,增长迅速,但不及lib文件;最后,这top 10后缀名所占比重比往年上升15%左右。

3. 重复数据删除

虽然单位存储价格显著降低了,但是企业的存储总成本却不断上升,因此重复数据删除技术得到越来越多的关注。作者选择了一个礼拜的数据,采用不同分块参数(算法、块长),评估算法和块长对重删率的影响。作者引入了重删域的概念,在不同域的文件系统是独立进行重删的,域的大小也是实验参数之一。比如域等于1表示每个文件系统单独进行重删,域为“Whole Set”表示全部857个文件系统共同重删,作者测试了不同大小的域(大小为1~857之间2的幂,1,2,4……)的重删率。

图13 分块算法和块长对重删率的影响

图13显示了分块算法、平均块长对重删率的影响,y轴是重删后的存储大小除以重删前的存储大小,因此越小重删率越高。域的大小为"Whole Set",其它更小域的曲线也与此类似。文件级重删不受块长影响,所以是一条直线。可以看到基于Rabin指纹的变长分块重删率最佳,分块越小重删率越好。

图14 域大小对重删的影响

图14是不同域大小对重删率的影响,重删率几乎随着log(域大小)增长线性改善。比较图13和14,作者认为域大小的选择对重删率的影响要大于分块算法和块长的影响,甚至也要大于重删选择文件级还是块级的影响。采用平均块长为8KB的rabin分块算法,比文件级重删多删除了18%~20%的数据;而块长8KB的定长分块算法,比文件级重删多删除10%~11%的数据,作者认为这相比于变长/定长块级重删带来的性能开销和复杂度,是不划算的,主存储系统是否需要块级重删值得商榷。作者接着对文件级重删进行了分析。

表1 文件级重删与后缀的关系

表1是文件级重复数据的最多的15种文件,各自对重删的贡献率以及平均文件大小。这是”Whole Set“的实验结果。结果显示重复文件主要是二进制文件:dll,lib,pdb,exe,cab,msp和msi一共贡献了58%的重复数据。

图15 文件级重删,文件大小与重删数据量的关系

图15显示了文件级重删中,重复数据与文件大小的关系。看起来重复数据大多在小文件里,大文件如磁盘镜像,很少会出现完全重复的文件,这在表1中也可以看出来。接着作者对块级重删也进行了类似分析。

表2 块级重删,后缀名与重删率

表2是块级重删中,重复数据与后缀名的关系,包括了定长和变长两种分块,平均块长都是8KB,”Whole Set“数据集。对于两种分块算法,最大重复数据来源都是vhd(virtual hard drive)文件,这些文件存在大量重复数据,但同时又很少完全重复,可以说是块级重删优势的最大来源吧。之后的四种文件都是编译器输出文件,这些文件存在块偏移的问题,它们的内容可能相同,但是头部数据(时间戳等)不同,导致定长分块的重删率下降。

4 总结

用于主存储系统的文件系统容量在不断增大,利用率基本不变;大多数文件是小文件,但是大多数字节存储在大文件中,平均文件大小是318KB,大多数文件只会写一次,暗示了读操作多于写操作;目录树结构变深;后缀名呈现多样性的趋势;磁盘碎片问题有所缓解。

在域为1的情况下,变长块级重删能删掉40%左右的数据,其中大约一半来自重复文件;虽然块级重删相比文件级重删对性能影响更大,复杂度更高,但是我觉得变长块级重删能多删除20%的数据很有诱惑力,鱼和熊掌可以兼得么?

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
共两个不同设计例子,都含详细的文档资料。 任务2.设计一个简单的二级文件系统 设计要求: 在任一OS下,建立一个大文件,把它假象成硬盘,在其中实现一个简单的模拟文件系统。 编写一管理程序对此空间进行管理,要求: 1. 实现盘块管理 2. 实现文件的读写操作 3. 每组最多2人,小组内要有明确分工,课程设计报告中设计部分可以相同,个人实现部分不同 参考建议: 将模拟硬盘的文件空间划分为目录区,文件区;采用位示图进行空间管理,盘块的分配使用显示链接(FAT表)的方式。 设计技术参数(数据结构)参考: #define MaxSize 100 #define Disk 512 //每个盘块大小为512bit #define NumDisk 2048 //有2048个盘块,既可分配空间为 1M /*************目录和文件的结构定义***********************/ struct DirectoryNode { char name[9]; /*目录或文件的名字*/ int type; /*0代表目录,1代表普通文件*/ struct DirectoryNode *next; /*指向下一个兄弟结点的指针*/ struct DirectoryNode *preDirFile; /*指向父结点的指针*/ struct DirectoryNode *subFile; /*指向第一个子结点的指针*/ int size; /*如果是文件则表示文件的大小*/ int first; /*起始盘块号*/ int last; /*末尾盘块号*/ int order; /*备用*/ }; //连续分配 struct FileSys { int VacTable[NumDisk]; //空闲表,0为空闲,1为被用 struct DirectoryNode root; //根目录 struct DirectoryNode Directory[NumDisk]; } *filesys; typedef struct { struct DirectoryNode *DirFile; char name[9]; }DataType; //包含一个指向目录的指针和名字 typedef struct { //队列结构的实现 DataType data[MaxSize]; int front,rear; //分别表示队列的头结点和尾结点 }Tp; void InitQueue(Tp *sq) //队列初始化 int EnAddQueue(Tp *sq,DataType data) //在队列中增加元素 DataType EnDelQueue(Tp *sq) //从队列中删除一个元素 int Empty(Tp *sq) //判断队列是否为空,返回0表示队列为空 ①.Dir:显示目录内容命令,显示当前目录下的文件和子目录。 ②.Md:创建目录操作。 ③.Create:创建文件,在当前目录下创建一个文件。 ④. all:显示从根目录开始的所有目录和文件及其层次结点。 ⑤.Cd:改变目录。 ⑥.Del:删除文件操作。 ⑦. Rd:删除目录操作,删除当前目录下的子目录。 ⑧. Ren:重命名函数 ⑨. Exit:退出命令

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值