Ext4 Workshop 2014

作者:刘峥

2014年3月26日,Napa Valley, CA.  今年LSF/MM Summit 2014会议就在这里举行,因此Ext4 Workshop相应的也就在这里了。会议内容主要是讨论后续一年Ext4文件系统的开发问题。

今年讨论的内容如下:

  1. Data Block Checksums
  2. Reflink
  3. Encryption
  4. Extent Cache Shrinker
  5. Buffer_head Removal
  6. SMR/Flash Device Optimization
  7. Multi-block Allocation
  8. Testing
  9. Mount Options Restrict

与会人员:

  • Ted Ts'o (Google, Ext4/Jbd2 Maintainer)
  • Jan Kara (SUSE, Ext3/Jbd Maintainer)
  • Ric Wheeler (Redhat)
  • Eric Sandeen (Redhat)
  • Lukas Cerner (Redhat)
  • Carlos Maiolino (Redhat)
  • Darrick Wong (Oracle)
  • Zheng Liu (Alibaba)
  • Michael Halcrow (Google)
  • Eric Whitney
  • 两位来自Western Digital的工程师

1. Data Block Checksums

目前Ext4已经具备对元数据进行校验的能力。如果需要对文件系统元数据做校验,仅需通过如下命令即可:

# mkfs.ext4 -O metadata_csum ${DEV}

目前Redhat计划让文件系统支持数据的校验和,来保证数据的正确。由于需要在文件系统中保存每个数据的校验和信息,因此需要在文件系统中创建相应的数据结构来保存信息。目前有两个方案:

  1. 静态方案
  2. 动态方案

静态方案比较简单,类似于metadata checksums,预先在格式化文件系统时直接在每个block group中创建出需要的数据结构。这样的好处是简单,对文件系统的改动比较小,同时很容易根据block group直接找到对应的校验和的位置。缺点则是不太灵活,对一些不需要做校验的block也需要分配出相对应的空间(比如extent tree)。

动态方案则直接在inode或者block group的描述符中直接创建一个B+tree,所有的校验和均保存在其中。这样在查找/创建校验和的时候时间复杂度会有所上升。特别是在block group中分配的方案,由于多个文件可能同时修改同一个block group中的B+tree,所以会有锁争用的开销。

Ted指出静态的方法比较简单直接,可以一点点的改进。如果采用动态方案,则比较复杂。当然,理想情况下,Ted比较喜欢动态的方案。毕竟通过动态方案的实现,不仅仅是data block checksums的问题,连reflink的实现也会简单很多。另外就是一些细节的讨论,比如fsck的时候对data block checksums的检查、df显示磁盘空间时候的计算等等。

2. reflink

由于Mingming Cao没有出席今年的Ext4 Workshop,目前为止reflink的设计方案也没有任何邮件,同时Darrick也不太了解目前reflink的可能实现,因此reflink的讨论就变得极其有限了。reflink(2)调用的目的是创建一个新的inode,但是该inode指向的内容均为另外一个已经存在的文件。这个新创建的文件是COW的,对它的所有修改都不会反应在此前的文件上。正如上面介绍data block checksums时所说,reflink的实现需要创建一个B+tree来记录那些没有修改过的block,而如果有了data block checksums的动态B+tree,则问题迎刃而解,只需要在该B+tree中进行记录就解决了。具体reflink的实现,还是需要等相关的邮件才能揭晓。

3. Encryption

文件数据加密这个之前并不在讨论范围,是开会当天加上的,而且鉴于是Google需要的需求,所以排的位置十分靠前。文件系统的数据加密功能很容易理解,就是将写入文件的内容先进行加密再保存在磁盘上。在Ext4上加这个功能的原因是因为Android操作系统。印象中从Android 2.4之后的版本(我不是Android用户,不太了解 ^ ^)开始,默认的文件系统变成了Ext4。由于用户会在手机上登录各种网站,所以Chromium浏览器会将一些个人用户信息以文件形式保存在手机上。这当然没啥问题,除非您哪天手机丢了。那么这些用户的信息就存在被获取的可能。各位当然也不用担心太担心,因为目前Android系统上会在Ext4上再使用eCryptfs对文件数据进行加密保存。所以您的个人数据还是安全的。但是用Michael Halcrow的原话来讲就是,这完全是个错误。

所以为了纠正这个错误,目前Google的想法是让Ext4原生支持数据加密。关于具体的加解密理论我也不太了解,可说的不多。但是鉴于Google的原因,估计这个特性很快就会加到Ext4上。

4. Extent Cache Shrinker

再提这个问题的原因是在与PostgreSQL开发人员的交流过程中(这次LSF/MM邀请了几位PostgreSQL的开发者来分享一些他们对Linux Kernel开发的希望)发现他们也遇到了Shrinker回收过程过长的问题。这个问题很早就被报告给了社区,不过我一直没有时间去改进,对不起各位了。

目前Extent Cache Shrinker的问题主要是在RB-tree中保存了所有对象的信息。而有些对象由于需要被delayed allocation、seek data/hole功能使用,是不能被回收的,所以在某些情况下,会出现Shrinker扫描很长时间却扫描不到可以回收的对象的情况。对于这一问题,目前有两种改进方案:

  1. 添加一个list专门保存可以回收的对象
  2. 完全放弃LRU-list算法

方案1让Shrinker快速找到可以回收的对象,从而减少等待时间。但是仍然保留了目前的LRU算法,因此还是存在维护LRU的时间开销。另外,由于添加了另外一个list,内存开销会增加近1/3;方案2则完全放弃目前的LRU算法,通过指针记录上次扫描的位置,从该位置继续扫描可回收的对象。这样做可以避免维护LRU算法的开销,减少锁争用。由于目前Shrinker在回收对象时还要考虑inode的PRECACHE标志,因此较为复杂。Ted介绍目前Google内部的做法是完全不回收带有PRECACHE标记的inode,而对其他的则一概回收。当然这样做完全是出于Google自己的需要,PRECACHE的应用都是Google底层的核心应用。因此upstream kernel上不能这样做。同时由于Google大量direct IO的使用,产生delayed allocation对象的机会较少(不能被回收),所以问题也并不严重。

下一步的计划就是同时实现两个方案并比较结果。此外,对于Extent Status Tree,我还在考虑用skip list替代rb-tree的方案以减小锁争用的开销。

5. Buffer_head Removal

目前在Linux Kernel中,buffer_head结构的核心作用尽管已经被bio取代,但是仍然有大量文件系统的代码在使用buffer_head结构来记录文件系统的元数据信息。Ext4就是其中一个。当然,这也是没有办法的事情,毕竟VFS层的很多地方都还需要使用buffer_head结构。Ted提出这个想法的目前是在Ext4中,除了direct IO路径和data=journalled模式外,将所有使用buffer_head的路径中将这一结构干掉。这样做的目的如果是简单重构,其实意义并不大。Ted的想法是通过干掉bufferred IO路径上的buffer_head,从而避免使用buffer_head中的Delayed标记。这样就可以避免在blocksize与pagesize不同时处理的麻烦。随之而来的计划便是将dioread_nolock特性默认打开,从而提高高速设备上direct IO的性能(此特性可以解决目前Ext4中direct IO路径上的扩展性问题)。

尽管前景美好,但是Ted和Jan表示没时间搞。所以哪位有兴趣的可以试试看,做完这个,对整个Ext4的读写流程会非常熟悉的。

6. SMR/Flash Device Optimization

这块主要的改进思路其实已经体现在Ted发的RFC中了(http://lwn.net/Articles/579564/)。主要是两方面的改进,一方面是针对日志的改进,尽量减少对日志的频繁刷新,从而避免由于SMR随机写性能影响文件系统,造成性能下降。另一方面是对mballoc算法的改进,做到对SMR友好。鉴于目前大家基本都没有拿到可以测试的SMR硬盘,所以大家并没有什么意见提出。

7. Multi-block Allocation

对于mballoc算法的改进源于Lukas对使用thin-provision的Ext4文件系统进行测试时发现的问题。问题是mballoc目前的算法总是倾向于在整个块设备上分配磁盘空间,即便块设备的开头有空闲空间,mballoc也经常会分配块设备后面的空间来进行使用。这在传统磁盘上当然没有问题(其实还是有问题的,因为越往后磁盘性能越差),但是对于thinp设备就要命了,因为thinp设备根本就没有宣称的那么大的空间,所以文件系统总是分配后面的磁盘空间thinp设备自然受不了。Lukas目前有补丁来解决这个问题。但是从长远来看,还是需要改进mballoc的分配算法。目前最大的问题是很多mballoc中的代码除了Andreas Digler(mballoc的作者)就没人知道为啥要这么写了。。。

另外谈到的一个关键问题是如何测试来确保分配算法确实有改进和不是造成性能的下降。大家还是给了些意见的,包括用一些成熟的测试工具,用已有的磁盘使用情况的Tracer等等,总之目前对于mballoc的改进还没有具体方案,只是有这个想法。

8. Testing

Ted介绍了自己的测试方法,再次强调了测试的重要性并希望大家多测试。同时感谢了Eric Whitney的测试工作。Ted也提出了对于xfstests测试框架的改进意见,希望Redhat的同学能进行改进。

9. Mount Options Restrict

这个话题去年就聊过了,但是还是没有彻底解决。主要问题是去年Redhat主要在弄RHEL7,没空搭理这个小问题。但是今年RHEL7大问题都解决了,所以这个小问题又提上桌面了。主要问题还是发行版希望使用Ext4内核模块来挂在Ext2、Ext3文件系统。但是这样就存在到底这么多特性哪些特性可以用在哪些文件系统上。今年这件事情从Lukas转到Carlos身上了。

今年预计Ext4会开发的新特性如下:

  • Data Block Checksums
  • reflink
  • Project Quota
  • mballoc优化
  • Ecryption
  • Extent Cache Shrink优化

CLSF 2013讨论会纪要(二)

第二天早上先由oracle的刘博同学介绍btrfs的进展。做为集宇宙之大成的btrfs相比xfs/ext4,新功能和改进都非常多。从08年开始btrfs就内置raid5/6了,一直在做性能改进,现在性能已经比multi-device略好5%,估计是md因为引入了新的设备层,所以性能会有小小损失(不过,5%,我个人感觉大了一点)。btrfs是支持snapshot的,但是对snapshot做defrag却是最近才加入的功能,对COW类性的fs来说,这个很好。online device replace这个功能我们争吵了半天,觉得这个功能到底谁需要,跟互联网运维的磁盘更换确实不搭边。去掉了单目录下创建hardlink的数据限制。还做了很多代码清理的工作,但是btrfs还需要多多注释,否则一般人不容易看明白代码。
接下来是一年一度的老问题(反正我从2011年参加clsf就都是这个问题):btrfs什么时候稳定下来?刘博回答:btrfs已经稳定了,大家开会沟通一致认为,xfs只是btrfs的过渡。于是文卿同学问道:“你能提供我一个btrfs的配置参数,保证我用了这个参数性能最优同时一定稳定吗?“,我以为刘博同学会说”mkfs.btrfs不带任何参数就行“,结果刘博同学回答:”这个你应该问做发行版的公司,我只是开发而已“,看来“纯”软件公司的”纯“开发人员跟互联网公司的开发人员差别还真大(刘博同学,我举这个例子只为说明而已,不是针对你,如果有所得罪,线下请你吃饭赔不是),我们可是要自己backport、自己功能测试、自己压力测试、自己上线测试(能上线测试都是求爷爷告奶奶了)、自己出性能报告、自己出上线测试报告的、自己给出最佳配置和使用方案的,全套都要搞,当然,我们拿的钱比oracle中国(不算美国)的”纯“开发人员多些,这点我不抱怨。

然后是华为的沈灿泉介绍华为正在开发的私有云系统,用到了ocfs2。华为的这款虚拟机托管方案用专用存储设备做后端,前端是很多个跑xen或者qemu的client,ocfs2存的是虚拟机镜像文件和配置文件。华为的同学在使用中发现ocfs2 90%的bug都出在dlm(分布式锁管理)上,公正的说,在IO压力不大,集群里机器增减不频繁的时候dlm工作还好,但是在人造的大压力下问题就多多了。广军同学于是推荐互联网公司人见人爱的zookeeper,但是灿泉说,zookeeper性能不够,因为ocfs2不是整个集群一个master那么简单,它是对每一个文件都要一个锁管理者(一个master),连文件系统的journal都是一个节点一个,靠zk一个个选根本不行,所以还是得用dlm。大家于是说到了kernel里的那个dlm比redhat gfs提供的dlm更简单也更稳定,EMC的彭涛同学还推荐了luster的dlm,也可备选。华为已经向ocfs2社区发了46个patch,其中39个已经被收入。(这patch数还是很高的,难怪我们组今年突然说KPI可以加一部分社区的patch工作,原来是让华为最近一年的社区patch数给眼红的,唉,去年想做upstream不让做,我一年多贴应用的冷屁股贴得我心都冷了突然又说现在可以做了。算了,人生嘛,十有八九都是不赶趟)未来华为的工作是支持scsi的fence命令,通过scsi命令把主机从集群中隔离出来;还有就是集群的writeback cache,使用SSD做cache来缓解尖峰IO的压力(这招,很多文件系统,不管是单机还是分布式的,都开始采用了)。
ocfs2最早是oracle开发的,涛哥在oracle做了四年的ocfs2开发,攒下了厚厚的几百个patch。这种做upstream且不是只修bug的机会,真的很难得。不过之后几个主力开发人员离开了,ocfs2基本处于停滞状态,bug都没人修了,现在华为突然说正在使用且积极的参与开发,确实值得鼓励,开源减少重复工作,复用提高生产力。


clsf 2013

Asias He同学讲解了虚拟机方面的IO优化,主要是virtio的改进。virtio-scsi.ko做了中断的合并(这点和网卡的polling倒是很像)。block multi queue在guest机器上的引入也提高了性能。还有discard命令穿越虚拟机到达host的优化。大家提到了discard命令在磁盘上会不会影响性能,coly和我都觉得应该不会,对于磁盘,trim命令其实没有生效,但是fusionio的李少华同学提醒:SATA协议里discard是会清io队列的(为了保证trim后读返回全零的语义),性能会略有降低。少华同学果然是学贯文件系统块设备scsi加sata,一句话我们只能拜服。

LSI的Jeb Tang介绍了公司的一些新产品。LSI其实不光卖SAS/RAID卡,也卖芯片,浪潮华为都用的是LSI的芯片,然后自己设计存储卡。硬raid卡不用说,用DRAM+FLASH+SUPERCAP(超级电容)来保证服务器宕机不丢数据,而且这个DRAM不仅是保证数据不丢,它还能大大减少io的延迟,对于io深度较低的应用,可以帮助其明显提升性能,比如mysql。Jeb提到了:其实对于1T的硬盘,1G的DRAM完全够了,因为大部分应用io深度不会超过8(我表示拜服)。LSI推出了一款带压缩的RAID卡,可以在export卷大小的时候直接报出解压后的大小,当然,对监控的要求就高了。LSI还提供了mmap接口把DRAM设备直接暴露出来给类似DB写日志用,这招狠,文卿同学打算回去就让DB的同学帮忙试试效果。

Fusionio的李少华同学介绍了fast swap的相关工作。linux在内存不够的时候会把部分内存存入swap分区(如果有的话),这个swap分区一般是在磁盘上,现在有了fusionio的高速存储卡,可以把这个swap分区放在高速卡上,这样就可以疯狂的使用内存(比如一些HPC应用,动辄malloc几个TB的空间)而不用担心OOM或者swap造成的巨大性能降低。linux现有的swap代码在高速卡上跑会有很多性能瓶颈,比如pte里‘A'标记和'P'标记分别有两次TLB flush,解决办法是去掉一个或者合并TBL flush;swap先在找cluster是线性的(显然是为了磁盘读取),现在也可以改为更快的算法以迎合SSD了;per-CPU的cluster,更好的增加io合并(我问少华:fusioniio卡也需要合并io吗?少华回答:即使是高速卡,16K的io和4K的io性能差别还是很大的,最好还是略合并一下);swap代码路径上还有很多锁,像anon_vma的mutex,swap_lock还有swap address sapce lock,现在也慢慢暴露出瓶颈(有高速卡就是好啊,泪奔),少华同学都一一解之。

最后由来自ubuntu社区的汪黎博士介绍他们使用ceph做测试的各种心得。ceph已经很火了,就不介绍了。汪博士在测试各种搭配的local fs后发现:btrfs最快但最不稳定,xfs出过一次io error然后无法mount了,ext4一直正常(文卿听到这里激动得都快哭了,当面表扬啊)。对于此结论,Jeff询问用的是什么版本的xfs,汪博士说是2.6.38的,Jeff说至少要3.10后的内核xfs他才敢打包票说稳定。看来用文件系统还是得有一个稳定的tree和一伙苦逼的维护人员才行啊,不是拿个光盘装上就能放心用的。
汪博士还反映ceph的文件接口出问题最多,块设备和对象接口比较稳定。大家好奇ceph现在最大部署过多大的集群,intel的Zheng Yan同学回答:dreamhost部署最大的是3PB数据,但是节点数不详。汪博士在ceph上做的工作就是将小文件的数据直接放在MDS上,减少网络延时。


clsf 2013
CLSF-2013 参会人员合影

PPT: ext4 xfs ceph virtio btrfs

感谢华为和oracle对clsf的赞助,也感谢LSI提供会场和午餐,还要感谢负责会务工作的谢广军和茶水,更要感谢各位参会者的积极参与和热烈讨论,我学到了很多。
当我向彭涛同学询问EMC做为一家存储公司的未来时,他告诉我,EMC的未来不是VNX,不是Symmetrix,更不是Iomega,而是Pivatolisilon时,我被震动了,我发现干了七年的码农真是白干了,光会码code,不会抬头看看未来,唉,我要好好向彭涛学习,好好的看看这个世界,好好的思考一下将来。

CLSF 2013讨论会纪要(一)

10月17日到18日两天在LSI上海办公室参加了 CLSF2013 讨论会。简要记录之,如有错误,欢迎拍砖。

第一天早上开场先是由LSI亚太区的总裁致辞欢迎大家,因为请来的几乎都是LSI的客户:华为、oracle、阿里、百度、腾讯等(其实还有竞争对手,比如fusionio:)。当然,LSI做为东道主不仅提供了场地还提供了中午饭,还真要谢谢人家。

先由Jeff Liu介绍去年xfs的进展。xfs去年最大的改动是加入了自描述的元数据,其实就是元数据的CRC校验,如果读取时发现校验对不上,就直接返回IO error。因为这个校验的增加,还将superblock升级到了v5,从测试来看加此校验只增加了不到5%的CPU消耗。
涛哥发问:“你是在机械硬盘上测的吧?机械硬盘太慢,所以校验计算增加的overhead比例就不明显,你应该用SSD进行测试。”
Jeff回答:“我们oracle没钱,我就一个笔记本,只能自己买了一个ORZ,不,是OCZ的便宜SSD做测试,overhead也就是这个水平。“
xfs_io现在开始支持SEEK_DATA/SEEK_HOLE,可以直接找到文件空洞所在的偏移。通过在mount的时候计算transaction log的保留空间(而不是像过去在运行时计算),减少了运行时的压力。在xfs做日志恢复时加入了readahead,减少了读延迟,加快了日志恢复的速度。
还有一些特性尚未merge code,但是正在开发中的,比如:在线文件系统缩容(涛哥一个劲的追问:谁会有这么奇怪的需求?);为空闲inode单独建一个btree,以加快小文件创建(也就是分配inode的速度);对inode cache的压缩(这里要解释一下,xfs是一款有20年历史的老文件系统,当初从SGI弄到linux里来的时候linux的vfs还不完善,所以里面有很多代码是做了今天vfs的很多工作的,所以inode也比较肥大:超过1700字节,有了压缩以后,可以减小到308字节),不仅省内存,也减少了磁盘IO。
接下来的讨论是关于online fsck的,
涛哥:我们线上有需求,如果机器异常重启,做fsck太慢来不及,所以希望先启动机器,然后慢慢的做online fsck,但是ext4是没有online fsck功能的,xfs有吗?
Jeff:xfs的目标,是不需要fsck,元数据自我描述自我恢复,现在AG(xfs的块分配单位,allocation group)就是自我管理的
Coly:我们当初挑选过的,xfs的代码量要几倍于ext4的,以我们这么小的团队和互联网对文件系统那么小的需求,ext4更加合适
Jeff:这个,xfs代码量大的问题,我得说两句,首先,xfs代码风格比较古老,函数调用里每个参数都是单起一行的,而且,注释量达到30~40%,比ext4的10~20%高得多,所以代码量自然也大得多。
涛哥:如果xfs有类似online fsck的功能,就是文件系统一边被使用一边做修复检查,那我们会考虑部分使用xfs的
Jeff:现在没有这个功能,也没有开发计划
涛哥:那xfs还有什么优势?
Jeff:xfs的需求是来源于付费的大客户的,要求大文件的支持、良好的稳定性、良好的扩展性、高并发IO下的良好性能
文卿:ext4在打了directio nolock的补丁以后,并发读写已经赶上xfs了....
总之,Jeff被涛哥一顿烂虐。后来吃晚饭的时候,涛哥反复申明:”我不是要难为Jeff,是我确实遇到一些需求ext4目前不好解决,如果xfs能满足我们就考虑部分使用xfs“,我:”你这样问法是不对的,你拿着火枪跑到武术馆说‘你们的武术能快过火枪吗?能快过我就学你们的武术’,这不是踢馆是什么?”

Intel的Yuanhan Liu(不是我故意输入英文名,是coly给的日程表里都是英文名,没办法)介绍和吴峰光一起做的0-day kernel test自动化框架,能自动检测kernel tree的性能变化(不管是好的变化还是坏的变化),然后自动bisect找到引起变化的patch,给相关人员发信。其实我们这边(阿里)非常需要这样的自动测试系统,因为内核组一个专职QA都没有。于是我们怂恿intel的同学把这个自动化测试的东东做成一个测试云服务,我们好接入,“做为回报,我们会持续的大量的继续购买intel的CPU“(Coly原话)。


clsf-2013

吃中午饭的时候我向Jeb Tang讨教了线上遇到的磁盘IO hang住的问题,Jeb表示,这个问题极难查找原因,因为磁盘的firmware、raid/sas卡的firmware、内核驱动都有嫌疑,而且他感觉,6Gb SATA口很多人反映稳定性不如3Gb的,更不如SAS口,所以google在服务器定制的时候,干脆在每个sata口上加了个reset芯片,一旦发生io hang住的情况,自己调那个芯片硬件reset那个sata口(相当于插拔硬盘,只不过不需要人肉了),就返回io error了。我于是专门问了这个reset芯片的价格:一个0.6美元。
边吃饭还边请教了百度的谢广军同学对于已经mount了的磁盘,插拔后怎么做到盘符绑定,原来用udev可以。回头我试试。

下午是我厂的文卿同学介绍ext4的进展。extent status tree终于进入upstream,以前aio会等在ext4元数据分配这个地方,现在有了extent status tree,等待少了很多。以前ext4的"打洞“只支持extent的文件,现在也支持间接块式的文件,甚至还支持bigalloc下的打洞。另外,bigalloc和delay allocation合用会有warning的那个问题也解决了,当然,Ted否决了我的patch以后,用了一个也不咋高级的方案。算了,不提这些了。谢广军同学对bigalloc表示了兴趣,当然,目前还在观望,主要看其他屌丝(比如我们)有没有把bigalloc的坑踩完。文卿同学说到了online fsck的那个需求,
文卿:目前能支持online fsck的文件系统就是三个,linux上的btrfs,freebsd上的zfs和ffs,btrfs太不稳定,zfs和ffs并发IO的性能不如ext4,用户不接受。所以目前我们还在想办法。另外,我们现在也在做ext4的quota功能,但是subtree的dir quota不准确,也需要改进。rhel7以后就默认xfs了,在这之前,ext4还是得发挥余热....
广军:不是吧,我们百度才不到20%的用的是ext4,还要推广呢,你这就”发挥余热“了?!
我:看来终于有一个新东西我们比百度的同学推得快了

来自oracle的Bob Liu同学介绍了zswap。zswap其实就是把要swap到硬盘的page先压缩再存磁盘,这样可以减少IO延迟,但是会多耗一点CPU。这个功能最早是在IBM的power架构上做的,用的是power带的协处理器来做LZO压缩,所以比较合适。

来自苏州柯达的majianpeng同学介绍了他所在公司的监控系统对文件系统和存储的需求。他们一开始用的是IPSAN做后端存储,但是发现成本太高,于是改用自己开发的用户态的文件系统来合并小文件为大文件(类似淘宝的TFS),现在已经成本很低了,也满足了需求。我很好奇的问jianpeng同学何以在软raid社区发了那么多patch,他说那不是他的工作是他的兴趣爱好属“不务正业”,我很感慨,我应该向他好好学习。


clsf-2013