本地数据缓存

更新时间:
复制 MD 格式

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引擎)+元数据缓存。