本工作来自上海交通大学/华为陈海波老师团队,发表于ATC 2019。
01 动机及背景
EROFS是一个针对移动设备的只读压缩文件系统。作者观察到,当前手机配备的存储空间不大,而安卓系统的系统分区、各种app占用的空间越来越大。导致用户的实际可支配空间越来越小。如图所示,安卓系统的/system分区从2.3.6的184MB增长到了9.0.0的1.9GB。为了尽可能增加用户的可用空间,对系统分区使用压缩文件系统是最优解。
文章对比了两个最常见的压缩文件系统,Btrfs和Squashfs。其中,Btrfs是一个B树文件系统,在使能压缩功能后,文件数据每128KB进行压缩存储,由于Btrfs是一个通用文件系统,同时支持读写功能,因此为数据修改效率妥协了数据压缩率,且在数据解压时会占用大量的内存空间。
Squashfs是一个只读压缩文件系统,压缩块大小4KB-1MB可调,由于安卓的/system分区几乎不需要修改的特性,只读文件系统比Btrfs更合适。然而,Squashfs同样存在严重的问题,在解压过程中squashfs会产生大量的CPU和内存开销,在资源紧张的移动设备上性能下降严重。
为了研究squashfs性能下降的原因,文章进行了进一步分析。第一个原因是压缩输入块大小固定,导致了的压缩输出数据大小不同,因此导致了可观的读放大,如下图所示,以128K压缩输入大小为例,压缩后数据存放在SSD的blk1-blk7中,若要读取4KB数据,则需要首先读取blk1-blk7共7块,解压得到128K原始数据后,只取其中4KB所需数据,这就导致了7倍的读放大。
第二个原因是在解压过程中大量的内存占用和数据搬运开销,在解压过程中,squashfs需要大量的临时内存用于解压,另外,解压过程中,数据需要多次搬运,造成大量的CPU开销。
这两个缺陷引出了两个关键思考:如何在减小读放大的同时尽可能少的降低压缩率?如何在解压过程中尽可能少占用内存?
02 EROFS的设计与实现
固定压缩输出块大小
为了产生固定大小的压缩输出块,EROFS在生成镜像时使用滑动窗口法调整压缩算法输入的原始数据大小。固定输出块大小具有多种优点。首先,固定输出块大小压缩率更高;第二,读取数据时仅需要读取包含目标数据的块,也就是说一块数据最多仅需要两次读操作,相较squashfs,读放大显著缩小。
灵活的原始数据存储
在实际解压前,EROFS可以使用两种方式存放原始压缩数据。当数据仅部分解压时,EROFS使用缓存式IO,即在发送读请求前为申请一块特殊inode的页缓存,并将原始压缩数据读入这一块缓存中,当再次触发读请求并且读区域正好落入当前压缩块时,即可省去一次IO。若压缩数据需要全部解压,EROFS则使用在位IO方式,即将原始压缩数据直接读入VFS分配的存放解压后数据的页缓存中。
多种解压策略结合
EROFS设计了四种解压后数据的存放方式。
1. Vmap存放,即使用vmap方法将申请的临时缓存和VFS分配的缓存作为连续的虚拟地址作为解压的目标地址。这种方式有两个缺点:第一需要动态申请内存,增加内存压力;第二每次解压都使用vmap和vunmap效率低下。
2. Per-CPU缓冲存放,即使用提前为每个CPU分配的缓存作为解压数据的存放地址,这种解压方式仅在解压数据小于4页时使用。
3. 滚动存放,即使用EROFS预先申请的16物理页内存存放解压数据,当解压数据超出16页时,则滚动回第0页覆盖其数据继续解压。
4. 在位解压,即解压后的数据和原始压缩数据放置在同一段内存空间,这种解压方式仅在确定解压过程中不会出现解压后数据覆盖还未解压数据时才可以使用(在mkfs时会判断是否会覆盖,并记录在inode中)。
根据四种不同解压后数据存放方式的特点,设计解压策略如下图所示。
03 优化
索引优化:一个压缩块中可能存在数百页原始数据,在解压时这些页的索引会占据大量内存,因此若VFS分配的页中存在多余的可重用页,则将压缩块存储在可重用页,这样可以避免重复读取,同时减少内存占用。
调度优化:传统压缩文件系统如Btrfs使用一个独立的解压线程进行数据解压,这样会带来调度开销,EROFS将解压工作放在读者线程执行,以避免解压线程的调度开销。
协同解压:若多个线程的读取落入同一个压缩块内,则仅由一个线程解压一次,其余线程共用数据,避免重复解压。
镜像补丁:使用增量补丁方式,EROFS可以支持少量补丁存在。在文件读取时,EROFS先读取镜像内文件原本内容,再读取补丁中覆盖内容进行更新。
04 评估
评估平台使用了hikey960开发板。评估方式采用了fio和enwik9数据集,fio分别执行顺序读取、随机读取、条带读取(每128KB读取4KB)进行基准测试。
测试结果如下图所示,在压缩文件系统中,btrfs表现最差,在每次读取无法落入缓冲的条带读取测试中,squashfs-128K下降明显,而EROFS的性能与squashfs-4K类似,接近非压缩的ext4和f2fs。
压缩率、内存占用测试
使用enwik9和silesia.tar两个数据集测试几个文件系统的压缩率。测试结果如图所示。可以看出,EROFS压缩率和squashfs-16K接近,低于squashfs-128K,压缩率接近0.5,可以节省接近一半的空间。
内存压缩测试方式为:开机、挂载文件系统,读取整个测试文件,查看内存占用情况。测试结果如下图所示。可以看出,EROFS的内存占用仅略高于非压缩文件系统的ext4,远低于squashfs。
实际环境测试
将安卓系统的/system;/vendor;/odm分区使用erofs,分别节省了30%-35%的空间,开机时间缩短2.3%。测试打开相机应用花费时间,92次测试累计分布如图所示。可以看出,EROFS的应用开启时间和ext4基本相同,甚至略优于ext4。
总结
EROFS作为一个为资源有限的移动设备设计的只读压缩文件系统,在保证较高压缩率的同时提供了高性能读取、低内存占用。在测试中,开启时间甚至略快于ext4。目前EROFS已并入linux主线内核,并且大规模部署在智能手机上。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !