dbray使用手册
dbray 面向开发机用户让用户支持使用dbray 来提交ray 任务,并且支持将本地 Ray 任务提交到 DataBuilder 远端 Ray 集群,利用共享 PFS 存储资源执行任务。
什么是dbray
dbray 是开发机上提交 Ray 任务到 DataBuilder 远端 Ray 集群的命令行工具。
表格概括它和原生 ray job submit 的差异:
| 维度 | 原生 ray job submit |
dbray job submit |
|---|---|---|
| 集群地址 | 需手动输入 --address http://...:8265 |
通过 --compute-id 自动从平台获取 |
| 鉴权 | 无 | DataBuilder 统一权限校验(compute_id 无权限时请求将被直接拒绝) |
| working_dir | 压缩后上传至 GCS 等远端对象存储,任务启动时自动下载并解压 | 1. 可通过 共享 PFS 不打包不上传,worker 直接使用本地PFS挂载路径 2. 可通过 BOS 上传任务包,worker 直接使用本地路径 |
| env_vars | 由用户自行配置 | 集中渲染并自动注入 |
| 子命令 | submit / status / logs / stop / list |
行为对齐 |
快速使用案例:
1cd /pfs/<...>/my-project # cd 到 PFS 上你正在开发的代码目录
2dbray job submit --config-file ~/.dbray/dbray.yaml -- python train.py
前提条件
满足以下所有条件,否则 dbray 无法工作
- 需持有一对 BCE AK/SK(长期或 STS 临时凭证均可)
- 需持有一个 具有权限 的
compute_id(在 DataBuilder 控制台分配的计算资源;如果没权限提交任务会被平台拒绝)
使用以下命令确认环境是否就绪:
1dbray --help # 1) dbray CLI 在 PATH
2python3 -c "from ray.runtime_env import RuntimeEnv; \
3 RuntimeEnv(working_dir='/tmp', working_dir_shared=True)" # 2) ray 补丁已装
快速开始
1.准备dbray凭证
绿色部分配置为必填项
1mkdir -p ~/.dbray && chmod 700 ~/.dbray
2cat > ~/.dbray/dbray.yaml <<EOF
3workspace_id: <your-workspace-id> # 不配置的话默认使用开发机所在工作空间ID
4user_id: <your-user-id> # 选填 用于生成带有标识的submission_id
5compute_id: <your-compute-id> # ray实例ID
6
7credentials:
8 access_key: <your-bce-ak>
9 secret_key: <your-bce-sk>
10 session_token: "" # 没有可空置
11EOF
12chmod 600 ~/.dbray/dbray.yaml
字段说明:
workspace_id/compute_id用于标识连接目标;user_id仅作为提交记录的可读标签,不影响权限校验;credentials中填写 AK/SK,请确保其对应账号拥有 Ray 实例及任务运行所需权限。
2.使用PFS模式提交任务
dbray默认采用pfs模式,需要满足以下条件才能工作
满足以下所有条件,否则 dbray 的PFS模式无法工作
- 开发机已挂载 PFS(一般在
/pfs/<workspace>/...或/mnt/pfs/<...>,前缀因部署而异) - Ray实例与开发机挂载相同PFS实例, 同时保证挂载源路径和容器内路径相同
2.1 准备任务代码
准备需要提交的任务的代码
以下为使用PFS提交任务示例
1# 假设 /pfs/<your-workspace>/projects 是你的 PFS 工作目录
2mkdir -p /pfs/<your-workspace>/projects/hello-ray
3cd /pfs/<your-workspace>/projects/hello-ray
1cat > demo.py <<'PY'
2"""Ray 任务。"""
3import math, os, socket, time
4import ray
5
6
7@ray.remote
8def slow_sqrt(n: int) -> dict:
9 time.sleep(0.5)
10 return {"n": n, "sqrt": math.sqrt(n),
11 "host": socket.gethostname(), "pid": os.getpid()}
12
13
14def main():
15 user = os.environ.get("task_user_id", "<unknown>")
16 print(f"hello from dbray, user={user}, cwd={os.getcwd()}")
17
18 N = 8
19 print(f"[driver] dispatching {N} tasks...")
20 t0 = time.time()
21 results = ray.get([slow_sqrt.remote(i) for i in range(1, N + 1)])
22 print(f"[driver] done in {time.time() - t0:.2f}s")
23
24 for r in results:
25 print(f" n={r['n']:>2} sqrt={r['sqrt']:.4f} on {r['host']} pid={r['pid']}")
26 print(f"[driver] sum = {sum(r['sqrt'] for r in results):.4f}")
27
28
29if __name__ == "__main__":
30 main()
31PY
2.2 提交执行任务
1cd /pfs/<your-workspace>/projects/hello-ray
2dbray job submit --config-file ~/.dbray/dbray.yaml -- python demo.py
输出任务执行日志:
1Submitted: dbray-<your-user>-20260627T...-xxxxxx
2Dashboard: http://<ray-dashboard-host>:8265
3Logs: dbray job logs dbray-<...>-xxxxxx -f
4Stop: dbray job stop dbray-<...>-xxxxxx
5
6...job stdout streamed in real-time...
7hello from dbray, user=<your-user-id>, cwd=/pfs/<your-workspace>/projects/hello-ray
8[driver] dispatching 8 tasks...
9[driver] done in 0.78s
10 n= 1 sqrt=1.0000 on ray-cluster-...-head-xxxxx pid=12345
11 ...
12 n= 8 sqrt=2.8284 on ray-cluster-...-head-xxxxx pid=12351
13[driver] sum = 15.6066
14
15Final status: SUCCEEDED
3.使用BOS模式提交任务
bos模式为dbray的另外一种模式,通过压缩并上传任务到bos后提交任务,无需工作路径在pfs挂载路径下,可直接用任意的工作路径
满足以下所有条件,否则 dbray 的bos 模式无法工作
- 配置文件对应的AK/SK的用户至少是该开发机/计算实例所在工作空间的用户
3.1 准备任务代码
以下为使用BOS提交任务示例
1# 假设 /workspace/code 是你的本次工作目录
2mkdir -p /workspace/code
3cd /workspace/code
1cat > hello.py <<'PY'
2"""Ray 任务。"""
3import math, os, socket, time
4import ray
5
6
7@ray.remote
8def slow_sqrt(n: int) -> dict:
9 time.sleep(0.5)
10 return {"n": n, "sqrt": math.sqrt(n),
11 "host": socket.gethostname(), "pid": os.getpid()}
12
13
14def main():
15 user = os.environ.get("task_user_id", "<unknown>")
16 print(f"hello from dbray, user={user}, cwd={os.getcwd()}")
17
18 N = 8
19 print(f"[driver] dispatching {N} tasks...")
20 t0 = time.time()
21 results = ray.get([slow_sqrt.remote(i) for i in range(1, N + 1)])
22 print(f"[driver] done in {time.time() - t0:.2f}s")
23
24 for r in results:
25 print(f" n={r['n']:>2} sqrt={r['sqrt']:.4f} on {r['host']} pid={r['pid']}")
26 print(f"[driver] sum = {sum(r['sqrt'] for r in results):.4f}")
27
28if __name__ == "__main__":
29 main()
30PY
3.2 提交任务
需要使用bos模式 所以这里加上 --mode bos;
--working-dir 为刚刚的开发机本地文件夹 /workspace/code;
--python 为刚刚的新建的入口测试hello.py文件。
1dbray job submit --config-file ~/.dbray/dbray.yaml --mode bos --working-dir /workspace/code -- python hello.py
可以看到压缩工作文件夹后续自动上传到bos然后返回bos路径,最后提交任务到ray,输出结果:
12026-08-03 17:47:51,811 INFO Compressing working_dir.zip: 0% (0.0 B / 774.0 B)
22026-08-03 17:47:51,811 INFO Compressing working_dir.zip: 100% (774.0 B / 774.0 B)
32026-08-03 17:47:51,811 INFO Compressing working_dir.zip: 100% (774.0 B / 774.0 B)
42026-08-03 17:47:51,811 INFO Compression completed: working_dir.zip size=696.0 B sha256=6df667bf5b4fe6f5db64f8808bcd997a1da4b6e7aad9bf51d054f386a64bb8bd
52026-08-03 17:47:52,222 INFO Uploading working_dir.zip to BOS: 0% (0.0 B / 696.0 B)
62026-08-03 17:47:52,325 INFO Uploading working_dir.zip to BOS: 100% (696.0 B / 696.0 B)
72026-08-03 17:47:52,365 INFO Uploaded BOS object bos://databuilder-workflow-dev/workspaces/workspace_9862_0763f283d58a/dbray/dbray-bf848ed90b027df8/working_dir.zip, size=696, parts=1
82026-08-03 17:47:52,365 INFO BOS upload completed: bos://databuilder-workflow-dev/workspaces/workspace_9862_0763f283d58a/dbray/dbray-bf848ed90b027df8/working_dir.zip
9Submitted: dbray-84a3fc23829c4bb3b074712f84fe1ee3-20260803T094753-1ca885
10Dashboard: http://172.16.17.17:8265
11Logs: dbray job logs dbray-84a3fc23829c4bb3b074712f84fe1ee3-20260803T094753-1ca885 -f
12Stop: dbray job stop dbray-84a3fc23829c4bb3b074712f84fe1ee3-20260803T094753-1ca885
13
142026-08-03 17:47:53,214 INFO job_manager.py:579 -- Runtime env is setting up.
15Running entrypoint for job dbray-84a3fc23829c4bb3b074712f84fe1ee3-20260803T094753-1ca885: python hello.py
16hello from dbray, user=84a3fc23829c4bb3b074712f84fe1ee3, cwd=/tmp/ray/session_2026-07-31_18-40-56_040060_1/runtime_resources/working_dir_files/bos_databuilder-workflow-dev_workspaces_workspace_9862_0763f283d58a_dbray_dbray-bf848ed90b027df8_working_dir
17[driver] dispatching 8 tasks...
182026-08-03 17:47:55,817 INFO worker.py:1680 -- Using address 172.16.18.133:6379 set in the environment variable RAY_ADDRESS
192026-08-03 17:47:55,822 INFO worker.py:1821 -- Connecting to existing Ray cluster at address: 172.16.18.133:6379...
202026-08-03 17:47:55,832 INFO worker.py:1998 -- Connected to Ray cluster. View the dashboard at 172.16.18.133:8265
21/usr/local/lib/python3.10/dist-packages/ray/_private/worker.py:2046: FutureWarning: Tip: In future versions of Ray, Ray will no longer override accelerator visible devices env var if num_gpus=0 or num_gpus=None (default). To enable this behavior and turn off this error message, set RAY_ACCEL_ENV_VAR_OVERRIDE_ON_ZERO=0
22 warnings.warn(
23[driver] done in 2.78s
24 n= 1 sqrt=1.0000 on ray-cluster-compute-b655-a7b9d8b3662b-head-clg77 pid=1143437
25 n= 2 sqrt=1.4142 on ray-cluster-compute-b655-a7b9d8b3662b-head-clg77 pid=1143436
26 n= 3 sqrt=1.7321 on ray-cluster-compute-b655-a7b9d8b3662b-head-clg77 pid=1143435
27 n= 4 sqrt=2.0000 on ray-cluster-compute-b655-a7b9d8b3662b-head-clg77 pid=1143434
28 n= 5 sqrt=2.2361 on ray-cluster-compute-b655-a7b9d8b3662b-head-clg77 pid=1143438
29 n= 6 sqrt=2.4495 on ray-cluster-compute-b655-a7b9d8b3662b-head-clg77 pid=1143440
30 n= 7 sqrt=2.6458 on ray-cluster-compute-b655-a7b9d8b3662b-head-clg77 pid=1143441
31 n= 8 sqrt=2.8284 on ray-cluster-compute-b655-a7b9d8b3662b-head-clg77 pid=1143439
32[driver] sum = 16.3060
33
34Final status: SUCCEEDED
4.查看历史作业
提交完任意的任务后可以通过以下命令查看提交过的任务列表。
1# 看历史作业列表
2dbray job list --config-file ~/.dbray/dbray.yaml
配置凭证多种方式
以下提供三种配置方法,三选一即可;
dbray 的连接参数:workspace_id / compute_id / access_key / secret_key(外加可选的 user_id / session_token)。
三种渠道,按下列优先级解析,也就是同一个参数被多处定义时,最左边的胜出:
1CLI flag > 环境变量 > --config-file
1.配置文件方式
配置文件方式将数据写入固定的配置文件,一次写好,推荐日常使用。
每次 submit/status/logs/stop/list 都只需 --config-file <path>。
使用--config-file <path>指定该写入的配置文件以提交任务:
1dbray job submit --config-file ~/.dbray/dbray.yaml -- python demo.py
2dbray job logs <sid> --config-file ~/.dbray/dbray.yaml -f
3dbray job list --config-file ~/.dbray/dbray.yaml
1.1 YAML 嵌套写法
~/.dbray/dbray.yaml:
1workspace_id: workspace_9862_xxxxxxxxxxxx
2compute_id: compute_a7b2_xxxxxxxxxxxx
3user_id: alice
4
5credentials:
6 access_key: ALTAKxxxxxxxxxxxxxxxxxx
7 secret_key: xxxxxxxxxxxxxxxxxxxxxxxxxxx
8 session_token: ""
1.2 YAML 顶层平铺写法:
~/.dbray/dbray-flat.yaml,credentials 字段不嵌套:
1workspace_id: workspace_9862_xxxxxxxxxxxx
2compute_id: compute_a7b2_xxxxxxxxxxxx
3user_id: alice
4access_key: ALTAKxxxxxxxxxxxxxxxxxx
5secret_key: xxxxxxxxxxxxxxxxxxxxxxxxxxx
1.3 JSON 写法:
~/.dbray/dbray.json:
1{
2 "workspace_id": "workspace_9862_xxxxxxxxxxxx",
3 "compute_id": "compute_a7b2_xxxxxxxxxxxx",
4 "user_id": "alice",
5 "credentials": {
6 "access_key": "ALTAKxxxxxxxxxxxxxxxxxx",
7 "secret_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
8 "session_token": ""
9 }
10}
三种格式 dbray 都识别。chmod 600:里面有您的 AK/SK,不要让别人读到。
2.使用环境变量
1export DATABUILDER_WORKSPACE_ID=workspace_9862_xxxxxxxxxxxx
2export DBRAY_COMPUTE_ID=compute_a7b2_xxxxxxxxxxxx
3export DATABUILDER_ACCESS_KEY_ID=ALTAKxxxxxxxxxxxxxxxxxx
4export DATABUILDER_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxx
5# export DATABUILDER_SESSION_TOKEN=... # 可选
6
7dbray job submit -- python demo.py # 连接参数从 env 自动取
变量名映射:
| 字段 | 环境变量名 |
|---|---|
| workspace_id | DATABUILDER_WORKSPACE_ID 或 DBRAY_WORKSPACE_ID |
| compute_id | DBRAY_COMPUTE_ID |
| access_key | DATABUILDER_ACCESS_KEY_ID |
| secret_key | DATABUILDER_SECRET_ACCESS_KEY |
| session_token | DATABUILDER_SESSION_TOKEN |
| user_id | DBRAY_USER_ID |
开发机镜像通常已预置
DATABUILDER_WORKSPACE_ID,仅需额外配置 AK/SK 与compute_id即可。
3.显式指定变量
一次性 / 调试用:
1dbray job submit \
2 --workspace-id workspace_9862_xxxxxxxxxxxx \ # 可选 默认用开发机所在工作空间ID
3 --compute-id compute_a7b2_xxxxxxxxxxxx \
4 --access-key ALTAKxxxxxxxxxxxxxxxxxx \
5 --secret-key xxxxxxxxxxxxxxxxxxxxxxxxxxx \
6 -- python demo.py
三种方式的混合
dbray 允许混用,按优先级合并。最常见的两种组合:
1# 1) AK/SK 写文件,compute_id 命令行现场指定
2dbray job submit \
3 --config-file ~/.dbray/dbray.yaml \
4 --compute-id compute_OTHER_xxx \
5 -- python demo.py
6
7# 2) 整套从 env 拿,但临时换 compute_id
8DBRAY_COMPUTE_ID=compute_xxxx \
9 dbray job submit -- python demo.py
常用指令列表
dbray job 下有 6 个子命令,全部需要配置连接参数(按照配置方式三选一)。
1.submit 提交作业
1dbray job submit [连接参数] [可选项] -- <entrypoint> [args...] --mode xxx
-- 之后的内容会原样交给 Ray 作为作业 entrypoint,最常见就是 python xxx.py [...]。
可选项:
| 选项 | 默认 | 说明 |
|---|---|---|
--working-dir <abs path> |
$PWD |
worker 端 cwd(必须在 PFS 共享路径上) |
--runtime-env <file.yaml> |
— | 用户自己的 runtime_env 文件(py_modules / env_vars 等) |
--runtime-env-json '<json>' |
— | 用户自己的 runtime_env 内联 JSON;与 --runtime-env 同时给时叠加在文件之上(同 key 内联值胜出) |
--no-wait |
false | 立即返回,不阻塞等日志 |
--mode |
shared | 1. --mode bos 使用bos模式提交作业 2. --mode shared 使用pfs模式提交作业 是默认模式 |
默认行为:submit 后阻塞,把 worker stdout/stderr 实时 tail 到本地终端,作业终态时打印 Final status: SUCCEEDED/FAILED/STOPPED。Ctrl-C 中断 tail 不会停止远端作业。
stdout 格式:
1Submitted: dbray-<user>-<UTC-timestamp>-<6-hex-random>
2Dashboard: http://<ray-dashboard>:8265
3Logs: dbray job logs <sid> -f
4Stop: dbray job stop <sid>
5
6<job stdout streamed>
7...
8Final status: SUCCEEDED
第一行 Submitted: 后的 token 就是 submission_id;后续 logs / stop / status 都用它。
dbray job submit 支持多种使用方式,以下介绍常见的开发与调试场景,包括开发调试、批量调度、离线查看日志、终止作业、环境隔离和并发提交。
所有示例默认使用配置文件,也可根据前述配置方式自行选择。
1--config-file ~/.dbray/dbray.yaml
提交作业多种方式
1.阻塞模式
阻塞模式是开发调试的常用方式,也是 dbray 任务提交后的默认行为。
提交后命令会停留在当前终端,实时输出远端作业的 stdout 和 stderr,体验接近本地直接运行:
1dbray job submit --config-file ~/.dbray/dbray.yaml -- python demo.py
关键行为:
- 可以实时看到程序输出。
- Python 报错时可以直接看到 traceback。
- 按
Ctrl-C只会中断本地日志 tail,不会终止远端作业。 - 如果需要真正停止远端作业,请使用
dbray job stop <sid>
2.非阻塞模式
非阻塞模式适合脚本化提交、批处理调度和后台运行。加上 --no-wait 后,命令会在提交成功后立即返回 submission id。
1SID=$(dbray job submit --config-file ~/.dbray/dbray.yaml --no-wait \
2 -- python demo.py | awk '/^Submitted:/ {print $2}')
提交后可以继续执行其他任务,之后再查询状态或查看日志:
1sleep 60
2
3dbray job status "$SID" --config-file ~/.dbray/dbray.yaml
4dbray job logs "$SID" --config-file ~/.dbray/dbray.yaml
适用场景:
- CI/CD 或调度脚本中提交作业。
- 一次提交后立即返回,不阻塞当前 shell。
- 后续通过
status和logs主动查询作业状态。
3.提交后离线观察
使用 --no-wait 提交长任务后,可以关闭本地终端。终端关闭不会影响远端任务执行。
1dbray job submit --config-file ~/.dbray/dbray.yaml --no-wait -- python long_train.py
之后可以重新打开终端,通过 submission id 查看日志:
1dbray job logs <sid> --config-file ~/.dbray/dbray.yaml | less
说明:
- 远端作业生命周期不依赖本地终端。
logs可用于后续追踪输出。- 配合
less可以更方便地翻页查看长日志。
2.status 查询作业状态
1dbray job status <submission_id> [连接参数]
输出枚举之一:PENDING / RUNNING / SUCCEEDED / FAILED / STOPPED。
3.logs 获取作业日志
1dbray job logs <submission_id> [连接参数] [-f|--follow]
不带 -f 时一次性拉到当前日志;带 -f 时实时 tail 到作业结束(Ctrl-C 中断 tail 不会停作业)。
4.stop 停止作业
1dbray job stop <submission_id> [连接参数]
正常输出 stopped,作业转入 STOPPED 状态。已经 SUCCEEDED/FAILED 的作业 stop 是 no-op。
5.list 列出作业
1dbray job list [连接参数]
返回该 compute_id 下所有 ad-hoc 作业的 JSON 数组(按 ray dashboard 的 list_jobs 输出,出于安全考虑已做隐私处理:runtime_env 字段已移除,敏感元数据已替换为 "***")。
示例:
1[
2 {
3 "type": "SUBMISSION",
4 "submission_id": "dbray-alice-20260627T125345-63bd06",
5 "status": "SUCCEEDED",
6 "entrypoint": "python demo.py",
7 "message": "Job finished successfully.",
8 "start_time": 1782564835594,
9 "end_time": 1782564840321,
10 "metadata": {},
11 "driver_exit_code": 0
12 },
13 ...
14]
6.env_vars 合并语义规则
env_vars 会按 key 独立合并,不是整体替换。
合并优先级从低到高如下:
| 优先级 | 来源 | 说明 |
|---|---|---|
| 1 | DataBuilder 渲染的 env_vars |
包括 STS / DataBuilder / Catalog 相关变量 |
| 2 | dbray 默认环境变量 | 例如 PYTHONDONTWRITEBYTECODE=1 |
| 3 | --runtime-env 文件中的 env_vars |
项目级配置 |
| 4 | --runtime-env-json 内联 env_vars |
命令行临时覆盖,优先级最高 |
示例:
1--runtime-env-json '{"env_vars":{"X":"y"}}'
这只会设置或覆盖 X 这个 key,不会清空其他环境变量。
因此,即使用户只传了:
1{"env_vars":{"X":"y"}}
dbray / DataBuilder 注入的 STS 凭证、Catalog 信息等仍然会保留。
示例1:内联 JSON
1dbray job submit --config-file ~/.dbray/dbray.yaml \
2 --runtime-env-json '{"env_vars":{"MY_DEBUG_FLAG":"0"}}' \
3 -- python train.py
示例2:runtime_env 文件
my_env.yaml:
1env_vars:
2 MY_DEBUG_FLAG: "1"
提交作业时使用该配置文件:
1dbray job submit --config-file ~/.dbray/dbray.yaml \
2 --runtime-env ./my_env.yaml \
3 -- python train.py
示例3:文件与内联 JSON 叠加
runtime_env 文件作为基础配置,命令行内联 JSON 用于临时覆盖:
1dbray job submit --config-file ~/.dbray/dbray.yaml \
2 --runtime-env ./my_env.yaml \
3 --runtime-env-json '{"env_vars":{"MY_DEBUG_FLAG":"0"}}' \
4 -- python train.py
典型错误与排查
本节介绍常见报错的含义及处理方式,帮助您在使用过程中快速定位问题。
1.access_key is required
常见完整提示:
access_key is required: set --access-key, DATABUILDER_ACCESS_KEY_ID, or 'access_key' in --config-file.含义:
dbray没有拿到AK。- 同类报错也可能是
secret_key is required。
处理方式:
- 按第 4 节介绍的三种渠道,至少配置一种凭证来源。
- 检查
--access-key、DATABUILDER_ACCESS_KEY_ID、--config-file里的access_key是否真的生效。
2.403 Forbidden / AccessDenied / 暂无操作权限
常见提示:
403 Forbidden{"code":"AccessDenied","message":"暂无操作权限"}含义:
- 你的
AK/SK没有对应compute_id的USE权限。
常见原因:
compute_id不属于你的 workspace,可能是--compute-id写错了。- 你确实没有被授权,需要 workspace owner 处理。
处理方式:
- 先确认
--compute-id是否正确。 - 如果确认无误,联系 DataBuilder workspace owner 给你授权。
3.working_dir_shared path /xxx is not mounted on this worker
常见现象:
- 在作业 dashboard 上看到这条 message。
含义:
- worker 上看不到你通过
--working-dir指定的路径。
最常见原因:
- 你把工作目录放在了
/tmp/...、/home/...这类非 PFS 路径。 - PFS 挂载点在开发机和 worker 上不一致,例如开发机看到
/pfs/<ws>/proj,worker 看到/mnt/pfs/<ws>/proj。
处理方式:
- 把代码移到正确的 PFS 路径下。
- 重新
cd到该路径后再提交。 - 如果是挂载点路径不一致,请联系平台运维人员确认 PFS 挂载路径映射关系。
评价此篇文章
