第1章:文件系统选择与优化
做嵌入式Linux回测系统,我踩过最大的坑就是文件系统。说实话,很多人觉得文件系统就是个存数据的地方,随便选一个就行。但在我参与的几个高性能回测项目中,文件系统选型直接决定了系统能不能跑起来。
今天咱们就聊聊Flash友好型文件系统、只读文件系统,还有日志策略怎么调优。这些都是我这些年摸爬滚打总结出来的经验。
1.1 Flash友好型文件系统:UBIFS vs JFFS2
嵌入式设备用的都是Flash存储,不是机械硬盘。Flash有个特点:写前必须先擦除,而且擦除次数有限。普通文件系统(比如ext4)在Flash上跑,很快就会把Flash写坏。
所以我们需要Flash友好型文件系统。目前主流的就是UBIFS和JFFS2。
1.1.1 JFFS2:老牌选手
JFFS2是Linux内核里最早出现的Flash文件系统之一。它的设计思路很直接:把整个Flash当成一个日志,所有修改都追加写入。
我在一个早期的回测项目里用过JFFS2。当时觉得它挺稳定,但后来发现一个问题——挂载时间太长了。你想想看,每次挂载都要扫描整个Flash,重建文件系统树。如果Flash有128MB,挂载时间可能超过10秒。
JFFS2核心特点:
- 支持磨损均衡
- 支持压缩
- 挂载时间随容量线性增长
- 内存占用较高
1.1.2 UBIFS:新一代选择
UBIFS是JFFS2的接班人。它引入了UBI层来处理坏块管理和磨损均衡,性能比JFFS2好很多。
我个人习惯在回测系统里用UBIFS。为什么?因为它挂载快,而且支持写缓冲,写入性能比JFFS2高出好几倍。
# 创建UBIFS镜像
mkfs.ubifs -r rootfs -m 2048 -e 128KiB -c 1024 -o ubifs.img
# 制作UBI镜像
ubinize -o ubi.img -m 2048 -p 128KiB ubinize.cfg
# 挂载UBIFS
ubiattach -m 1 -d 0 /dev/ubi_ctrl
mount -t ubifs ubi0:rootfs /mnt/rootfs
我的建议:新项目直接用UBIFS。JFFS2只适合Flash容量很小(64MB以下)的场景。
1.2 只读文件系统:SquashFS
回测系统的固件部分,其实不需要频繁修改。这时候用只读文件系统就非常合适。
SquashFS是我最常用的只读文件系统。它支持高压缩比,能把一个100MB的根文件系统压缩到30MB左右。对于Flash容量有限的嵌入式设备来说,这太重要了。
我曾经在一个项目里,固件大小刚好超过Flash容量。用SquashFS压缩后,不仅塞进去了,还省出20MB空间给数据分区。
# 制作SquashFS镜像
mksquashfs rootfs/ rootfs.squashfs -comp xz -b 128K
# 挂载SquashFS
mount -t squashfs rootfs.squashfs /mnt/rootfs -o loop
注意:SquashFS是只读的。如果需要修改文件,必须重新制作镜像并烧录。所以它只适合存放不常变动的系统文件。
1.3 日志策略调优
文件系统的日志机制,说白了就是为了保证数据一致性。但日志写多了,性能就会下降。
在回测场景下,我们通常可以接受一定的数据丢失风险,换取更高的写入性能。这时候就可以调整日志策略。
1.3.1 UBIFS日志调优
UBIFS的日志策略主要通过挂载参数来控制:
| 参数 | 说明 | 推荐值 |
|---|---|---|
| bulk_read | 批量读取,提高顺序读性能 | 1 |
| no_chk_data_crc | 跳过数据CRC校验,提高写性能 | 1(回测场景) |
| compr_type | 压缩类型,lzo速度最快 | lzo |
# 高性能挂载方式
mount -t ubifs ubi0:rootfs /mnt/rootfs -o bulk_read,no_chk_data_crc,compr_type=lzo
1.3.2 关闭不必要的日志
对于临时数据分区,比如存放回测中间结果的目录,可以考虑关闭日志:
# 创建无日志的UBIFS卷
ubimkvol /dev/ubi0 -N temp_data -s 50MiB -t static
# 挂载时禁用日志
mount -t ubifs ubi0:temp_data /mnt/temp -o chk_data_crc=0
避坑指南:我曾经在一个回测系统里,把所有分区都关了日志。结果一次意外断电后,配置文件损坏,系统起不来了。所以系统关键分区(比如/etc)一定要保留日志保护。
1.4 知识体系总览
下面这张图展示了本章的核心逻辑:
1.5 实战建议
说了这么多,最后给几个实际项目中的建议:
- 系统分区用SquashFS:固件、内核、库文件放这里,只读保护,压缩省空间。
- 数据分区用UBIFS:回测结果、配置文件、日志文件放这里,需要读写。
- 临时分区关日志:中间计算结果、缓存文件,丢了也不心疼。
- 关键配置保留日志:比如网络配置、系统参数,这些丢了系统可能起不来。
小技巧:如果你用的是NAND Flash,记得选UBIFS。如果是NOR Flash,JFFS2可能更合适。不过现在大部分嵌入式设备都是NAND了。
嗯,文件系统这块就聊到这儿。记住一句话:没有最好的文件系统,只有最适合你场景的文件系统。选对了,性能翻倍;选错了,天天修Bug。
公众号:蓝海资料掘金营,微信deep3321