A File is Not a File: Understanding the I/O Behavior of Apple Desktop Applications

原文

 

摘要

文章分析了iBench 的I/O 行为,揭示了iBench 和一般文件系统在组织文件、顺序读写、异步与原子性操作等方面的差别。文章为下一代的本地文件系统和基于云的存储系统给出了意见。(这里ramification 不懂什么意思)

引言

分析包括两个Apple 软件套件:iWork(Pages,Numbers 和keynote)和iLife(iPhoto,iTune和iMovie)。为了分析iBench 套件的I/O 行为,建立了一个称为DTrace 的框架并开发了一个基于Apple-script 的应用。得出以下结论:

  1. A file is not a file.用户看来的一个文件实际上也是由多个小文件组成的。
  2. Sequential access is not sequential.顺序访问也不是真正的顺序访问
  3. Auxiliary files dominate.辅助文件占据主导地位
  4. Writes are often forced.写操作是被强迫了,许多程序定期的会使用fsync 刷到磁盘里
  5. Renaming is popular.重命名是十分常见的(一致性)
  6. Multiple threads perform I/O.有些应用会起上百个线程来进行I/O ,所以存储/文件系统应该是可感知线程的,这样才能够合理的分配带宽。
  7. Frameworks influence I/O.开发框架影响I/O ,里面举例了在引用cocoa.h 头文件时会从689个文件中包含112047行代码。

文章的主要贡献:

  1. tracing framework
  2. 解构iBench I/O 行为
  3. 描述了哪些性质上的变化影响了I/O
  4. present the 34 traces from the iBench task suite

Case Study

通过创建一个文档,接着插入15 幅JPEG 图(每个2.5MB)并保存文档为一个Microsoft .doc 文档格式。观察这个过程中十个线程对六类文档进行的I/O 解释了引言中的七个结论。

IBENCH TASK SUITE

这个section 用前面提到的iWork 和iLife 作为workload 进行了iBench 的测试。系统调用的traces 是通过DTrace 收集(The system call traces were gathered using DTrace)。

ANALYSIS OF IBENCH TASKS

一开始就提出了四个问题:

  1. 访问了哪些文件,以及这些文件的大小?
  2. 读和写文件时如何访问的?是顺序的?还是预留空间(预取)的?
  3. 什么是事务性(transactional)属性?写是通过fsck 命令写入还是自动执行的?
  4. 多线程的应用是如何把I/O 分担到各个线程中的?

文章比对了iPhoto, iTunes, iMovie, Pages, Numbers, Keynote 在iBench 测试操作(start,Dup 等)时获取文件类型的个数和比率,以及指定类型文件的个数和比率,这里需要提出的是文章把访问的文件类型分为了multimedia,productivity(像doc,xls等),plist,sqlite,strings,other 六个类型。接着将文件大小分别对文件个数和操作文件总大小取加权。对应的得出四个表:

  1. 访问某类型(六个中一个)文件个数占所有访问类型文件个数的比率
  2. 访问某类型文件总大小占所有访问文件大小的比率
  3. 访问某大小文件(<4KB, <64KB, <1MB, <10MB, >10MB)个数占所有文件个数的比率
  4. 访问某大小文件的总大小占所有文件大小的比率

从1,2 两个图可以看出iPhoto,iTunes 和iMovie 访问multimedia 类型文件的个数和大小都比较大,从文件大小的个数来看,访问<4KB 文件个数占访问所有文件个数的比率都比较高,特别是Pages,Numbers 和Keynote 应用超过60% 访问文件的格式是<4KB 文件。很有意思的是,虽然访问4KB 文件数目很多,但由于这些文件很小所以占所有文件大小的比率很小,我想如果对访问这些文件的耗时进行下分析,可能会对系统性能提高有更好说服力。

下面一部分是关于sequentiality 的分析,我又回头看了下对这些workload 的操作:start 打开对应的应用程序,open 是打开媒体或文档等文件,imp 是将media 等导入到媒体库library 中,new 是创建新的文件并保存。

首先看这些操作读的连续性,所有workload 中start 操作读的连续性超过了75%,可见这些程序在开启的时候大部分I/O 是连续的(这点其实可以拆分来看,虽然连续读操作在容量上占了大部分,但是时间上可能还是随机写所占的时间更长,可以考虑在这方面做工作)。iPhoto 和iTunes 中Imp 操作类似于一个copy 操作,所以连续性较好;有点不理解iTunes 中PlayS (播放10 首歌曲)全部是近似读操作,而PlayM (播放三分钟电影)几乎就没有连续的操作(WHY)。

接着说了预取在除了copy 之外的操作上基本没有什么用!大部分操作也没有过多的采用预取。

Writes typically involve a trade-off between performance and durability.

写操作往往是在性能和持久性之前做了一个权衡。这部分是对sync 命令的分析:

The graph further subdivides the source of the fsync activity into six categories. SQLite indicates that the SQLite database engine is responsible for calling fsync; Archiving indicates an archiving library frequently used when accessing ZIP formats; Pref Sync is the Preferences Synchronize function call from the Cocoa library; writeToFile is the Cocoa call writeToFile with the atomically flag set; and finally, Flush-Fork is the Carbon FSFlushFork routine.

fsync 被具体分类六类:SQLite 是SQLite 数据库调用fsync,archiving 为在访问ZIP 格式文档的时候产生,Pref Sync 是cocoa 库中一个函数调用的fsync ,writeToFile同上,Flush-Fork 是Carbon 库调用的。图看的眼花了~~

中间插一段atomic write(原子性写),即写操作要么失败,回滚到写之前状态,要么成功               – Step W1: Acquire “write lock” on the existing file. (this is usually part of your app semantics, so you might not need any Win32 APIs here)
– Step W2: Copy the old file in a new temporary file. (copy Foo.txt Foo.Tmp.txt)
– Step W3: Apply the writes to the new file (Foo.Tmp.txt).
– Step W4: Flush all the writes (for example those being remaining in the cache manager).
– Step W5: Rename the old file in an Alternate form (ren Foo.txt Foo.Alt.txt)
– Step W6: Rename the new file into the old file (ren Foo.Tmp.txt Foo.txt)
– Step W7: Delete the old Alternate file (del Foo.Alt.txt)
– Step W8: Release “write lock” on the existing file.

这是对应的流程图:

write

这样实际上,为了保证写的原子性,会有大量的重命名操作,可见为保证写的原子性系统I/O付出了较大代价。

再就是多线程和异步,家用电脑为了提高交互性能及减少对用户的延迟,常常采用异步写策略。实验得出的结论却是异步读写在所实验的内容中很少采用,但一旦采用了操作中异步I/O比率占用较高。另外iBench 中任务为了会使用很多线程进行I/O 减少对用户的延时(有些可能是上百个线程)。

相关工作

关键字:研究的对象,学术和工程环境,个人应用程序行为,多媒体应用程序,动态workloads,元数据特征,静态存储,长期存储

讨论和结论

有一段话非常有意思:

The iBench tasks also illustrate that file systems are now being treated as repositories of highly-structured “databases” managed by the applications themselves. In some cases, data is stored in a literal database (e.g., iPhoto uses SQLite), but in most cases, data is organized in complex directory hierarchies or within a single file (e.g., a .doc file is basically a mini-FAT file system).

文件系统现在越来越被当作为应用程序管理的高度结构化“数据库”。在一些情况下,数据保存在字母顺序的数据库中,大部分情况下,数据通过复杂目录层次结构组织起来,或者只是一个文件(比如.doc文件实际上就是一个mini-FAT 文件系统)。

完了完了~~~这篇看的还是太慢!