作为一名多年的文件系统爱好者,自2017年冬在家汇聚一些想法和思路来POC只读压缩文件系统(即后来开源并upstream到Linux主线的EROFS文件系统)直到今天已经有4年的时间。我相信很多人不解为什么要长时间专注一个这么“简单”的只读文件系统,本文希望从我的自述解答如下问题:
1、之前的只读压缩文件系统存在什么问题?
2、为什么不改进之前的只读文件系统?为什么不开发通用文件系统的压缩特性(例如ext4、f2fs、xfs等)?为什么不开发块设备方案?
3、EROFS究竟有什么优势?
4、EROFS的未来。
如果大家觉得下述这些观点还有些道理,对EROFS或者Nydus镜像服务有些兴趣或者有新的落地场景,欢迎尝试并及时反馈我们,同时非常欢迎贡献中立、开放的EROFS和Nydus解决方案。
1、不破不立
故事的源头要从2016年说起。那时我刚入职华为消费者BG,在了解方案过程中,就听到谷歌在Android N上向下游厂商推双分区方案来实现AB升级,双分区虽然能实现无感升级,但意味着双倍的空间占用,因此谷歌引入了社区成熟的squashfs文件系统通过压缩来解决空间占用的问题。
那时的华为终端作为Android阵营的激进派,一方面与谷歌深度合作第一时间商用最新的Android版本,另一方面构建自己的黑科技、“讲故事”。如果说“天生快,一生快”的代表作F2FS文件系统是2016年存储领域的一个大故事,那squashfs就是最新的Android版本一大新特性。F2FS可以算成功了,而squashfs呢?
结果是显然的,可能大家会好奇为什么成熟的squashfs会失败。终其原因是因为Android场景对系统资源的要求极为苛刻——
(1)应用保活,即使进了后台也要尽可能活着不能杀死;
(2)系统和前台应用不能卡顿;
(3)前后台切换要流畅、无感。
在有限的内存和CPU资源下要满足(2)、(3)还不能牺牲(1)对于一个没有深度思考的简单透明压缩方案是极端苛刻的。只读分区的重要性在于大量重要的运行时库都放在系统分区,开源的squashfs在应用轮番启动和前后台切换的测试中,在切到相机前台时,会概率卡住几秒,同时伴随着低内存下的内存回收甚至hungtask。频繁的内存和cache抖动导致整个系统无法进入稳态,不可用。
我记得很清楚的是,在各种调参无果后,整个EMUI7项目组在8月底“风风火火”的把squashfs和AB升级回退掉了。
这是squashfs在华为手机上的结局,而Android的生态结局来的稍微晚了一些:
【p.s. 越来越多的场景正在像当初的Android一样苛刻,例如高密和轻量级容器的需求,我们可以继续妥协么?】
二、只读压缩的再思考
转眼间到了2017年,忙完手头项目后,我在思考下一步要做什么时,脑海里又复盘了一遍一年前的压缩方案。那压缩方案在手机上究竟可不可行?我认为是可行的,确切来说是只读压缩的商用是可以值得走钢丝冒险的:
首先,从是否可以压缩的角度,只读分区里的数据(具体来说是so和odex之类的可执行数据)是确定性有收益的,且只读分区的压缩数据是preload压缩的;读写分区里的只读数据类似,但用户数据收益未知,例如视频、图片、录音都是压缩过的,从商业上收益无法证明;
其次,从投入产出比上,squashfs刚落地失败,投入搞读写压缩搞不好是真的献给情怀了;只读压缩看起来想安稳落地都需要精打细算,要不就会步入squashfs的老路;
最后,从方案可行性上,LZ4在手机内纯解压大概单核~2GB/s,对于ufs 2.x的打满性能大概是600MB/s左右的顺序读,如果把内存资源搞定,CPU资源上妥协一点值得一试,原因有二:
1)系统分区都是一些非I/O带宽敏感的数据;
2)系统分区总有效数据量有限,也就意味着总I/O量有限。
因此怎样最大化压缩率(减少总I/O量,给解压带来更多的margin),怎样尽可能的不依赖额外的内存资源,怎样做到压缩数据cache更友好,成了我那个阶段考虑的重点。
当然,现在这几点都有了确定性的答案:
原地I/O时分复用page cache避免额外分配,原地解压做到解压零拷贝;
固定输出的压缩技术最大化压缩率,同时压缩cache以页为单位更友好,每个压缩块可独立解压(不存在无效数据),可独立选择原地还是cache I/O。
正好2017年底,中低端机ROM空间告急,市场那边已经提出了正式的需求,给压缩方案来了一波顺水推舟。最后结局还是比较美好,我们在荣耀10青春版也就是EMUI 9.0.1低端机上实验性落地,最后大佬在P30发布会和EMUI9.1上正式宣传了这个特性。
这里插一句块设备压缩,固定输出的压缩技术对块设备方案不友好,因为I/O单位所限,基本做不到,而文件系统是字节级的访问固定输出才有更大的意义。当然块设备多了一层overhead更高且没必要,这里不再细提。
三、EROFS文件系统
下面到了关键,当时大佬也在建议我一开始就把方案放到f2fs或者ext4中实现,我盘算了很久没有这么做,原因如下:
1)基于之前失败的事实,我认为f2fs和ext4读写文件系统的inode和索引格式也过重,而我专注的还是那些只读的数据,应该怎么轻量、高效怎么来,避免落地瓶颈;
2)只读场景是一个看起来简单但事实很广泛的场景。通用文件系统场景ext4已经可以满足绝大多数通用需求,而只读场景没有一个经得起极致考验的文件系统,而只读是一个很大的限制性前提条件可以做深度优化定制,而做到通用文件系统中会让这一可能性消失。
因此路子就被限制在改进squashfs和造新轮子上,这样有几点考虑:
1)除去很多细节上的设计问题,究其到底,squashfs是一个字节级寻址的“文件系统”,其blocksize概念只是个基本的压缩单位并不是I/O单位。而字节级寻址和不对齐的元数据做不到只读场景下极致性能(设想给squashfs只实现数据的Direct I/O、mmap和dax场景都需要做额外运行时检查,如果不合适还要fallback到buffer I/O,或者是bounced buffer memcpy),尤其是不对齐的元数据设计也做不到无额外I/O放大。话句话说,高性能的磁盘文件系统需要从基因上就有真正“块”的概念来做到直接访问,即使是未来的pmem,块寻址也不会淘汰,只要做到类似的空间节省。
2)那时个人观察,squashfs的维护者不怎么负责任,新特性接受程度低,推一些简单的优化、小特性(例如ACL)或者bugfix都不见积极回音,那推一波深度优化不知道argue或者silence到猴年马月,而且大改squashfs磁盘格式已无向后兼容的优势,改造意义已经不大。相关的帖子见:
https://lore.kernel.org/r/20170922215508.73407-1-drosen@google.com/
https://lore.kernel.org/r/cover.1533630854.git.geliangtang@gmail.com/
https://lore.kernel.org/r/20190802003457.GD17372@mit.edu/
https://lore.kernel.org/r/20190117082148.129347-1-zhengbin13@huawei.com/
等等等等。(当然最近squashfs作者不知何故活跃了很多……)
3)只读场景是一个可以持续深耕的场景,在嵌入式(手机、路由器)、容器镜像、app容器化(snap、appimage等)甚至IoT设备中都可以找到大量的场景,光列roadmap清单都可以列好久。只要格式经得起推敲、性能优异和在不牺牲性能的前提下把镜像大小做到极致,就可以在只读这个大场景下做到通用性。
最后,结果就是在2017年底,慢慢勾勒出了的现代只读文件系统最核心的几个idea:
1)基于4KiB页单位的磁盘块,非压缩场景可直接mmap、direct I/O和dax,避免一切额外运行时检查和无效fallback;
2)引入tail-packing inline来达到small blocksize或者不对齐元数据接近的空间节省效果,同时根据数据局部性原理来提升I/O性能;
3)32或者64字节的inode来最小化存储元数据,同时满足对齐要求(16字节的inode格式已经没有直接价值【太小,且需要2次索引cache不友好】。)
4)元数据不压缩,因为元数据一般都是随机访问,且为关键路径时延要求敏感,压缩元数据性价比不高;
5)可随机访问的目录结构解决squashfs低效的近线性查找;
6)固定输出压缩、原地I/O和原地解压,主打跟squashfs的差异性,极致解压性能。
2018年春,我们整个项目组在上海集体封闭讨论一周,敲定了EROFS文件系统ondisk磁盘格式,其主要部分一直延续到今天。
四、镜像格式的未来
Android场景已经有越来越多的厂商选择EROFS,例如已经公开的OPPO和酷派,没有公开的小米,还有当前正在紧锣密鼓落地的谷歌原厂:
容器镜像领域,EROFS已经与Nydus镜像服务通过RAFS v6格式深入集成,后面会在按需加载中持续发力,做到数据面无必要不过用户态来达到极致性能。
在基础设施上,erofs-utils已经实现了mkfs、fuse、dump和fsck功能(很多人问只读文件系统要fsck干什么?答:更多用于兼容性检测,其次才是一致性检查),目前也发展出了liberofs,API稳定后可以无缝集成到各大场景中。
erofs及erofs-utils已经登陆到Archlinux、Debian、Fedora、OpenSUSE、Ubuntu等主流发行版中……
不管怎样,默默坚持了4年的我,情怀也罢,自我价值也罢,很希望一直陪着Linux的发展长青下去。也希望各界更多大佬加入我们,继续完善场景,一起maintain,一起普惠整个Linux生态,当然技术无国界,咱(俺)更要自强…
本文转自公众号:猴子的自我修养,EROFS的作者hsiangkao
标签:场景,只读,压缩,文件系统,squashfs,EROFS,缘起 From: https://www.cnblogs.com/mlqq24/p/18250828