集群架构
Ray 集群由一个 Head Node 和若干 Worker Node 组成。单机 ray.init() 时,这些组件也会启动,只是都在一台机器上。
Driver
Driver 是用户程序入口。它提交任务、创建 Actor、持有 ObjectRef,并通过 ray.get 或 ray.wait 等待结果。
在真实部署中,Driver 可以运行在:
- Head Node 上。
- 集群外,通过 Ray Jobs 提交。
- Kubernetes 中的独立 Pod。
这不影响核心语义:Driver 负责发起计算,不负责执行所有计算。
Worker
Worker 是实际运行用户 Python 代码的进程。Ray 会根据任务需要启动或复用 Worker。
Worker 分两类看更清楚:
| Worker 类型 | 主要职责 |
|---|---|
| Task Worker | 执行无状态远程函数 |
| Actor Worker | 承载某个 Actor 实例,执行它的方法 |
Task Worker 可以被多个任务复用。Actor Worker 通常长期绑定到一个 Actor,因为 Actor 的状态存在进程内。
Raylet
Raylet 是每个节点上的本地控制平面。它承担几个关键职责:
- 维护本节点资源视图。
- 启动、停止和复用 Worker。
- 接收任务租约并安排本地执行。
- 参与对象位置、对象拉取和对象传输。
- 向 GCS 汇报节点和资源状态。
可以把 Raylet 理解为“节点级运行时管家”。它不运行你的 Python 函数,但它决定本节点什么时候启动 Worker、哪个 Worker 接任务、对象是否需要从别的节点拉过来。
Object Store
每个节点都有对象存储。任务返回值和 ray.put 对象会进入对象系统,其他任务通过 ObjectRef 引用这些对象。
对象存储有几个重要性质:
- 对象通常是不可变的。
- 大对象可以在同节点 Worker 之间共享。
- 对象可能跨节点传输。
- 内存不足时可以 spill 到外部存储或磁盘。
GCS
GCS(Global Control Store)是集群级元数据服务。早期版本里它基于 Redis,现在是独立服务。
GCS 管理的信息包括:
- 节点加入和离开。
- 各节点的资源信息。
- Actor 的位置和状态。
- Placement Group。
- Job 提交和状态。
GCS 不是所有任务的瓶颈。任务执行、对象传输、本地调度这些高频路径不经过 GCS,它们由 Raylet 和 Object Store 在本地完成。GCS 主要在集群协调和故障恢复时发挥作用。
Dashboard 和 State API
Dashboard 是调试工具,不是业务依赖。它读取运行时状态,帮助你查看:
- 节点和资源。
- Job、Task、Actor。
- 对象引用和内存。
- 日志、错误、指标。
本教程后面的调试章节会用它定位常见问题。
控制面和数据面
分布式系统里常把“控制面”和“数据面”分开:
| 面向 | Ray 中的例子 | 关注点 |
|---|---|---|
| 控制面 | GCS、Raylet、调度、Worker lease | 谁运行、在哪里运行、资源是否足够 |
| 数据面 | Object Store、对象传输、序列化 | 结果和参数如何移动 |
这条分界很重要。很多性能问题不是“调度慢”,而是对象太大、依赖太碎、跨节点拉取太频繁。
一次任务从 Driver 到 Worker
这里有两个时间点要分清:
.remote()很快返回,它返回的是ObjectRef。ray.get()可能阻塞,因为它要等对象真正 ready。
Mini Ray 中如何对应
本教程的 Mini Ray 用单进程多线程模拟这些角色:
| 真实 Ray | Mini Ray 对应 |
|---|---|
| Driver | 运行 Demo 的主线程 |
| Core Worker | mini_ray.core.Runtime |
| Raylet / Scheduler | ResourceScheduler |
| Python Worker | ThreadPoolExecutor 里的线程 |
| Object Store | ObjectStore 字典加 Event |
| Actor Worker | 一个长期存活的 Actor 线程和队列 |
这个映射是学习用的。真实 Ray 的复杂性来自多进程、多节点、共享内存、网络通信和故障恢复。Mini Ray 把这些先去掉,让你看清核心控制流。完整的实现系列会在 mini-ray.llm101.moe 展开。