浅谈 EROFS
文章目录
本文通过“准备一份基础环境镜像”的例子,浅谈 EROFS(Enhanced Read-Only File System)。
为便于理解,下面以启用压缩的只读镜像为例,不展开制作命令、压缩算法和底层数据结构。
What
先把最容易混淆的一点说清楚:
1 | 文件数据以压缩形式保存 |
EROFS 是 Linux 的一种只读文件系统,支持将目录和文件制作成可以直接挂载使用的镜像。
可以简单理解为:
1 | 制作时:把准备好的目录和文件组织成镜像 |
挂载后,应用看到的仍然是普通的目录和文件;需要读取压缩数据时,由文件系统完成相应的解压。
所以:
不是先把整个镜像解开再使用,而是挂载后,按需读取里面的文件。
注意,压缩是可选功能,不是所有 EROFS 镜像都必须压缩。
Why
操作系统文件、预装工具、基础运行环境等内容,往往在准备好后反复读取,并不需要每次运行时修改。
对于这类数据,我们既希望它们少占磁盘,又希望程序可以方便地读取,而不是每次使用前都先完整解包。
EROFS 的目标并不只是“压得越小越好”,还要尽量控制读取时的 I/O、解压计算和额外内存开销。
因此,它的目的可以概括为:
把只读文件保存得更紧凑,同时让程序能够直接、高效地读取。
基础 Example
假设一份基础环境包含:
1 | 基础环境 |
现在,应用只需要读取 etc/config.ini。
先完整解包再使用
假设采用“把压缩包完整解到目录中,再启动应用”的部署方式:
1 | 基础环境压缩包 |
这条路径中,即使本次只需要一个文件,也先展开了整套环境。
使用 EROFS 镜像
1 | base.erofs |
不需要为了读取这个配置文件,先把 bin/tool 和 lib/libdemo.so 全部解出来。
区别就在于:
省掉的是使用前的整包解压和文件落盘,不是所有解压操作。
How
只看三个关键点。
1. 制作镜像时,先组织好目录和文件
通过 mkfs.erofs,可以把已有目录制作成 EROFS 镜像。
镜像不仅保存文件内容,也保存目录结构、文件属性以及定位数据所需的信息。启用压缩后,文件数据可以以压缩形式存放。
1 | 原有目录和文件 |
之后挂载镜像,就能按原来的目录结构访问其中的文件。
2. 读取文件时,按需定位和解压
以相关数据尚未被缓存为例,可以把读取过程简化为:
1 | 应用读取某个文件的一段内容 |
应用仍然使用普通的文件读取接口,不需要自己解析镜像或调用解压库。
这里的“按需”是以相关数据块为单位,不代表应用读取几个字节,底层就恰好只读取、解压几个字节。
3. 尽量减少读取和解压的额外工作
压缩文件系统需要解决一个问题:
1 | 应用只想读一小段内容 |
EROFS 在压缩数据布局和解压路径上做了专门优化,尽量减少这类额外读取,并减少解压过程中的临时内存和数据拷贝。
可以简单理解为:
不仅考虑“存起来占多少空间”,也考虑“读出来要花多少代价”。
与 OverlayFS 的关系
结合上一篇介绍的 OverlayFS,两者可以这样分工:
1 | EROFS:保存只读的基础内容 |
例如:
1 | 应用看到的目录 |
应用需要修改下层文件时,由 OverlayFS 按需复制到可写上层,再修改上层副本。
不是 EROFS 自己变得可写了,而是写入由另一个可写文件系统承接。
记忆图
1 | 准备阶段: |
一句话概括:
把只读文件做成可以直接挂载的镜像,需要什么就读取什么,不必先把整套内容解开。
参考资料: