Log-structured File Systems
换到博客园排版有问题,原版在这里:http://xubenbenhit.github.io/LogStructureFileSystem.html
Log-structured File Systems
先来扯淡,这篇博客讲的是LFS,之前写的硬盘与磁盘冗余阵列其实是第一篇,而这个应该算是第三篇,这中间差了一篇介绍文件系统的博客,原本打算今天回去之后一起写了,但是考虑到自己回家之后的效率不敢保证。故而先在实验室写完这个文章,而文件系统的资料全部在家。
1. 什么是LFS?
首先回顾一下我们是怎么来写Log文件的,不就是把最新的状态一行一行的写在日志文件的最末尾么(这个联系是我自己YY的)。那么Log-structured File System也是一样,就是更新数据的时候直接将数据放在末尾。如下图:
一开始,我们写入磁盘数据块Foo,然后旁边的A是它的inode:
然后,我们再写入块Bar,旁边的A'是inode:
最后,我们更新数据块Foo,获得Foo',这时候我们将其写回磁盘,就变成这样子:
2. LFS是怎么来的?
LFS是在上个世纪九十年代前后搞出来的,当时的主要考虑有这个几点(道听途说):
❝
内存越来越大,进而可以不断扩充Cache的容量,也就会意味着数据读取操作可以越来越不需要访问磁盘了,进而使得磁盘写操作越来也成为性能瓶颈;
序列磁盘数据读取速度跟随机读取磁盘数据速度的差距越来越大,这种情况下如果可以将随机磁盘操作转换为序列磁盘操作,则收益可观;
处理小文件的时候,之前的文件系统效率不高,而事实上小文件才是常见的;此外对于小文件的写操作,磁盘本身也不擅长,因为RAID4/RAID5处理小文件的时候性能也是不高的;
❞
因为有了这些,所以就有了LFS。LFS首先将磁盘数据的更新缓存在Cache中,当缓存到一定规模(称之为一个segment)的时候再一次性写入空闲磁盘,由此获得高性能。 当然了,说起来很简单,做起来就不是喽,这里面主要有两个方面的问题:其一是整个操作过程中的文件定位;其二是磁盘空间管理。
这里我觉得就不按照论文的思路来写了,因为没劲,不如就按照自己的理解一步步来做推演吧,比较论文作者也是自己一步步想出来的。
3. 开始推演
LFS是先在内存在存储文件更新,这个存储单元称之为一个segment,等到segment存满了的时候再一次性写入空闲磁盘。于是乎就需要首先保证整个操作的正确和高效。
首先,根据FFS(Fast FIle System)的设计经验,需要用一个inode来存储这个segment中每个文件的元信息,也就是文件的一些属性,诸如大小、文件块(文件可能需要多个磁盘block来存储)的物理地址、权限等等。当然了,inode也是在segment中的,为了方便考虑就存储在对应文件的后面,见第一部分的图。注意一点,这个inode一般很小,只有128Byte左右。
按照FFS的设计,将inode存储在一块连续的磁盘空间(物理地址是可以事先计算的),但是一次性将segment写入磁盘这个操作本身就会使得文件的inode“散布在”整个磁盘空间,而且按照LFS的设计,文件是不可能被原地修改的,这也就意味着最新版的文件的inode的地址始终在变化!!故而按照“惯例”,设计一层间接连接(indirection),称为imap,用来存储各个inode的物理地址。
既然有了imap,那么问题来了,imap存储在哪儿?第一种选择是将其存储在磁盘的某一固定位置,但是我们注意到每次写segment的时候都会对imap进行更新,而每次更新imap都需要将磁头转到固定位置,有点影响效率啊!不如将imap放在inode后面吧。
这里多说一句,imap本身可能也占用多个磁盘block,故而只需要将更新的那一块imap放在inode后面就可以了。这样又有个问题,imap地址不确定,怎么寻址呢?所以还是需要一个地址确定的区域,里面存储imap的地址就可以了,这个区域称之为CheckRegion,这里面存储了imap各个block的物理地址。就可以通过CheckRegion->imap->inode->file的方式定位到文件了。但是,文件夹怎么处理?
按照FFS的设计,所谓的文件夹无非就是一些文件名和文件inode的映射,在FFS中文件夹被当做普通的文件数据来存储,那么LFS也这么干。于是我们就可以看到 /dir/foo 是这样存储的:
具体而言是这样,首先定位到dir文件夹的inode所在的imap,然后根据查找到dir文件夹的inode物理地址,然后找到dir文件夹的物理地址,进而获取foo文件的inode,然后在CR->imap->inode->foo。注意到这样设计还有一个意外的好处,就是说文件夹下的文件更新操作是不需要更新文件夹本身的,这也就避免了“递归更新”文件夹的文件夹的文件夹。。。好的,至此,文件定位以及没有问题了。但是每次这样将segment写入空闲磁盘,一直这样下去,哪有那么多磁盘呢?这就涉及到磁盘空间回收(segment cleaning)的问题了。
一般来说,磁盘空间回收大致需要这三步:首先将一些segment读入内存;然后判断segment里面的block数据是否是“存活的”,也就是说文件是否处于最新版本;最后将所有的“存活”文件集中写进segment中,而将剩下的空间回收。如何判断block是否为最新版本?
为了实现这个功能,那么就需要知道segment中block的原信息了,比如它所归属的文件inode以及在文件中的位置。这些信息需要存储在segment中的一个称为segment summary block的区域中。那么我们就可以查找这个block数据的当前物理地址,比对一下就知道是否是最新版了。当然了,这样一来,最好将imap整个加载到内存中方便查询。
当然了,可以改进这个设定,为每个文件设置版本号,每次文件更新版本号递增,将这个版本号存储在segment summary block以及imap中,这样只需要比对一下文件版本号就可以判断整个文件是否是最新版本了。关于segment clean,什么时候执行呢?执行clean达到什么目标就停止呢?怎么选择segment执行clean?以及是否需要重组live file以便获得更好的locality? 第一个第二个实验表明不太重要,实际操作而言,设置两个阈值,点那个空闲segment数目低于某一阈值后执行clean,当回收使得空闲segment数目高于另一阈值后停止clean。
第三个问题很有讲究,事实上,论文中采用的算法是计算每个segment的clean性价比(cost-benefit),这个计算公式具体参考论文吧。为此在CheckRegine中保存一个segment usuage的表单。
第四个问题,也是很有技巧性的地方,论文中的做法是按照存活文件最近一次更改时间的顺序依次写入segment中。至此,描述的差不多了,下面看看两个细节。
Check Point Check Region中包含的数据imap地址以及segment usage等等都是在变化的,所以需要每过一段时间更新一下。正常情况下先将Cache中的segment写入磁盘,然后更新Check Region,因为考虑到更新CR过程中也可能出现异常,所以用两个timestamp块包裹住真实的CR数据,只有当前后两个timestamp一致的时候才认为这个CR是正常的。为了避免在更新CR过程中出现故障导致CR不可用,LFS使用两个CR,交替使用,这样即使故障了,也可以用另一个CR来恢复。
Crash Recovery 遇到特殊故障,LFS怎么恢复呢? 首先,寻找到最新的可用CR,这里的“可用”表示该CR的前后timestamp是一致的。然后使用论文中提及的Roll-Followed算法来恢复。这里面有一个“奇怪”的地方,就是说imap的最新版block不都已经在segment里面了么,那么直接用这个更新就可以了嘛!!其实不是的,因为考虑到磁盘写操作的时候imap本身可能没有写正确。。。。
至此,应该是差不多了,详细的东系统的介绍直接看下面的资料吧。
4. 参考文献
❝
- http://pages.cs.wisc.edu/~remzi/OSTEP/file-lfs.pdf
- http://www.eecs.berkeley.edu/Pubs/TechRpts/1992/CSD-92-696.pdf
- http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.54.502
- http://blog.notdot.net/2009/12/Damn-Cool-Algorithms-Log-structured-storage
❞
Log-structured File Systems的更多相关文章
- The storage wars: Shadow Paging, Log Structured Merge and Write Ahead Logging
The storage wars: Shadow Paging, Log Structured Merge and Write Ahead Logging previous: Seek, and yo ...
- SSTable and Log Structured Storage: LevelDB
If Protocol Buffers is the lingua franca of individual data record at Google, then the Sorted String ...
- Introducing Microsoft Sync Framework: Sync Services for File Systems
https://msdn.microsoft.com/en-us/sync/bb887623 Introduction to Microsoft Sync Framework File Synchro ...
- Mounting File Systems
1.Mounting File Systems Just creating a partition and putting a file system on it is not enough to s ...
- Canal 同步异常分析:Could not find first log file name in binary log index file
文章首发于[博客园-陈树义],点击跳转到原文Canal同步异常分析:Could not find first log file name in binary log index file. 公司搜索相 ...
- Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'系列一:
从库报这个错误:Got fatal error 1236 from master when reading data from binary log: 'Could not find first lo ...
- centos重启报错Umounting file systems:umount:/opt:device is busy
系统重启报错: Umounting file systems:umount:/opt:device is busy 只能硬关机,回想一下最近刚安装了nod32 for linux x64的杀毒软件,开 ...
- mysql从库Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'报错处理
年后回来查看mysql运行状况与备份情况,登录mysql从库查看主从同步状态 mysql> show slave status\G; *************************** . ...
- 'Could not find first log file name in binary log index file'的解决办法
数据库主从出错: Slave_IO_Running: No 一方面原因是因为网络通信的问题也有可能是日志读取错误的问题.以下是日志出错问题的解决方案: Last_IO_Error: Got fatal ...
随机推荐
- 经典SQL语句基础50题
很全面的sql语句大全.都是很基础性的,今天特意整理了下.大家互相学习.大家有好的都可以分享出来, 分享也是一种快乐. --创建数据库 create database SQL50 --打开SQL50 ...
- POSt 提交参数 实体 和字符串
//1.后台接受是 字符串形式 [HttpPost] public int SendTaxiAudioByWX(string userid, string suid, string indexno, ...
- jquery validate 一个注册表单的应用
先看页面 前端表单代码 register.html <form class="mui-input-group" id="regForm"> < ...
- 【数据库】mysql中复制表结构的方法小结
mysql中用命令行复制表结构的方法主要有一下几种: 1.只复制表结构到新表 ? 1 CREATE TABLE 新表 SELECT * FROM 旧表 WHERE 1=2 或者 ? 1 CREATE ...
- BZOJ 1226 学校食堂(状压DP)
状压DP f(i,j,k)表示前i−1个人已经吃了饭,且在i之后的状态为j的人也吃了饭(用二进制表示后面的状态),最后吃的那个人是i之后的第k个 (注意k可以是负数) 然后 如果j&1=1那么 ...
- 题解 P1808 【单词分类_NOI导刊2011提高(01)】
大家用的方法都太好了!! 蒟蒻小金羊来发一篇玄学堆排. STL大法好! (附有核心code详解,完整code) 核心:两次排序,第一次自我排序,第二次整体排序. 核心code1: string str ...
- 创建Django工程-Day19
1. 新建一个day19的工程和app01. 2. 新建templates和static的文件夹. 3. 去settings.py中去做配置. 1)注释掉csrf 2)配置模板路径 'DIRS': [ ...
- 洛谷 P3539 [POI2012]ROZ-Fibonacci Representation 解题报告
P3539 [POI2012]ROZ-Fibonacci Representation 题意:给一个数,问最少可以用几个斐波那契数加加减减凑出来 多组数据10 数据范围1e17 第一次瞬间yy出做法, ...
- HPP注入详解
###HPP参数污染的定义 HTTP Parameter Pollution简称HPP,所以有的人也称之为“HPP参数污染”,HPP是一种注入型的漏洞,攻击者通过在HTTP请求中插入特定的参数来发 ...
- scala(三)
一.面向对象编程——类 1.定义一个简单的类 class HelloWorld { private var name = "leo" def sayHello() { print( ...