ossfs 2.0.8 及以后版本支持本地数据缓存,通过将读取过的文件数据缓存到本地磁盘,加速后续的重复读取并降低 OSS 请求量。本文介绍本地数据缓存的工作原理、配置方法与性能表现。
背景信息
使用 ossfs 2.0 访问 OSS 时,每次读取文件都需要从远端拉取数据。对于 AI 训练、模型加载等需要多轮重复读取相同数据的场景,频繁的远端访问会带来较高的网络时延和带宽消耗。
ossfs 2.0 的本地数据缓存通过在本地磁盘保留已读取过的文件数据,使后续访问直接从本地获取,从而显著提升重复读性能、降低 OSS 请求费用。
ossfs 2.0 本地数据缓存具备以下特点:
性能更优:大文件、小文件重复读场景下带宽均显著优于 ossfs 1.0,具体可见下文性能对比。
自动淘汰:内置 LRU 淘汰策略,缓存写满时自动回收最久未访问的文件,无需手动清理。
海量小文件支持:配合元数据缓存(
--max_inode_cache_count、--attr_timeout),可大幅加速 AI 训练数据集的多轮加载。
本地数据缓存仅用于读缓存,不影响写路径——写入操作不经过本地缓存。这与 ossfs 1.0 的 -ouse_cache 不同,后者会同时缓存读写数据。
工作原理
缓存粒度
缓存以 OSS 对象(文件)为基本单位。每个被读取过的文件在缓存目录中对应一个缓存文件,采用按需填充的方式。
读取流程
首次读取:数据从 OSS 拉取并同步写入本地缓存目录。
后续读取:直接从本地缓存读取。
空间回收
当缓存接近容量上限时,自动按 LRU(最近最少使用)策略淘汰旧文件,腾出空间给新数据,回收操作以单个缓存文件为最小单位进行。
配置方法
配置项 | 是否必填 | 说明 | 默认值 |
disk_data_cache_dir | 是 | 本地缓存目录路径。配置为非空时启用数据缓存。 | 空 |
disk_data_cache_size | 是 | 缓存容量上限,按 GiB 对齐。不可超过缓存目录所在磁盘/分区的可用空间。 | 空 |
disk_data_cache_io_engine | 否 | 磁盘缓存 IO 引擎,可选 psync 或 libaio。 | psync |
约束:
--disk_data_cache_dir 指向的目录必须存在且为空目录,尽量保证缓存路径为独立分区 / 独立盘。
--disk_data_cache_size 不可超过缓存目录所在磁盘的可用空间。
同一台机器上挂载多个 ossfs2 实例时,每个实例必须使用独立的缓存目录。
ossfs2 进程退出时不会自动清理缓存目录,需要手动清理。
挂载后尽量不要对缓存目录路径进行操作,避免发生未知错误。
挂载命令示例:
ossfs2 mount /mnt/oss/ \
--oss_bucket <your-bucket> \
--oss_endpoint <your-endpoint> \
--oss_access_key_id <ak> \
--oss_access_key_secret <sk> \
--disk_data_cache_dir /mnt/disk/ossfs2/cache \
--disk_data_cache_size 256G环境要求
参数 | 要求 |
缓存盘文件系统 | ext4、xfs 或 tmpfs(仅限 psync 模式),其他文件系统未验证 |
缓存盘类型 | 推荐弹性临时盘 / 本地 NVMe;ESSD PL0/PL1/PL2 的吞吐容易成为瓶颈,此时使用体验可能较差;内存充裕时可使用 tmpfs(仅限 psync) |
缓存盘可用空间 | 不小于 --disk_data_cache_size 设定的值 |
使用建议
本地数据缓存适用于“读多写少”且需要重复访问相同数据的场景。
IO 引擎(disk_data_cache_io_engine)配置建议:
psync:使用同步读写系统调用,读取时数据会经过操作系统 PageCache。当缓存数据量接近或小于可用内存时,热数据自然驻留在 PageCache 中,可获得接近内存的读取速度。适用于通用场景、低规格云盘以及 tmpfs 缓存盘(tmpfs 不支持 libaio)。
libaio:使用 Linux 异步 IO 接口,绕过 PageCache 直接操作磁盘。适用于大容量本地 NVMe + 数据集远大于内存的场景,相比 psync 通常有 20% 左右的额外提升。
下表列出典型场景及推荐配置:
场景 | 使用建议 |
AI 训练数据多轮加载(多 epoch 重复访问同一数据集)、固定数据集多次查询 / 分析 | 启用本地数据缓存,按数据集大小×1.1 设置 --disk_data_cache_size。缓存盘为本地 NVMe 且数据量较大时,推荐 --disk_data_cache_io_engine=libaio,充分发挥磁盘性能。 |
大模型推理 / vLLM 加载(GB 级模型文件反复加载) | 推荐机型内存大于模型总大小时,使用 tmpfs 盘作为缓存盘。若内存不足以全缓存模型文件,也可选择本地盘作为缓存盘,但此时性能会受盘性能限制,需要具体评估后判断是否开启本地数据缓存。 |
若对数据实时性要求高且数据频繁修改的场景下,不建议开启数据缓存(缓存存在一定时效性差异)。
性能对比
测试对象:ossfs 2.0.8 vs ossfs 1.91.10。表中“首次读 / 后续读”分别对应缓存未命中(需从 OSS 拉取)与命中本地缓存。“—”表示该配置无缓存,不区分首次/后续读。
场景一:大文件顺序读(4 线程读取 100GB 文件)
测试环境
机器:ecs.i4.4xlarge(16 vCPU,128 GiB)
本地 NVMe 盘:3576 GiB NVMe(读带宽 6 GB/s,写带宽 3 GB/s,IOPS 90w)
ossfs 2.0:--disk_data_cache_dir=<path> --disk_data_cache_size=3T
ossfs 1.0:-ouse_cache=<path> -oparallel_count=128
结果
配置 | 带宽(首次读 / 后续读) | CPU (avg/max) | 峰值内存 |
ossfs 2.0(无缓存) | 2841 MB/s — | 385% / 468% | 5170 MB |
ossfs 2.0 | 2206 / 5947 MB/s | 244% / 349% | 2081 MB |
ossfs 1.0 | 1249 / 2648 MB/s | 815% / 1214% | 137 MB |
结论:
启用缓存后,ossfs 2.0 在大文件后续读场景下相比 ossfs 1.0 性能提升约 2.2 倍(libaio 模式 5947 vs 2648 MB/s),可达到本地 NVMe 性能上限;同时 CPU 占用大幅降低(≈250% vs 800%)。
场景二:海量小文件读取(ImageNet 训练数据集加载)
测试环境
机器:ecs.i4.32xlarge(128 vCPU,1024 GiB)
本地 NVMe 盘:8 × 3576 GiB NVMe
数据集:ImageNet 训练集(约 1.3M 张图片),多 epoch 重复加载
ossfs 2.0:--disk_data_cache_dir=<path> --disk_data_cache_size=1500G --disk_data_cache_io_engine=libaio --attr_timeout=36000 --max_inode_cache_count=11000000(启用元数据缓存)
ossfs 1.0:-ouse_cache=<path> -oreaddir_optimize -omax_stat_cache_size=11000000 -ostat_cache_expire=72000
结果
配置 | 带宽(首次读 / 后续读) | CPU (avg/max) | 峰值内存 |
ossfs 2.0(无缓存) | 304 MB/s —(约 2400 img/s) | 67% / 209% | 5062 MB |
ossfs 2.0 | 329 / 895 MB/s(约 7100 img/s) | 116% / 1216% | 6802 MB |
ossfs 1.0 | 38 / 224 MB/s(约 2000 img/s) | 66.1% / 206% | 31.6 GB |
结论:
启用磁盘缓存 + 元数据缓存后,ossfs 2.0 后续 epoch 加载性能达到首次读的 2.7 倍(895 vs 329 MB/s),且完全消除 OSS 网络请求。多轮重复加载相同数据集的 AI 训练负载,强烈推荐使用 ossfs 2.0 本地数据缓存(libaio引擎)+元数据缓存。