Ext4 Workshop 2013 总结

作者:刘峥

2013年04月17日,Ext4 社区的开发者举行了一个讨论会。主要讨论目前 Ext4 文件系统中出现的问题及解决方法,以及后续的开发计划。本文章汇总了本次会议的内容。

在这次会议中,主要讨论了如下内容(每个话题中讨论的内容包括但不限于话题本身):

  1. write stall 问题
  2. 3.10 merge window 的相关情况
  3. 关于 Ext4 stable/long-term tree 的维护
  4. extent tree layout 修改
  5. bigalloc 特性的改进
  6. Online Fsck 特性的开发
  7. data=guarded 和文件系统延迟问题的优化
  8. 不同挂载参数的选择
  9. Ext4 针对不同设备的优化

与会人员:

  • Ted Ts'o (Ext4/JBD2 Maintainer, Google)
  • Jan Kara (EXT2/3/JBD Maintainer, SUSE)
  • Eric Sandeen (Red Hat)
  • Mingming Cao (Oracle)
  • Tao Ma (Tao Bao)
  • Lukas Cerner (Red Hat)
  • Zheng Liu (Tao Bao)
  • Darrick Wong (Oracle)
  • Mel Gorman (SUSE)
  • Daniel Phillips

1. write stall 问题

这一问题最初是由 MM 内核开发者 Mel Gorman 报告的,他在测试内存管理的补丁时,发现 Ext4 文件系统的交互响应比较差,延迟很高。通过观察发现是由于 do_get_write_access() 函数中会阻塞在 lock_buffer() 上,造成延迟较大。

Ted Ts'o 提出了两种解决方案:

1) 在调用 do_get_write_access() 时避免 lock_buffer;

2) 整体修改 JBD2,自己管理 buffer_head,从而降低延迟。

由于第二种方案太过复杂,短期内很难完成,所以目前打算先优化 do_get_write_access() 函数来降低延迟。同时,在刷新 metadata 时,通过加入 REQ_* 标记来避免优先级反转问题,提高响应速度。

 

2. 3.10 merge window 的相关情况

最近马上要开始新一轮的 merge window 了,所以 Ted 说明了一下目前的进展,他目前还在进行各种测试。Jan Kara 说他通过 xfstests 测试发现 data=journal 模式下第68项测试失败。Ted 则抱怨了一下 xfstests 没有支持 local group,造成每次测试都要手工指定测试项目。

Lukas 讨论了他关于优化 invalidatepage() 的补丁,Jan 表示会 review 代码。Ted 则说这个 merge window 可以考虑把 vfs 层的补丁先合并进来,下个 merge window 再解决 Ext4 专门的补丁。

Jan 则讨论了他关于优化 Ext4 writepage 路径的补丁,Ted 的建议是留到下一个 merge window 再合并。

 

3. 关于 Ext4 stable/long-term tree 的维护

Ted 对于 stable/long-term tree 的维护工作的态度是,目前他没有时间和精力来单独维护一个这样的 tree。目前,对于 Ext4 文件系统来说,如果需要使用较为稳定的版本,可以的选择是 linux stable tree。因为目前所有有意义的补丁会被抄送给 stable@vger.kernel.org,由 stable tree 对应的维护者来进行维护。当然,如果一些补丁不能够简单的直接打到 stable tree 上,则该补丁将不会包含在相应的 stable tree 中。

 

4. extent tree layout 修改

目前 Ext4 中 extent 存储的物理磁盘块的长度是 48 位,所以,可以将其扩展为 64 位以支持更大的磁盘分区。Ted 表示如果可以扩展到 64 位当然是最好的,但是这是一个长期的工作,目前还没有明确的需求需要搞这么大的文件系统。

目前 Ted 认为对于 Ext4 文件系统更为重要的事情是如下几个:

  • 解决 unwritten extent conversion 的问题,从而彻底实现 dioread_nolock;
  • 对 extent tree/map_blocks 函数进行重构;
  • mballoc 代码的重构和改进,包括 buddy bitmap 被很快回收的问题;

 

5. bigalloc 特性的改进

目前淘宝在使用 bigalloc 的过程中发现该特性还有一些不足,比如在使用 cluster (默认64k) 作为磁盘分配的单位时,对于小文件的存储,空间开销偏大。所以淘宝的想法是希望能够某几个 block group 按照 block size 来分配文件,剩下的 block group 按照 cluster size 来分配。这样可以尽量减少小文件对磁盘空间的占用。Ted 给出的建议是可以考虑指定一个参数,在格式化的时候,指定前面多少个 block group 通过 block size 来分配。这样做相对比较简单;另外一种更为简单的方法是将磁盘分成两个分区,分别按 block size 和 cluster size 来进行格式化,从而解决这一问题。

 

6. Online Fsck 特性的开发

这一需求也是淘宝目前遇到的实际问题。由于数据库等系统需要尽可能的在线提供服务,所以我们希望能够尽可能的缩短宕机后的启动时间。所以,如果可以实现 online fsck 的功能,则可以尽可能的缩短系统启动的时间,同时保证文件系统不被破坏。目前已知的可以进行 online fsck 的文件系统是 zfs, ffs, btrfs。Ted 给出的建议是可以考虑在分配磁盘块的时候在相应的 block group 上添加相应的标记,表明这个 block group 正在进行磁盘块的分配,在出现宕机后,这个 block group 的数据只进行读操作,所有写操作都会被映射到其他的 block group 中。这样可以尽可能的保证文件系统的一致性。

 

7. data=guarded 和文件系统延迟问题的优化

data=guarded 模式最早是 Chris Mason 针对 ext3 fsync 延迟过大提出的一种日志模式。但是后来由于 ext4 中引入延迟分配 (delalloc) 特性而没有再继续开发,也没有被合并进 upstream kernel。这次提出这个话题,主要是由于淘宝在部署 ext4 的过程中遇到了很多延迟问题。在讨论延迟问题的过程中,Ted 提出了一个长远的改进计划,即通过使用 extent status tree 在内存中进行磁盘块的分配,在 end_io 中再创建日志并修改元数据提交。这样可以极大地缩短日志的持有时间,从而尽可能的避免由于日志提交造成文件系统操作的延迟。同时 Ted 还建议减少延迟的方法是尽可能提前将文件预分配出来,同时尽量将文件的元信息保存在内存中。

 

8. 不同挂载参数的选择

这个话题主要是 Red Hat 和 SUSE 的开发者提出的,目的是减少 Ext4 测试环节的压力,同时由于 Linux 发行版陆续使用 Ext4 内核模块来处理 Ext2/3 文件系统,需要在内核中添加检查代码来确保 Ext2/3 文件系统在使用 Ext4 内核模块时的正确性。

其中比较重要的几个挂载参数是是:

  • indirect-based/extent-based 文件的支持;
  • async_journal_commit参数(该参数将被标记为危险,可能造成数据丢失);
  • data=journal 与 delalloc 的互斥问题

 

9. Ext4 针对不同设备的优化

这一话题主要是围绕目前文件系统开发的优化方向来进行讨论。由于 ARM 处理器在服务器领域的使用,文件系统即需要考虑高端硬件设备的优化,同时还要兼顾这类低端设备的优化。针对高端设备,文件系统可以多使用些资源(如内存资源)来获取更好的性能;同时针对 ARM 这类内存较小的设备,可以减小资源的使用,同时提供尽可能好的性能。

Ted 表示目前 Google 针对 e2fsck/mke2fs 工具是有一些优化的,并且已经放到了 upstream 的 e2fsprogs 中,但是并没有在内核代码中针对不同设备进行优化的想法。同时 Ted 表示目前可能更需要考虑针对 eMMC 设备的优化问题。

 

根据本次 Ext4 workshop,后续 Ext4 文件系统的开发主要包括:

  • extent tree 代码重构
  • map_blocks 函数代码重构
  • do_get_write_access() 优化,解决 write stall 问题(目前 Ted 已经将补丁发出并合并进ext4 dev 分支)
  • 使用 extent status tree 来优化磁盘块分配,减小延迟
  • 修改 extent tree layout 支持更大的磁盘
  • mballoc 代码的重构和优化

关于此前使用 extent status tree 实现 range locking 的问题。由于 Jan Kara 已经开始在 VFS 层实现一套通用的 range locking,因此目前与 Ted, Jan 讨论的结果是暂时先不在 Ext4 中单独实现一个 range locking 了。

未来一段时间,Ext4 的开发将主要集中在已有问题的解决,性能的调优和代码的重构上。暂时不会有新的供用户使用的新特性。

ext4 bigalloc + inline data 测试

[原写于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分钟就检查结束了。