本文封面背景图采用CC-BY-SA-4.0协议,来源于Wikipedia
前言
本文主要讨论EROFS文件系统的使用
EROFS是一个只读文件系统,主要由Gao Xiang开发,在Linux 5.4中合并到主线内核。EROFS的设计目标是提供高性能、低资源开销的只读文件系统,设计上主要针对的场景是ROM、系统分区、应用分区等较轻量级的手机或者嵌入式环境。笔者在这里对EROFS在一般存储与备份的应用场景下的表现进行研究。
笔者想试用EROFS是因为它可能具有以下优势:
- 布局设计上对随机访问性能进行了优化,可以提供更加强劲的随机访问性能
- 相比squashfs是按压缩前的内容分块,EROFS是按压缩后的内容分块,可以保证直接访问的压缩内容块大小固定
- 支持POSIX ACL
- 实验性支持块级别的去重
- 相比squashfs支持的文件级别的去重,EROFS支持的块级别的去重可以更加高效地去重
|<- variable-sized extent ->|<- VLE ->|
clusterofs clusterofs clusterofs
| | |
_________v_________________________________v_______________________v________
... | . | | . | | . ...
____|____._________|______________|________.___ _|______________|__.________
|-> lcluster <-|-> lcluster <-|-> lcluster <-|-> lcluster <-|
(HEAD) (NONHEAD) (HEAD) (NONHEAD) .
. CBLKCNT . .
. . .
. . .
_______._____________________________.______________._________________
... | | | | ...
_______|______________|______________|______________|_________________
|-> big pcluster <-|-> pcluster <-|
EROFS的使用
EROFS的安装
以Arch Linux为例,目前的内核早已包含EROFS,只需要安装erofs-utils
即可使用EROFS。
sudo pacman -S erofs-utils
EROFS的创建
EROFS的创建非常简单,只需要使用mkfs.erofs
命令即可,例如:
sudo mkfs.erofs /path/to/image.img /path/to/source
在此基础上,我们还可以指定更多参数,例如:
-z
:指定压缩算法,可选lz4
、lz4hc
、lamz
,可以在后面加,
并跟上压缩等级,可以用:
分隔可选的压缩算法,例如指定压缩等级为12的lz4hc
算法即为lz4hc,12
-C
:指定最大物理簇大小,单位为字节,最大为1 MiB,即1048576
-E
:指定拓展选项dedupe
:开启去重
EROFS的挂载
EROFS的挂载非常简单,只需要使用mount
命令即可,例如:
sudo mount -t erofs /path/to/image.img /path/to/mountpoint
还可以通过fuse的方式挂载,例如:
sudo erofs-fuse /path/to/image.img /path/to/mountpoint
效果测试
笔者就存储与备份应用场景对EROFS进行了测试,并与squashfs进行了对比。
创建速率及压缩率
笔者使用不同的压缩参数,测试squashfs和EROFS的创建速率和压缩率。
笔者的测试平台是:
- CPU:AMD 5800H 8c16t 3200 MHz
- 内存:板载美光DDR4 16 GB 3200 MHz
- 存储:致态TiPlus 5000 2 TB
- 发行版:Arch Linux
- Linux:6.4.6
erofs-utils
:1.6squashfs-tools
:4.6.1
基本测试
测试文件为一个装有Xfce桌面环境的Arch Linux容器文件夹,原始大小约为3797448 KiB,squashfs和EROFS的块大小均为1 MiB。
文件系统 | 压缩算法 | 压缩等级 | 大小(KiB) | 压缩率 | 耗时(s) | 速率(KiB/s) |
---|---|---|---|---|---|---|
squashfs | zstd | default (15) | 1436510.05 | 37.37% | 43.99 | 86328.69 |
squashfs | zstd | 6 | 1438565.88 | 37.88% | 16.77 | 226357.23 |
squashfs | zstd | 3 | 1493950.67 | 39.58% | 8.15 | 465885 |
squashfs | zstd | 1 | 1602424.36 | 42.20% | 6.96 | 545443 |
squashfs | lz4 | Not Supported | 1951430.30 | 51.39% | 7.37 | 514986 |
erofs | lz4 | Not Supported | 3519608.00 | 92.68% | 10.24 | 370781 |
erofs | lz4hc | 9 | 1855644.00 | 48.47% | 388.97 | 9762 |
可见,EROFS除非采用压缩程度极小的算法等级,否则文件系统的创建将极度缓慢,在相同压缩算法与压缩等级的情况下,EROFS的创建比squashfs慢超过50倍,远远不如squashfs实用。这里默认创建squashfs时会开启重复数据删除功能,而EROFS的重复数据删除目前还是实验性支持,开启后会导致创建速率雪上加霜,极度缓慢,即使是在最快的lz4算法下,平均输出速度不到1 MB/s,因此这里没有完整测试,这里EROFS的压缩率不如squashfs主要是未开启重复数据删除的原因。
究其原因,是mkfs.erofs
仅使用了单线程设计,不仅压缩仅由单线程完成,文件读取与重复数据删除全部都在一个线程里面排队,导致文件系统创建速率极低,在文件备份的场景下非常不方便。
详细测试
笔者进一步考虑了块大小这一因素,测试了不同块大小下的压缩率和创建速率,测试结果如下。测试文件同样是一个装有Xfce桌面环境的Arch Linux容器文件夹(但带有boot
分区),原始大小约为3909512 KiB。本测试对比了块大小、压缩算法、压缩等级三个因素,反映的结果为压缩率、创建速率、压缩速率,测试结果如下:
文件系统 | 块大小(KiB) | 压缩算法 | 压缩等级 | 大小(KiB) | 压缩率 | 耗时(s) | 速率(KiB/s) |
---|---|---|---|---|---|---|---|
squashfs | 4 | zstd | 1 | 1911360 | 48.89% | 7.42 | 526888 |
squashfs | 128 | zstd | 1 | 1740716 | 44.53% | 6.11 | 639854 |
squashfs | 1024 | zstd | 1 | 1715208 | 43.87% | 6.04 | 647270 |
squashfs | 4 | zstd | 3 | 1886500 | 48.25% | 7.25 | 539243 |
squashfs | 128 | zstd | 3 | 1682224 | 43.03% | 6.21 | 629551 |
squashfs | 1024 | zstd | 3 | 1606452 | 41.09% | 7.26 | 538500 |
squashfs | 4 | zstd | 6 | 1853852 | 47.42% | 7.65 | 511047 |
squashfs | 128 | zstd | 6 | 1619220 | 41.42% | 7.41 | 527599 |
squashfs | 1024 | zstd | 6 | 1551152 | 39.67% | 15.36 | 254526 |
squashfs | 4 | zstd | default (15) | 1800144 | 46.05% | 38.99 | 100269 |
squashfs | 128 | zstd | default (15) | 1540216 | 39.40% | 46.63 | 83841 |
squashfs | 1024 | zstd | default (15) | 1531772 | 39.18% | 43.62 | 89627 |
squashfs | 4 | lz4hc | Not Supported | 2196376 | 56.18% | 12.16 | 321505 |
squashfs | 128 | lz4hc | Not Supported | 1830572 | 46.82% | 30.59 | 127803 |
squashfs | 1024 | lz4hc | Not Supported | 1789976 | 45.79% | 41.73 | 93685 |
squashfs | 4 | lz4 | Not Supported | 2310164 | 59.09% | 7.69 | 508389 |
squashfs | 128 | lz4 | Not Supported | 2078612 | 53.17% | 6.07 | 644071 |
squashfs | 1024 | lz4 | Not Supported | 2063612 | 52.78% | 6.39 | 611817 |
squashfs (no-duplicates) | 4 | lz4hc | Not Supported | 2239452 | 57.28% | 12.09 | 323367 |
squashfs (no-duplicates) | 128 | lz4hc | Not Supported | 1865724 | 47.72% | 29.79 | 131236 |
squashfs (no-duplicates) | 1024 | lz4hc | Not Supported | 1823560 | 46.64% | 40.18 | 97300 |
squashfs (no-duplicates) | 4 | lz4 | Not Supported | 2354264 | 60.22% | 8.88 | 440260 |
squashfs (no-duplicates) | 128 | lz4 | Not Supported | 2115096 | 54.10% | 5.95 | 657061 |
squashfs (no-duplicates) | 1024 | lz4 | Not Supported | 2098692 | 53.68% | 6.25 | 625522 |
erofs | 4 | lz4hc | 9 | 2225036 | 56.91% | 76.71 | 50964 |
erofs | 128 | lz4hc | 9 | 1995220 | 51.04% | 261.54 | 14948 |
erofs | 1024 | lz4hc | 9 | 1983248 | 50.72% | 865.25 | 4518 |
erofs | 4 | lz4 | Not Supported | 2374256 | 60.73% | 16.33 | 239407 |
erofs | 128 | lz4 | Not Supported | 2239728 | 57.29% | 16.49 | 237084 |
erofs | 1024 | lz4 | Not Supported | 2236176 | 57.20% | 17.88 | 218653 |
erofs (fragments) | 4 | lz4hc | 9 | 2132044 | 54.53% | 77.94 | 50161 |
erofs (fragments) | 128 | lz4hc | 9 | 1842848 | 47.14% | 330.58 | 11826 |
erofs (fragments) | 1024 | lz4hc | 9 | 1815460 | 46.44% | 31.68 | 123406 |
erofs (fragments) | 4 | lz4 | Not Supported | 2285184 | 58.45% | 16.04 | 243735 |
erofs (fragments) | 128 | lz4 | Not Supported | 2102400 | 53.78% | 21.02 | 185990 |
erofs (fragments) | 1024 | lz4 | Not Supported | 2084988 | 53.33% | 27.49 | 142216 |
分析以上数据,我们可以得出一些结论:
- 低压缩等级的zstd算法的压缩率对块大小较为敏感,将块大小由128 KiB提高到1 MiB的收益仍然明显;其他情况一般仅由4 KiB提高到128 KiB才有明显收益
- lz4hc算法的压缩率对块大小不敏感,但是压缩速率对块大小非常敏感,增大块大小将严重影响压缩速度
- 这里的测试仍然表明,EROFS的创建速率很慢,在同样的压缩等级为9的lz4hc算法、1 MiB块大小下,比squashfs慢了20多倍
- 由于IO瓶颈,本测试对于squashfs在低压缩等级的zstd下的压缩以及lz4算法下的压缩的压缩速率不能反映太多实际问题
- EROFS在架构上的设计似乎使其在相同条件下比squashfs更节省空间,但是目前EROFS的用户空间程序较弱,重复数据删除功能性能开销极大,而目前的squashfs默认开启重复数据删除,导致现在默认情况下创建的squashfs压缩率更有优势
读取测试
笔者对整个文件系统用rsync
逐文件进行了读取测试,较完整、均衡地包含了随机读取性能和连续读取性能;为了控制变量,两个文件系统均采用压缩等级为9的lz4hc算法压缩,并都用1 MiB的块大小,测试结果如下:
文件系统 | 耗时/s |
---|---|
squashfs | 17.83 |
EROFS | 15.93 |
EROFS的架构优势在这里体现了出来,EROFS的读取速率略高于squashfs,但差距不大,可能是块大小过大,EROFS的文件系统布局收益不明显的原因。
总结
EROFS在存储与备份应用场景下的表现目前看来并不理想,虽然该文件系统的架构设计和布局都非常优秀,可以提供更加强劲的随机访问性能,但是由于其现有创建程序mkfs.erofs
的开发力不够,功能实现不充分,将各项操作都放在一个线程下,导致了资源利用不充分,创建备份速率极慢,导致其在存储与备份应用场景下的表现不佳,需要后续优化。