[原写于2012年2月]

先前我以为对文件系统来说,读写文件时跑得快才是关键,mkfs和fsck的速度不用操心。直到几天前,线上的运维同学反映:集群里某台(或者悲剧一点,某几台)机器如果宕机了,如果不能迅速重启,可能会对其它服务器带来额外的压力,因为外部流量还在,而“重启”过程包括了对突然断电的磁盘做fsck,所以,fsck的速度也很重要。

于是我找了个台式机(没办法,我们组的开发机服务器没有上T的硬盘),上面配了coly自己买的 2T 硬盘,测了一下ext4如果带上 nojournal + bigalloc + inline_data 后fsck的速度。

硬盘: 希捷Barracuda LP 2TB 5900转 32MB(ST32000542AS)
CPU: Core 2 Duo E8400 3.00GHz 1333MHz FSB (2 cores)
内存: 2GB 800MHz DDR2
mkfs命令:mke2fs -m 0 -C $CLUSTER_SIZE -I 4096 -O ^has_journal,^resize_inode,^uninit_bg,extent,meta_bg,flex_bg,bigalloc,inline_data $DEVICE

用工具 dir_tree 程序创建树状目录结构和文件:

./dir_tree -m /test/ -d 7 -l 4 -n 5 -f 5 -S 64m -s 24576 -t cd
./dir_tree -m /test/ -d 7 -l 4 -n 5 -f 5 -S 64m -s 24576 -t cf

7个总目录,4层目录结构,每个目录下有5个子目录,每个文件64MB(这是某种程度上模仿hadoop的线上环境),总共5470个目录,21875个文件,大约占掉1.4T空间

用不同的cluster size来分别格盘并创建文件,看fsck -f运行的时间。测试结果如下:

cluster size (KB) NR of inode (inode table) time (seconds)
4 122093568 5484
64 30517408 1366
128 15258704 682
256 7629352 339
512 3815136 168
1024 1907352 84

中间这一列“NR of inode“就是mkfs完成后默认的总inode数,反映了inode table的大小。

从测试结果看,随着cluster size越来越大,fsck的速度越来越快。原因是大cluster占用的元数据更少——更少的block group,更少的inode table。
普通的ext4(就是不带bigalloc+inline_data)要90多分钟,而如果用1MB大小的cluster(bigalloc),则不到2分钟就检查结束了。