2012年的文件系统和存储峰会在4月1日和4月2日在旧金山举行,会议介绍在这里,主要分为文件系统,IO系统和内存管理系统三块,由于是邀请制,会议的含金量还是很高的,全球在这三个方面的大约80个人在一起总结目前的工作并讨论接下来一年在这三个方向下一步的开发计划,由于文件系统和IO系统的结合越来越紧密,所以很多session都是在一起讨论的,本文也不区分两者,而统一放在一起阐述。
file system consistency
这个议题实际上是今年FAST的一篇论文,来自University of Tornoto的Ashvin Goel和Daniel Fryer介绍了他们的工作,主要思想是在运行态通过各种预先设定好的invariant来动态检查各种文件系统error,从而尽早的发现问题,具体的论文可以参见这里。 想法不错,但是内核开发者对额外的内存以及cpu消耗表示担忧,所以具体的能否在工业界实现还有待进一步的研究。
write back status update
吴峰光同学介绍writeback最近的进展,io-less dirty throttling已经有了明显的进展(70%),目前的主要工作集中在balance_dirty_pages中,通过计算dirty_limit以及这个程序的dirty_ratio,可以设置程序合适的dirty速度(通过让程序睡眠来实现),从而让多个io heavy的程序能够同时开展工作并且没有太大的波动,延时也会比较稳定。而且目前Mel Gorman已经将Pageout从direct reclaim里面拿掉,而由flusher来完成写入,所以writeback就显得更为重要。接下来的工作可能有以下几个方向:
1. dirty page虽然不会被direct reclaim写入,但是仍然会存在于lru中,这样多次的scan会浪费多余的cpu,添加一个新的page flag并将它们挪到新的队列似乎是一个选择。
2. blkcg IO controller for buffer write:由于目前的blkcg只能对read/sync write起作用(blkcg需要使用进程上下文,而对于buffer write IO,上下文已经丢失),而write back的上下文则刚好是在buffer write,这也就使blkcg对buffer write的控制在这里实现变得顺理成章。峰光已经有一个patch set,但是Tejun似乎对这个提案不太赞成,他认为blkcg的工作应该交给block层来做,但是从我和峰光的讨论来看,这里涉及到大量的修改以及不必要的overhead,我个人还是比较看好峰光的实现,当然他们方案的pk还在继续,有兴趣的同学可以参见这里。
3. per-memcg的dirty limit:由于目前只有一个全局的dirty limit,导致对memcg的控制较弱,这个可能是google比较感兴趣的一个方案,下一步他们应该会投入一定的人力来做这个事情。
Writeback and Stable Pages
这个还是stable pages的老问题,他的来龙去脉可以看这里, 解决方案有三种:
1.上层做rewrite,这个比较复杂,所以一直不被看好
2.上层等待底层的写结束以后再做新的写入
3.上层发起新写请求的时候做cow拷贝出新的数据出来,这样新的上层写入和底层的i/o操作互不干扰
去年LSF的一致结论是使用wait_on_page_writeback,也就是方法2。可是今年Ted T’so在google集群中发现了问题,就是写会被阻塞很久(具体的thread可以参见这里),于是方案3又被重新提起。但是这里有一个问题就是随着底层i/o设备速度越来越快,cow的方法真的能比等待写入的速度更快么? 目前的结论是由底层的i/o设备向上层也就是文件系统报告它是否需要stable page的支持,文件系统则会告诉i/o层是否会给予一个stable pages。这样对于一般不支持stable page的设备,盲目的wait_on_page_writeback就不再需要了,这样可以部分避免google遇到的问题,而wait_on_page_writeback则继续是那些需要stable page的设备的方案。目前的redhat内核对stable page的支持还没有加入,所以google的问题我们应该暂时还不会遇到。
copy offload
copy offload这个概念实际上很早就在SCSI-1中已经有描述,但是一直没有普及。可能是由于最近big data的兴起,copy offload才重新火了起来。其实这个概念很简单,就是用户的copy被offload到了存储端直接完成,从而节约了大量的用户和存储间的带宽以及内存,cpu等的消耗。如果extended copy能够被copy源以及copy目标的存储系统支持,那么大数据的备份将非常方便。
这个的实现目前还在探索阶段,SUSE的Hannes Reinecke介绍了他的一些尝试,一种是通过扩展FIEMAP来实现,但是FIEMAP目前的一些问题似乎还没有解决。另外一个方案是添加一个xcopy的system call,但是可能会有一些长时间的阻塞,另外这个和sys_sendfile基本很像,还有就是这个方案就完全是linux自己的方案了,posix的兼容完全无法保证。
In Kernel AIO/DIO
目前内核的AIO实现是使用的user pages,所以这套路径在内核里面就没有办法使用了。Oracle的Dave Kleikamp提到修改iov_iter,让它可以同时容纳iovec(用户传过来的)和bio_vec(内核传过来的),并修改direct_IO的路径,这样在内核态就可以使用了。
他同时提到了自己对loop back设备的修改,让loop back设备能够直接发送AIO,从而避免Loop back设备所在文件系统的cache。这套方案对于基于文件image的虚拟机有很大的帮助,我个人认为Oracle VM就是使用的这种方式。KVM应该也可以从中收益。
RAID engine Unification
由于pNFS开始有RAID方面的需求,所以现在内核里面的实现已经有MD,DM,btrfs了,所以Boaz Harrosh提议能否创建一个新的raid实现,其他的都可以调用这个实现。当然这个首要前提就是不能影响现有的工作,并能够通过lvm raid的一套工具来管理,又一项重大的工程。
xfstests
Dave Chinner提到了xfstests的一些进展,现在xfstests正在逐渐成为一套标准的文件系统测试工具,里面大概有100个测试是和底层文件系统无关的,当前还有一些不足需要进一步去完善。我在参加ext4 workshop的时候也和Ted聊过,Ted也建议采用xfstests作为基本的regression test工具,而如果有新的测试用例也需要逐渐往xfstests里面添加。
Flush media
SanDisk的Steven Sprouse介绍了flash设备的特点,以及接下来的可能工作方向。
目前的flush设备生命周期的计算都是以TB或者PB为单位,也就是说有一个简单的公式
lefetime terabyte writes = physical capacity * write endurance / write amplification
容量physical capacity在不断增加,但是成本也在增长,写的次数write endurance却随着密度的增大在下降,写放大write amplification取决于很多因素比如usage,block size, over provision, trim等。目前nand的发展趋势是block size越来越大(2004年的时候是64KB,现在则到了1MB),每个cell的bits越来越多(密度越来越大),单位bit的写次数在降低,所以一些厂商的ssd内部也已经是混合存储了(一些写次数多的SLC被用于journal等,其他的数据则放在成本较低的MLC里)。
关于写放大,一般的认为是随机的写会导致一定的写放大,但是这里有一个问题是多大的写才算呢?理论上来说只有当写的大小比ssd的block size大的时候才可以,但是block size信息一般ssd是不会暴露出来的,而且上文也提到过block size现在的趋势是越来越大,所以也许今天的顺序写到明天就变成随机写。Christoph Helwig甚至提出小于64M的写都是随机写,那么到底该如何呢?最优的方案是ssd能够把block size暴露出来,让上层文件系统了解到这些信息。
所以最终的话题自然转到文件系统和block设备层之间如何更好的合作呢?
1. 文件系统能够告诉block层那些数据会在同时消失,这样ssd可以把它们放在一个block上,删除的时候整个block就都能重新使用,Ted提到一个很好的例子,rpm,一般一个rpm包安装的文件的生命周期都是一样的,同时被安装,同时被删除。
2. block层能够上报文件系统自己的一些信息,比如上文提到的block size, page size, stripe size等,让文件系统更好的利用这些信息
3. block层提供机制能够让文件系统提供数据的tag(比如那些数据会经常被更新和访问),这样底层设备可以做相应的处理
4. 文件系统能够做一些flash设备的清理工作(如trim),帮助设备更好的工作
关于合作,Steven还举出了一个很好的例子,有A,B,C,D四个文件,对于底层设备有两种存储模式
interleave mode
die1 die2 die3 die4
a1 a2 a3 a4
b1 b2 b3 b4
c1 c2 c3 c4
d1 d2 d3 d4
这种模式下,文件的读取由于可以在并行的在4个die上执行,会非常快,但是一旦涉及到数据更新,写放大就会比较严重。
另一种模式是non-interleave mode
die1 die2 die3 die4
a1 b1 c1 d1
a2 b2 c2 d2
a3 b3 c3 d3
a4 b4 c4 d4
这样的话更新的时候写放大很小,但是读取就会比较慢了,因为只能在一个die上串行。这时候如果文件系统(或者应用)能够提供必要的信息,底层设备就能够更好的布局。
Device mapper and Bcache
还是老议题,facebook的flashcache以及google的bcache都是以快速ssd设备来做慢速设备的cache的解决方案,flashcache基于device mapper,bcache则需要修改内核,但是效率更好一些。内核到底应该怎么弄,大家只是觉得需要一个,但是需要那一种还没有达成一致。
high iops and scsi/block
Roland Dreier首先描述了目前block层设备驱动的两种模式:make_request类型的(设备直接注册make_request,从而可以忽略大部分block层的函数)和基于request类型的(由于queue_lock的存在有大量的contention)。前者工作在底层并且无法使用很多block层的功能(最明显的一点是blktrace利用的很多trace point已经无法使用了),而后者则效率比较差。Jens提到他正在进行的multi-queue工作,并承诺将尽早发出,这个对于一些通用的快速ssd设备(而不是像fusion io那样使用专属驱动)应该会有很大的帮助。
LBA hinting and new storage commands
Frederick Knight首先介绍了SMR技术(shingled magnetic recording),通过SMR可以进一步提高磁盘的密度(具体原理请google之),但是带来的问题就是在写数据的时候需要一次写一个band,如何处理这个问题呢?
1. transparent: 完全对用户透明
2. band把信息向上汇报然后让上层来处理
3. 使用hints让上层和设备层互相传递部分信息,具体的策略则由各自自行决定
社区目前是趋向第一种方案(当然,这样内核完全不需要修改),或者方案三。
大数据相关的,淘宝还是非常牛的
http://blog.tao.ma/?p=36