赞
踩
“智能手机通常存储和运行时内存有限。压缩只读文件系统可以显著减少只读系统资源使用的存储空间。然而,现有的压缩只读文件系统使用固定大小的输入压缩,这会导致显著的I/O放大和不必要的计算。在解压缩期间,它们还会消耗过多的运行时内存,并在运行时内存不足时降低性能。在本文中,我们描述了EROFS,这是一种新的压缩友好型只读文件系统,它利用固定大小的输出压缩和内存高效解压缩来实现高性能,而无需额外的内存开销。我们还报告了我们在数千万智能手机上部署EROF的经验。评估结果表明,EROFS在各种微基准测试中优于现有压缩只读文件系统,并将实际应用程序的启动时间减少了22.9%,同时存储使用率几乎减半。“
EROFS文件系统,(英文名:Enhanced Read-Only File System )是一个Linux操作系统下的只读文件系统,用来在保证嵌入式设备端到端的性能下节省存储空间,尤其是Android设备。相比其他通用文件系统,它使用了减少元数据的设计,并且提供透明压缩技术给目标文件系统用户 。在效果上,采用了EROFS超级文件系统之后,手机的随机读取性能平均提升20%,最大可提升近300%;实现系统ROM空间占用节省2GB(以P30 Pro 128G为例,不同机型节省空间不一样);可避免在内存紧张时低效地反复读数据,解压缩数据带来的整机卡顿问题;天然只读设计,系统分区不可被三方改写。支持华为EMUI 9.1、Color OS 11.2、CoolOS 2.0系统。 ——引自百度百科
引导EROFS只读文件系统研发的主要动力有以下两个方面:
低用户感知存储空间:指的是由于成本紧张,智能手机通常资源稀缺,与此同时,Android操作系统占用的空间不断增加,以及数据存储中的大量零快,消耗了手机存储的大量空间。这对于低端手机,主要指大部分在欠发达地区运用的Android手机而言,大量的内存占用对手机性能会产生极大的影响。下图显示对于存储在Andriod不同版本手机中稀疏图像与原始图像占用内存大小的对比:与此同时,Android应用程序的存储消耗也在不断增长。据Google Play报道,到2017年初,与Google启动Android应用程序市场时相比,平均应用程序规模已经翻了五倍。因此,可供用户使用的低端智能手机的存储容量相当小。此外,智能手机的许多顶级应用程序往往会消耗大量内存,即使在高端智能手机上,系统启动的操作也只剩下少量内存。
现有只读文件系统的不足:压缩只读文件系统旨在最大限度地减少存储使用。然而,应用现有的压缩读取为用户提供更多空间是采用压缩文件系统,它向应用程序公开标准文件接口,但在文件写入和读取过程中透明地压缩和解压缩文件数据。Btrfs启用压缩时,文件数据被分成多个128KB的块,并单独压缩。每个压缩块将存储在一个区段中,该区段是连续块的运行,顺序存储数据。这些区段的位置记录为B树结构中的索引。为了读取文件数据,从存储器中读取相应的扩展数据块,并解压缩整个数据块。要更新文件,将新数据压缩并写入新的数据块,然后更新索引。为了读取文件数据,Btrfs从存储中读取相应的数据块,并解压缩整个数据块。要更新文件,Btrfs将压缩新数据,将其写入新数据块,并更新索引。Btrfs是一个通用文件系统,因此其内部结构必须考虑有效的数据修改,并且不能针对压缩进行积极优化。此外,压缩不是唯一的度量标准。解压缩期间的内存消耗也应受到限制。
EROFS增强的压缩文件系统:
1.EROFS的关键设计
为了克服固定大小输入压缩引起的读取放大,EROFS采用了不同的压缩方法:固定大小输出压缩。
为了生成固定大小的输出,EROFS使用滑动窗口压缩文件数据,滑动窗口的大小是固定值,可以在图像生成期间进行配置。压缩算法被多次调用,直到所有文件数据被压缩。例如,对于1MB滑动窗口,EROFS一次向压缩算法提供1MB原始数据。然后,该算法尽可能压缩原始数据,直到消耗掉所有1MB数据,或者所消耗的数据可以生成精确的4KB压缩数据。剩余的原始数据与更多数据合并,形成另一个1MB原始数据,用于下一次调用压缩。在相同压缩单元尺寸下,它具有更好的压缩比,在解压缩期间,仅读取和处理包含请求数据的压缩块,同时使固定大小的输出压缩使就地解压缩成为可能,进一步降低了EROFS中的内存消耗。
EROFS有两种策略:缓存I/O和就地I/O。EROFS对压缩块使用缓存I/O,这些压缩块将被部分解码。EROFS管理一个特殊的索引节点,其页面缓存存储由物理块编号索引的压缩块。因此,对于缓存的I/O,EROFS将在特殊索引节点的页面缓存中分配一个页面,以启动I/O请求,以便存储驱动程序将压缩数据直接提取到分配的页面。
对于将被完全解压的压缩块,EROFS使用就地I/O。每次读取文件时,VFS将在页面缓存中为文件系统分配页面,以放置文件数据。对于任何一个在解压前不包含任何重要数据的页面,我们称其为可重用页面。对于就地I/O,EROFS使用最后一个可重用页面初始化I/O请求。
因为对于包含多个压缩块中数据的读取请求,压缩块被一个接一个地解压。例如,为了读取图中的块D4至D6,首先解压缩C0以获得D4和D5的第一部分;则C1被解压缩以得到D5和D6的其余部分。
Vmap解压缩以获得块D3和D4中的数据,EROFS首先从存储器读取压缩块C0并将其存储在存储器中。然后EROFS将在以下步骤中对其进行解压缩。
1.找到存储在压缩块(C0)中的最大所需块号,该压缩块是示例中的第五块(D4)。作为一个优势,EROFS只需要解压缩前五个块(D0到D4),而不是解压缩所有原始数据块。
2.对于需要进行解码的每个数据块,找到存储空间。在图3(b)所示的示例中,EROFS分配三个临时物理页以存储D0、D1和D2。对于请求的两个块D3和D4,EROF重用页面缓存中VFS分配的两个物理页。
3.由于解压算法需要连续内存作为解压的目标,EROFS通过vmap接口将前一步骤中准备的物理页面映射到连续虚拟内存区域。
4.如果是就地I/O,在这种情况下,压缩块(C0)存储在页面缓存页面中,EROFS还需要将压缩数据(C0),复制到临时的每CPU页面,以便解压缩数据不会在解压缩期间过度写入压缩数据。
5.最后,调用解压缩算法,将压缩块中的数据提取到连续存储区域。
EROFS的实现:
在当前实现中,使用4KB作为固定输出大小,因为它是页面管理和存储数据传输的最小单位,因此可以最小化I/O放大。在EROFS中仅压缩文件数据,存储索引节点和目录条目等元数据时不进行压缩。
EROFS的两个版本:
EROFS的图像布局:
EROFS图像布局和块索引
在当前实现中,文件的元数据和数据存储在一起,以获得更好的位置。对于每个文件,如图所示,索引节点存储在开头,后面是包含扩展属性(即,XATTR)和块索引的块。压缩或未压缩文件数据块(编码块)存储在每个文件的末尾。
块索引用于快速定位读请求的对应编码块。如图显示了压缩前包含十个块的常规文件的示例块索引。块索引是一个8B长度的条目数组,每个条目对应于压缩前的数据块。每个条目指示对应的数据块是否是开始新编码块的头块(图中的布尔头字段)。如果是,还存储编码块地址(blkaddr)、新编码块中第一字节的偏移量(偏移量)、编码块是否被压缩(cmpr)以及该块是否可以被解压缩(dip)。如果不是,则在未压缩块之前必须有一个头部块,并且与头部块的块号差异记录在dist中。
对于未压缩数据块的读取请求,EROFS根据请求的块号获取块索引条目。对于头块,EROFS从blkaddr处的块解压数据,如果偏移量为非零,EROF可能还需要从blkaddr之前存储的最近编码块解压。对于非头部块,EROFS根据存储的dist计算相应头部块的位置,并开始解压缩,直到请求的块数据解压缩。压缩后较大的一些数据块(例如,图中的块5)未被压缩并直接存储为编码块。对于这些情况,相应的cmpr字段设置为假(即图中的“N”)。
目录的存储与常规文件类似,只是没有块索引,编码块用于存储未压缩的目录条目。为了更好地定位目录中的随机访问,EROFS将所有目录头(例如索引节点号、文件类型和名称长度)放在目录条目的起始部分,并将文件名放在这些标题之后。
对于前文提及的两种版本的不同解压策略:
两种版本的EROFS具有不同的解压缩策略。如果要提取的原始数据块少于四个,则商业部署的EROFS使用每CPU缓冲区解压缩;否则,使用vmap解压缩。
在最新的EROFS中,实现了所有四种解压缩方法。如果要提取的数据块不超过一个,则选择每CPU缓冲区解压缩。
否则,如果使用就地I/O检索压缩块,并且可以就地解压缩,则EROFS采用就地解压缩方法,避免不必要的内存分配和内存复制。对于解压缩的块可以放入预先分配的VM区域的其他情况,EROFS使用滚动解压缩,因为它比vmap解压缩具有更少的内存分配开销。对于任何其他情况,采用vmap减压方法。
论文链接——EROFS: A Compression-friendly Readonly File System for Resource-scarce Devices | USENIX
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。