CLSF2012讨论会纪要(二)

[原写于2012年10月]

第二天,来自淘宝的刘峥介绍一年来ext4文件系统的开发进展。
ext4的bigalloc,增大分配单位,减少元数据,加快硬盘检查和创建大文件的速度。meta data checksum,让文件系统的错误更早更快的暴露出来,有利于数据安全和文件系统本身的稳定,但是打开checksum会造成大约20%的性能损失,这个就看用户的选择了。inline data,将小文件或目录(小于4K)的数据放入inode之中,根据统计,ext4上大约70%的目录都在100字节以内,所以这个特性对小目录众多的应用有较好的性能提升。
NO_HIDE_STALE,当用户用fallocate分配了一个大文件的磁盘空间以后,一旦他开始随机写,由于extent会从UNWRITTEN变成全零,大的extent会被切成很多小的extent,元数据会大量增加,journal会频繁写硬盘,这样性能就大大下降了;现在有了NO_HIDE_STALE,用户可以通过ioctl指定:我在从大文件里读一段内容之前一定会先写入正确的内容,没写过的部分我不会去读的,这样,不再又extent的分裂,也没有了频繁的写journal,性能就得到了保证。这是刘峥在跟踪TFS在使用ext4后性能退化的问题时发现的改进方法。这一方法对像Oracle或IBM的DB2这样的数据库系统也是有用的。
status extent tree,将硬盘上extent tree的信息保留在内存里,这样查找和空间判断都变得简洁了。这一工作还在进行,相关patch还没有merge到ext4里。
做direct io的覆盖写时不拿i_mutex,能减少大文件多线程写时的锁竞争,对于使用SSD的数据库系统来说效果非常明显。
ext4开始支持带meta_bg的在线resize。

来自fusionio的李少华介绍了这一年来在快速存储设备上遇到的性能瓶颈及相应的对linux block层的改进。
虽然fusionio的卡很贵,但是仍有不差钱的公司采用多块fusionio卡做raid的方案(应该是金融行业),之前kernel软raid的很多代码和配置在高速PCIE设备上遇到了问题,比如机械硬盘做raid时默认stripe是512K,但是在fusionio的raid上这一size过大,不能发挥SSD随机读写的高IOPS特性,所以应该选小的stripe,当然,也不能太小,太小会造成request被分割到不同的设备上。少华在测试中发现的理想stripe大小是8K或16K。
少华提醒:SSD读是不影响寿命的,但是写会,所以要尽可能的减少对SSD的写(这大概是为什么很多人用SSD盘来做系统盘,存放可执行文件、公共库等只需读的文件);在SSD快满时,写操作的throughput会下降(主要是因为SSD自己在做gc),而适时的做trim操作(告诉SSD的firmware某块区域不再需要被使用)可以避免这个问题。
coly问:trim以后的那片区域是能保证read全零吗?
少华:没有这个保证
少华还提到,由于RAID是将多个设备聚合成一个,这个新设备只有一个flusher进程来写脏页,性能不够。吴峰光说将来有计划实现一个device多个flusher。
大家还讨论到了fusionio(也包括其它一些SSD厂商)的PCIE-flash卡支持atomic write,由firmware加硬件来保证一个写请求要么成功,要么没发生。这是个杀手级的功能,文件系统为了实现写事务,都是用的journal,不仅代码多而复杂,且对性能也有损失。如果firmware支持原子写,那文件系统完全可以把journal拿掉,专心至致的优化磁盘布局了。
其实固态存储对文件系统的冲击还不止这些,比如,SSD里其实有map来记录逻辑存储地址到实际硬件地址的信息(就是FTL,flash translate layer),而文件系统也有记录文件偏移到逻辑存储地址的信息,显然有点重复了,所以fusionio提出了directfs,一个文件一旦创建就给1T的大小,但是这个1T没有任何对应的物理地址,直到用户开始在文件里写了,才利用SSD里的那个map直接把文件偏移映射到物理存储地址,简洁高效,还带点前卫。这是不是文件系统发展的一个方向?

来自IBM的Zhiyong Wu介绍了最近他们在做的在vfs层统计热数据的工作。他们会在vfs层采集数据被读取的频率,以此算出数据的“温度”是热还是冷,并提供给文件系统层去做数据迁移。统计粒度是1MB。Coly认为统计这个对互联网企业来说最大的用处,不是数据迁移,而是找出应用的bug(运转不好的应用会多次读取热数据)。大家觉得统计所有inode的信息太费内存了,最后提供接口,可以统计某几个inode的信息。
我看介绍里有统计热数据的top200,便问这个排序是在什么时候做的,Zhiyong回答说是每次发生io时都会排序。大家觉得这显然太费了,我建议不在内核里排序,直接把数据和它们的访问频率暴露出来,运维人员一个sort -k2命令就可以自己搞定排序的事情 🙂

接下来是redhat的Asias He介绍他在virtio里做的vhost-blk。有了host-blk,从guest os来的io请求会被直接map成host上的bio(以前这些guest os来的io会变成QEMU的针对host os的read和write系统调用,相当于走了两遍kernel的io路径)。大家讨论了各个公司的虚拟化方案,现在最热的云计算说白了就是虚拟机集群,xen是企业级用的最多的,一些互联网公司在尝试container的方案以获得最优的性能(如openvz、lxc),而KVM是redhat主推的(在rhel6里已经把kvm设为默认虚拟机,不再支持xen),原因是kvm毕竟是社区比较认可的虚拟化方案,而lxc等container方案安全性不够。

最后由memblaze的LuXiangFeng做业界SDD存储的报告。
memblaze是类似fusionio的国内创业公司,他们对PCIE的SSD设备做了很多软件方面的开发,提供了多种接口,既可以像磁盘一样线性访问,也可以像key/value存储那样直接put/get(这个对互联网应用挺方便的),还可以做raw device操作(比如应用直接去并行操作SSD上的不同channel,或者应用自己去做gc)。对SSD做单线程的读写是无法发挥SSD的高iops特性的,应用应该加大io并行度——或者通过启动多线程读写,或者通过aio来增加iodepth。

clsf 2012
全体参会人员合影

结语:感谢 支付宝 赞助此次CLSF讨论会

CLSF 2012讨论会纪要(一)

[原写于2012年10月]

10月11日到12日两天在EMC北京办公室参加了CLSF 2012 讨论会。简要记录之,难免碎片,如有错误,欢迎拍砖。
第一天首先是南大富士通的缪勰介绍btrfs这一年的新进展。
btrfs已经具有了在线修改RAID的stripper大小、自动修复RAID1的坏盘等功能,且将meta block的size变为可调(上限64K),这样btree就矮了很多(因为node大了),在删除大文件时seek过程变少了,删除速度更快。
ext4如果发现io error会将文件系统置位read-only,而btrfs以前是没有这个能力的,今年才开始学ext4,加上了坏盘时置read-only的功能。
btrfs还增加了subvolume的quota功能,增加了send/receive对文件系统进行整体备份和恢复(这个备份是备份btrfs的那棵btree,就免得全盘备份了,但是大家觉得,好像这个功能没有太大的用户市场)
还有一些未来的优化工作:
btrfs提供强大的snapshot功能,但是如果一个文件做了太多的snapshot,那么一个node可能有很多snapshot point指向它,如果现在要对这一个node进行操作(btrfs是广泛利用COW的,所以即使是覆盖写,也要copy出来一份新的),那么还需要把多个snapshot指下来的point都改为指向新node,反向查找很费力,以后计划加入了一个中间的ref,snapshot point都指向这个ref,ref再指向node,那么如果node变了位置,只要把ref改一下就行了,不用改所有的snapshot point。
btrfs未来也会采用buddy system来管理free space(类似ext4),以减少磁盘碎片。
线下讨论我向缪勰请教了一些btrfs的问题,才知道btrfs里文件的inode、inode ref、extent等元数据是混合放在一棵fs tree里的,所以对一个文件的查找或对某文件内容的查找都是在一棵btree里,虽然btrfs会尽可能的把一个文件的相关元数据往一个node里放,但是也不保证在插入新pair时node分裂会把元数据给隔开。btrfs在性能上确实还有很多工作要做。

clsf 2012
大家在休息时间各自讨论

来自Oracle的刘博同学主要介绍了一下一年来他在文件系统性能优化方面积累的一些经验和工具。
Chris Mason的seekwatcher是跟踪io性能的好工具,但是它只能处理单硬盘的io数据,所以Chris现在打算开发更先进的iowatcher,能够处理多块硬盘,还能看到io的latency和cpu状态,提供的信息更综合。比如,btrfs在写时throughput还行,但是latency较大(写很多小文件时尤其明显),所以怎么观察和优化这些latency迫切需要强大工具的支持。
刘博同学还提到了ftrace,而我们推荐了朱辉开发的kgtp,可以实时在线调试(很方便我们这些经常需要查线上kernel bug的苦逼码农)且延时很小。但是kgtp一直没有进upstream,淘宝kernel自己backport了这部分代码。
Asias He同学问我们测文件系统用哪些工具,其实我们组根本连一个QE都没有(不能跟redhat、SUSE、Oracle这些做发行版的公司比),文件系统都是靠开发人员自己测(自己吃自己的狗粮,也挺好),我们把iozone、fsmark、xfstest、postmark等一堆开源测试工具用脚本攒在一起(“要你命三千”),对着文件系统一顿高压力的狂轰乱炸几天几夜,如果没有panic、也没有“block 120 seconds“,就算是过了。当然,功能测试还需要开发自己另外写程序来模拟。

接下来是Oracle的Jeff Liu介绍一年来xfs的开发进展。
在各大公司的运维人员和DBA中,都流传着“xfs文件系统对大文件的性能最好”的传说。但毕竟只是传说,coly给出了一个故事,还是比较有说服力的:ext4文件系统刚开发出来的时候(好像是2006年前后),很多评测结果都好于xfs(包括大文件),那时xfs是输在了journal的性能上;两三年后,xfs改进了journal的性能,评测结果超过了ext4;然后,ext4开始学习xfs的部分优化方法,性能又超过了xfs....所以,实际在upstream里,这两个文件系统的性能是在互相追赶,并没有一个权威的标准说明谁比谁更好或者更不好。
ext4和xfs对文件都是使用btree,从设计的角度来谁也没有压倒性的优势,所以关键还看细节处的优化。所以我不完全赞同“架构决定性能”,架构是决定了性能的“天花板”,但是最后能不能到达这个天花板,还看具体开发人员的努力。我觉得架构师们都是非常聪明的人,而好的架构往往是高度相似的,所以靠架构领先来取得压倒性优势并不常见(大家看看现在各大互联网公司的所谓“分布式存储”,是不是架构都长得很相似?架构都相似了,性能也不会差特别大),常见的还是靠在细节处修bug、找性能瓶颈的默默无闻的码农来一点一点的优化,最终靠高稳定、高性能、高便捷来赢得用户。所以,传说中的“xfs性能好于ext4”值得商榷。
xfs最初是从SGI UNIX里移植到linux上来的,当时linux的vfs层做的不好,所以移植过来的xfs代码也包括了一些本来该vfs做的事情,所以linux里的xfs代码非常庞大(10万行),维护是个很大的负担。所以xfs最近的工作都集中在精简代码上,很多patch都是在做删代码的工作。一个很典型的例子:xfs的writeback函数调用路径特别深,linux kernel提供的4K大小的stack根本不够用,于是想出了一个神办法,就是在函数调用路径的中间停下来,把剩下的调用工作放入work queue,让剩下的操作稍后由延时任务自己来完成。这样stack才不会被撑爆。
来自fusionio的李少华:我在测试中发现work queue的扩展性很差,你如果太频繁的往里面放东西,性能是会急剧退化的,而且把work放入queue的CPU和以后将执行此work的CPU很可能不是同一个,这将影响CPU的cache。
Jeff Liu:这些锁竞争和CPU级的速度损失,跟IO的性能相比,不算什么的,一次写盘或读盘,几个毫秒都过去了,省那几百个微秒并不紧要

然后是腾讯的冯小天介绍腾讯内核组的工作。
腾讯的新内核是基于mainline的2.6.32内核,虚拟机用xen,而目前的云平台是用的container。基于mainline带来了很多bug,一路踩了不少雷,要是一开始基于rhel6的2.6.32内核就好了(看来我们是幸运的)。小天在推广新内核上也遇到很多困难:业务方不肯升级OS,甚至重启机器都不愿意,尤其是208天的那个bug搞得腾讯内核组非常郁闷。未来,准备利用腾讯上SSD盘的机会把ext4也推上线。
Coly提到了淘宝CDN使用的SSD盘坏得很少,其实比机械盘耐用。

clsf 2012
中间穿蓝色衣服的是来自腾讯的冯小天

淘宝的余峰介绍了淘宝在使用mysql中对linux文件系统和存储层提出了新的要求。
目前mysql使用的innodb引擎会造成短时的大量IO,性能会有抖动,考虑换成levelDB的LSM引擎。现在SSD的出现让pc server的IO能力变得过剩,通过在一台服务器上启动多个mysql实例来更加充分的利用IO资源。目前SSD卡似乎没有接口看“使用寿命还剩多少”,等出了问题再换盘就麻烦了,来自memblaze的唐志波回答说,一般SSD写10 P的数据(或者使用3年)就会有较多错误出现,而厂家一般是到3年就要给更换的。

最后是EMC的Xuezhao Liu介绍lustre client。最近他们和whamcloud合作,计划把lustre的client推到kernel code里,Peng Tao今年4月份参加LSF的时候提出了这件事,社区表示欢迎,当然,前提是清理代码让其符合kernel code style。推进的工作除了清理代码、整理格式,还要将client部分从lustre代码中剥离出来。
问:lunstre client代码有多少?
答:里面光是通信方面就有三万行代码,总共十万行。
大家惊了。一次往kernel里进十万行代码,这还是相当不容易的。