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

我与“又拍”这六年

2007年夏天,我还在北京漂泊,爸从老家过来看我,由于一直没有回家过年,我们已经两年没见面了。父子相见,高高兴兴嘻嘻哈哈,我便带爸一起去看当时军事博物馆的新武器展览。那时我还没有数码相机,就找同事借了一个,拍下了不少照片,回来以后发现:这么多照片存哪儿呢?存自己硬盘上,远在家乡的妈看不见;存flickr上?速度太慢。于是在网上找了一圈,发现国内的yupoo(“又拍”)界面相对最清爽,使用最方便。于是都把照片放上去了。

DSC02523
这是我爸2007年在“飞豹”战斗轰炸机前面的照片(中间穿白色短袖的,别认错了)

2008年春节,爸妈都到北京来陪我过年,一家人隔了三年终于又聚在一起过年了,好不感慨,我也买了数码相机,拍了很多照片,一股脑都传到了“又拍”上面。
“又拍”也算争气,这六年来,我家里的照片、博客上的图片都是放在上面的,还从没出过问题。“又拍”的web客户端以前上传总有几个小错,现在修复了,上传很顺利。今年5月我的博客托管服务器挂了,托管商收回机器,写了六年的博客文章现在都没有找回来——现在这个是新找的托管商,所以文章都是从2012年开始——但是“又拍”上的图片依旧是在的,一张没少,这专业的存储提供方,比二手的托管机房,那是强太多了。

IMG_1973
这是2007年阿里妈妈创业的时候在湖畔花园的合影,现在包括我一共有5个人还在公司
DSC_3360
也是2007年在湖畔花园时的照片,坐着的是“三多”同学

IMG_0045
2009年我结婚,和老婆在家乡的照片

上面的照片一直都是托管在“又拍”上的。感谢“又拍”网,让我这样的抠门儿免费用了整整六年,从京漂一直用到现在成家立业。服务非常稳定。谢谢你们!

ext4磁盘碎片查看

子团兄最近在测试ext4的bigalloc特性,cluster为256K,放入了16个大文件,每个文件25GB。反馈我说碎片很多,我觉得很奇怪便问是怎么看出来碎片多的,他说是用fsck看的:

#fsck.ext4 -f -y /dev/sdi1
e4fsck 1.42 (29-Nov-2011)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdi1: 27/7631216 files (59.3% non-contiguous), 104148800/488377984 blocks

看起来"non-contiguous“占到了59.3%,似乎碎片很多的样子。
我翻了一下代码,这个值是在e2fsprogs包里计算出来的:

e2fsck/unix.c

static void show_stats(e2fsck_t ctx)
{
....
    frag_percent_total = ((10000 * (ctx->fs_fragmented +
                    ctx->fs_fragmented_dir))
                  / inodes_used);
....

其实就是用该文件系统中"fragmented“的文件数加上"fragmented”的目录数,再除以一共创建出来的inode数(也就是总文件数加总目录数)。但是哪种文件称为"fragmented“呢,看看扫描extent结构的代码:

e2fsck/pass1.c

static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
                             struct process_block_struct *pb,
                             blk64_t start_block, blk64_t end_block,
                             ext2_extent_handle_t ehandle)
{       
....
                if ((pb->previous_block != 0) &&
                    (pb->previous_block+1 != extent.e_pblk)) {
....
                        pb->fragmented = 1;
                }
....

只要这个extent与上一个extent物理块上不是连上的,这个文件就算是"fragmented“了(目录亦如此)。即使用上bigalloc特性,一个cluster配成256KB,那么一个block group就是4K * 8 * 256K = 8G大小,对于25G大小的文件来说,怎么都不可能连续,因为跨block group了,16个大文件那就算16个"fragmented“,除以inode总数27(这个inode总数包括了文件、目录、甚至journal本身也算一个inode)那就是59.3%了。
这样计算出来的"non-contiguous“只能反映非连续文件占总文件数的比例,不能说明磁盘的碎片多与不多。大文件几乎不可能extent相连一点空都不留,但因此就说碎片严重并不合理,因它是由几个不相连的大块组成的;比如一个25G的文件由4个8G的大块组成,我们不能因为它是"fragmented“的就说碎片很严重,毕竟才4个碎片。换个角度,我如果在该ext4里创建100个4KB的小文件,那non-contiguous就是16/127=12.6%,这并不能表示碎片情况变好了,因为多了这么多小文件,其实磁盘上碎片更多了。

要综合评估磁盘的碎片状况到底是好是坏并不容易,推荐的办法是用filefrag -v看看磁盘里某几个大文件的碎片情况,如果它们的碎片很少,而文件系统里的小文件也不多,那基本可以认为磁盘碎片不严重。当然,最彻底的办法是用dumpe2fs查看每个block group里block bitmap被分配的情况。

rhel6 的软RAID问题

先是彭敏同学报线上服务器出现了kernel panic,我上去一看panic的地方在
md_seq_show()--> mddev_unlock()
里的 md_wakeup_thread(mddev->thread),说是mddev->thread为NULL。用的是基于2.6.32-220的ali_kernel。查了一下,这个问题倒是在2.6.32-279已经fix了,upstream的补丁是"md: Avoid waking up a thread after it has been freed"

于是我让彭敏同学升级内核到2.6.32-279,但是更悲剧的是,279更不靠谱,创建raid10后刚开始mkfs.ext4就panic了....panic的地方更诡异,在drivers/scsi/scsi_lib.c的一个BUG_ON里:
panic

        /*
         * Filesystem requests must transfer data.
         */
        BUG_ON(!req->nr_phys_segments);

        cmd = scsi_get_cmd_from_req(sdev, req);
        if (unlikely(!cmd))
                return BLKPREP_DEFER;

        memset(cmd->cmnd, 0, BLK_MAX_CDB);
        return scsi_init_io(cmd, GFP_ATOMIC);
}

只好顺着代码一点点调试,才发现是raid10在处理io的函数make_request()里错把upstream的补丁直接backport过来,upstream里已经没有BIO_FLUSH和BIO_FUA只有REQ_FLUSH和REQ_FUA了,但是backport的人显然不知道,就直接用REQ_FLUSH来代替BIO_FLUSH,但在2.6.32内核里,这压根是两个不同的值。于是,make_request()在clone request时把request的FLUSH标志给漏掉了,到了scsi层:

static int sd_prep_fn(struct request_queue *q, struct request *rq)
{
        ....

        /*
         * Discard request come in as REQ_TYPE_FS but we turn them into
         * block PC requests to make life easier.
         */
        if (rq->cmd_flags & REQ_DISCARD) {
                ret = sd_setup_discard_cmnd(sdp, rq);
                goto out;
        } else if (rq->cmd_flags & REQ_WRITE_SAME) {
                ret = sd_setup_write_same_cmnd(sdp, rq);
                goto out;
        } else if (rq->cmd_flags & REQ_FLUSH) {
                ret = scsi_setup_flush_cmnd(sdp, rq);
                goto out;
        } else if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
                ret = scsi_setup_blk_pc_cmnd(sdp, rq);
                goto out;
        } else if (rq->cmd_type != REQ_TYPE_FS) {
                ret = BLKPREP_KILL;
                goto out;
        }
        ret = scsi_setup_fs_cmnd(sdp, rq);

对REQ_FLUSH的判断失效,进不了scsi_setup_flush_cmd而直接走了scsi_setup_fs_cmnd,结果悲剧了。看来升279不是办法,还是把"md: Avoid waking up a thread after it has been freed"的补丁打到220上吧。
感谢彭敏同学对软RAID功能的支持。

把这个279的bug告诉了涛哥
涛哥:upstream把BIO_FLUSH和REQ_FLUSH合并为一个不是Tejun Heo搞的鬼吗?他不是去红帽了吗?他搞了这摊事怎么不backport到rhel6的279上去?
我:....大概他去红帽就只做upstream不用干backport的苦活吧

ARM开发者大会2013

上周六去参加了北京的2013年ARM开发者大会。说是大会,其实也就两百来人,不算特别多,我不是搞嵌入式的,参加是纯属好奇。
ARM
先是Allen Zhong做开场白,谈谈ARM开发者的机会。大意是世界范围内中产阶级增长迅速,80亿的世界人口里60亿有手机,这其中10亿是智能手机(去年的数据),所以ARM的技术用途很广泛市场很大,大家如果来学习ARM的开发一定有大把的工作机会,举“捕鱼达人”为例,已经月收入上千万了。(我个人觉得ARM虽然出货量大,但毕竟卖硬件利润低,走丰富软件的道路基本也正确,只是个人软件在国内要赚钱真的好难,用过flashget,netant的老网虫们应该明白我在说什么吧?靠谱的还真就剩在线游戏这类个人软件了)

后面讲解ARM在浏览器处理javascript里的优化,坦白说我没太听懂,过。彭晓波介绍了ARM的开发调试工具 DS-5,能出详细的性能profile图,举个例子:手机游戏开发常用的2D图形库是cocos2dx,用DS-5分析cocos2dx,发现其memcpy占了超过50%的CPU运行时间,后来发现是纹理处理方面的问题,改进后性能大涨(当然,高端智能手机感觉不到这个改进);DS-5还发现过Android的很多性能热点,都已经提给了Google。(会后每人发了件印着"DS-5“的T恤,结果今天文卿看到我的T恤就大喊,”啊,屌丝吾!“)

Neon是ARM下的SIMD指集,类似Intel的SSE系列,为了方便使用,做了个开源的C库叫Ne10,适合矩阵运算、图形处理一类的应用,据说可以把图像缩放加快2.6倍,“美图秀秀”就是用的Ne10。(erasure code的实现依赖于矩阵运算,不知用Ne10能否有帮助)

最后压轴的当然是宋宝华老师,介绍kernel里arm tree的变化。以前各个ARM板子代码相差极大,各有一摊,比如三星的s3c2410,以前学嵌入式的都不知道啥叫ARM,就知道s3c2410,更何况还有“友善之臂“这类公司的soc驱动根本进不了upstream的公司出的板子(听到“友善之臂”我笑了,连我这种从没搞过嵌入式的人都听说过这家公司,去年玩cubieboard没少长见识)。现在好了,合并了。不同arm板子的驱动和firmware归在一起,用类似配置文件来开关,现在一个kernel image就可以在不同的soc上boot起来。合并不同arm板子的驱动代码是社区做的重构,“生命在与运动,代码在于重构。重构是上进程序员每天的进行式.是一项工程而不是靠天份挥洒的艺术”,宋老师引用侯捷的话,颇为触动码农的心。
另外还有ARM的big.little策略:8个ARM核,其中四个是高性能高功耗的A15,另四个是低频率低功耗的A7,可以8个核一起用;也可以在4个高频核和4个低频核之间切换——计算任务小或者不做计算时将task迁移到4个A7核上,一旦计算任务变大,立刻切换到4个A15上,同时只能有4个核在跑。这一切换也是由kernel的CPU scheduler来支持的。
宋宝华

宋宝华老师声音洪亮、讲解清楚
后记:
回来后在网上查了一下“友善之臂”这家公司,哟,这名字居然是从著名的单机游戏《博得之门》里来的,真是勾起我久远的回忆,遥想03年我第一次玩《博得之门》,那真是全身心的投入啊......这公司名字起得好。

1 3 4 5 6 7 14