
当 AI 训练数据存储在某个云区域,而 GPU 集群部署在另一个云区域时,每一轮 epoch 训练迭代都会给跨区域网络传输带来可观开销。于是,我们利用算力侧的 NVMe 盘来构建 Alluxio 分布式缓存层,通过对接 Anyscale 平台的 Ray 框架,对 1TB 数据集开展 Ray Data 基准测试,结果显示:缓存预热后,数据读取耗时从 4241 秒降至 208 秒,整体提速 20 倍。
🔗 Anyscale 平台的 Ray 框架:https://www.anyscale.com/platform
现存痛点:跨区域读取成为分布式 AI 训练瓶颈
在分布式 AI 训练中,跨区域数据读取是 GPU 数据工作流中最常见、影响最大且成本居高不下的性能瓶颈。在本次基准测试环境中,Ray 集群部署在 asia-south1(印度孟买)区域,而训练数据存储在 us-central1(美国中部)的 GCS 存储桶中,每一次数据读取都要跨越重洋。
我们使用分布式多模态数据处理库 Ray Data,直接从远端 GCS 读取 1TB Parquet 格式数据集,单次完整读取耗时超 4200 秒。而 AI 训练任务往往需要多轮迭代遍历同一数据集,网络延迟会被持续放大,最终导致 GPU 因等待数据而空转,算力资源严重浪费。标准的 Ray Data 读取代码示例如下:
ds = ray.data.read_parquet("gs://us-central1-bucket/dataset/")
ds.map_batches(train_step).count()
# 4,294 seconds. Every epoch.
问题并非出在 Ray 框架本身,根源在于数据远端部署,每一次读取都要重复进行跨区域网络拉取。
解决方案:Alluxio + Anyscale Ray 框架
平台介绍
Anyscale 是面向多云场景的 AI 平台,基于 Ray 构建,可支撑企业搭建、扩展全流程 GPU 加速 AI 业务。平台提供 Python API,屏蔽了 Kubernetes 集群部署、Ray 分布式算力运维等复杂工作。为了支持多云体验,Anyscale 充当统一管理平面,可连接 AWS 账户、Google Cloud 项目或其他云中 Kubernetes 集群里的云资源。除了统一的管理体验之外,还可以配置多个云资源,使得当主配置中的资源在 Anyscale 集群上不可用时,Anyscale 作业可以回退到其他区域或云提供商的资源,从而保障业务连续性。
Alluxio 是位于算力侧、基于 NVMe 盘部署的分布式缓存系统,与 Ray 集群同节点部署。数据首次读取时,Alluxio 会将远端存储的数据缓存至本地 NVMe SSD;后续所有训练迭代、参数调优、重复读取操作,均可直接从本地缓存获取数据,彻底消除跨区域网络传输开销。
Alluxio 这套缓存方案可无缝对接亚马逊 S3、谷歌 GCS、微软 Azure Blob 、阿里云 OSS、腾讯云 COS、百度云 BOS、火山引擎 TOS等主流对象存储,也支持本地 NAS、HDFS 等兼容 POSIX 协议的文件系统。
整体架构逻辑
统一全局管控平面(Anyscale)对接多云 Ray 集群,每个 Ray 集群均搭配本地 NVMe 缓存(Alluxio),通过 Alluxio 统一命名空间实现数据抽象,底层数据源为唯一的核心对象存储(S3/GCS/Azure Blob)。

我们通过 Anyscale 的 Kubernetes Operator 部署了 Anyscale Kubernetes 云资源,同时部署了 Alluxio 的 Kubernetes Operator 及挂载的文件存储,并利用 Alluxio 进行数据访问。
在本次基准测试中,底层的存储桶位于 GCS 的 us-central1 区域 ------ 无论数据存放在哪里,其架构、访问模式和性能特征都是完全相同的。如果你的训练数据在 S3 中,而 GPU 在其他地方,或者你正在将数据从本地存储拉取到云端的 Ray 集群中,同样的方法完全适用。这也是用 Alluxio 对 Ray Data 进行缓存能够跨多云落地、而非仅仅针对单一云进行优化的原因所在。
[ Ray Cluster · asia-south1 (Mumbai) ]
5 × n2-standard-8 · ray.data.read_parquet()
↕ S3 API(port 29998)or FUSE mount ↕
[ Alluxio Workers · NVMe Cache ]
3 × n2-standard-16 · 8× NVMe SSDs each · 6TB total pagestore
↕ first read only ↕
[ GCS · us-central1 ]
Cross-region object storage · never touched again after cache warm
Ray Data 可通过两种方式对接 Alluxio,两种模式均无需修改训练代码、模型逻辑与 Ray 任务配置:
- S3 兼容接口:基于 s3fs 工具,通过 29998 端口访问;
- FUSE 挂载:挂载至本地 /mnt/alluxio 路径,走标准POSIX 本地文件访问。
对于迭代式训练负载 ------ 比如多 epoch 训练、Ray Tune 超参数搜索、重复的数据集遍历 ------ 这种方案的经济性非常可观:只需承担一次跨区域网络开销,后续所有迭代均以本地 NVMe 高速读取性能运行。
踩坑总结:规模化测试中遇到的两大问题
本次实现 20 倍提速并非一蹴而就,我们累计执行 5 轮基准测试,发现两个 Ray 用户极易踩中的坑,其中一个问题还曾产出误导性测试数据。
坑1 ------ 规模化场景下,.materialize() 严重拖累读取性能
初期测试中,我们使用 ray.data.read_parquet(paths).materialize() 主动加载全量数据。在 1.2GB 小数据集场景下,缓存预热后实现了 18 倍提速,非常令人兴奋。但随着数据集规模扩大,性能急转直下:

0.41x ------ 我们甚至让事情变得更糟了。 在120GB时,Alluxio 比直接读取 GCS 还要慢。
问题根源
.materialize() 会将所有反序列化后的数据写入 Ray 对象存储。数据规模扩大后,会触发大量磁盘溢出(disk spilling),NVMe 缓存的性能优势被完全掩盖,最终测试结果反映的只是磁盘溢出速度,而非真实数据读取性能。
解决办法
替换执行逻辑,使用 map_batches(lambda x: x).count():该方式同样能强制进行完整的行级反序列化 ,每个字节都会被读取和解码 ,会丢弃结果而不写入 Ray 对象存储,彻底规避磁盘溢出问题。
# ❌ Before --- triggers disk spilling at scale, masks cache benefit
ray.data.read_parquet(paths).materialize()
# ✅ After --- full data read without object store pressure
ray.data.read_parquet(paths, filesystem=fs).map_batches(lambda x: x).count()
这是 Ray 特有的坑。当你希望数据驻留在对象存储中供下游任务使用时,.materialize() 是正确的选择。但在评测数据加载吞吐量时,它会引入一个写入瓶颈,使得任何缓存层看起来都不如实际表现。切换之后,在相同的硬件上我们立即看到了 3 倍的性能提升。
测试脚本演进过程
V1 / V2 :使用 materialize():小规模下有效,大规模下崩盘。使用了 .materialize(),在 1.2GB 时产生了最初的 18 倍加速。在 120GB + 5 个 Ray worker 时,对象存储溢出导致结果下降至 0.41 倍。v2 扩展了 v1,通过环境变量支持多数据集配置。
V3:改用 map_batches().count(),仅支持 S3 接口访问,首个可用于大规模测试的稳定版本。通过 .map_batches(lambda x: x).count() 强制完整行反序列化,不写入对象存储,消除了两个坑。
V4(最终版):新增环境变量 ACCESS_MODE 可切换 S3 接口 / FUSE 挂载模式,本次 1TB 数据集、20 倍提速的核心数据均基于该版本 FUSE 模式产出。
基准测试结果
基于 V4 版本、FUSE 挂载模式,我们对 1TB FineWeb-Edu Parquet 数据集开展三轮测试(首轮冷读、后两轮热读),算力位于印度孟买,数据存储于美国中部 GCS:

核心结论:缓存预热后,平均提速20.35 倍
在两轮热读中,Alluxio 基于本地 NVMe 读取 1TB 数据约 208 秒,而直读 GCS 需 4100 秒以上。在数据本地化后,没有跨区域网络开销和网络波动,性能非常稳定。
冷读场景实现 2.4 倍提速也符合预期:首轮仍需从远端 GCS 拉取数据,但 Alluxio 的并行预取(Parallel Prefetch)工作流比原生的直读方式更高效,并且只需承担首次的跨区域开销。
为何重点展示缓存预热加速比,而非综合平均加速比?
综合 5.84 倍的平均加速比包含了首轮冷读耗时。在真实 AI 训练场景中,第一轮迭代完成缓存加载,后续绝大多数训练轮次(第 2 轮及以后)均运行在缓存预热状态,20.35 倍的提速才是训练作业在绝大多数时间里真正体验到的速度。
60GB S3 API 基准测试 ------ 辅助参考数据

在 60GB 数据量下通过 S3 API 访问时,热读的加速比为 5.17 倍。针对大于 100GB 的大规模数据集,优先推荐 FUSE 访问模式:该模式省去 s3fs 协议转换层,Ray Data 直接通过本地 POSIX 路径读取数据,与 Ray 并行预取架构适配性更强,性能优于 S3 接口。
解决方案适用场景
Alluxio 分布式缓存搭配 Ray 集群,在以下四大场景中价值最为突出:
- 多轮 epoch 迭代训练:重复读取同一数据集的训练任务,缓存将跨区域成本分摊到所有 epoch 中,而跨区域网络开销仅需承担一次,迭代轮次越多,收益越高。
- Ray Tune 超参搜索(Hyperparameter Search):多组并行实验任务读取同一份数据集。Alluxio 统一提供本地缓存数据,避免大量并发跨区域请求冲击远端对象存储。
- 跨区域 / 多云部署:算力与数据分属不同云区域、不同云厂商,可智能切换资源,兼顾高可用性与成本优化,兼容亚马逊 S3、谷歌 GCS、微软 Azure Blob 、阿里云OSS、腾讯云COS、百度云BOS、火山引擎 TOS等主流对象存储。
- 本地数据上云训练:将机房本地存储数据对接云端 Ray 集群,一次数据入缓存,后续全量本地高速读取。
如何快速接入该方案
Alluxio 以 Kubernetes operator 的形式与 Ray 集群一起部署。该 Operator 与部署在 Anyscale Kubernetes 云资源上的 Anyscale Operator 没有交互。Ray Data 对接 Alluxio 分为两种方式,代码示例如下
import s3fs, ray
# Option 1 --- S3 API(works out of the box)
alluxio_fs
key="alluxio", secret="alluxio",
endpoint_url="http://alluxio-worker.alluxio.svc:29998",
client_kwargs={"region_name": "us-east-1"},
config_kwargs={"s3": {"addressing_style": "path"}},
)
ds = ray.data.read_parquet("s3://gcs/your-dataset/", filesystem=alluxio_fs)
# Option 2 --- FUSE (recommended for large-scale reads)
ds = ray.data.read_parquet("/mnt/alluxio/gcs/your-dataset/")
# Either way --- use thisfor benchmarking, not .materialize()
ds.map_batches(lambda x: x).count()`
在基于 Anyscale 的 Ray 工作负载中应用 Alluxio
如果你正使用 Ray Data 访问云对象存储,尤其是在跨区域或跨云的场景下,Alluxio 的分布式缓存可以在不修改训练代码的情况下,帮助实现数据读取速度的大幅提升。
开启 Alluxio AI 之旅:可👉免费下载部署,基于自身业务负载进行性能测试,也可参考👉 Fireworks AI 落地案例,了解生产环境中 Alluxio 如何加速模型训练与模型服务。