使用 Ray Jobs CLI 快速入门#

本指南详细介绍了用于提交和与 Ray Job 交互的 Ray Jobs CLI 命令。

要以编程方式使用 Python SDK 而不是 CLI 来使用 Jobs API,请参阅 Python SDK 概述

设置#

Ray Jobs 在 1.9 及以上版本中可用,并需要完整安装 Ray。你可以通过运行以下命令来安装 Ray:

pip install "ray[default]"

有关安装 Ray 的更多详细信息,请参阅 安装指南

要提交作业,您需要向 Ray 集群发送 HTTP 请求。本指南假设您使用的是本地 Ray 集群,您可以通过运行以下命令启动它:

ray start --head
# ...
# 2022-08-10 09:54:57,664   INFO services.py:1476 -- View the Ray dashboard at http://127.0.0.1:8265
# ...

此命令在本地机器上创建一个 Ray 头节点,您可以将其用于开发目的。注意在启动或连接到 Ray 集群时出现在 stdout 上的 Ray 仪表板 URL。稍后使用此 URL 提交作业。有关生产部署场景的更多详细信息,请参阅在 虚拟机Kubernetes 上部署 Ray 的指南。

提交作业#

从一个可以在本地运行的示例脚本开始。以下脚本使用 Ray API 提交任务并打印其返回值:

# script.py
import ray

@ray.remote
def hello_world():
    return "hello world"

# Automatically connect to the running Ray cluster.
ray.init()
print(ray.get(hello_world.remote()))

创建一个空的工目录,并在其中包含一个名为 script.py 的文件,文件内容为上述的 Python 脚本。

| your_working_directory
| ├── script.py

接下来,找到可以提交作业请求的 Ray 集群的 HTTP 地址。将作业提交到与 Ray 仪表板 使用的相同地址。默认情况下,此作业使用端口 8265。

如果你使用的是本地 Ray 集群(ray start --head),直接连接到 http://127.0.0.1:8265。如果你使用的是在虚拟机或 Kubernetes 上启动的 Ray 集群,请按照那里的指示设置从客户端的网络访问。查看 使用远程集群 获取提示。

要告诉 Ray Jobs CLI 如何找到您的 Ray 集群,请传递 Ray Dashboard 地址。设置 RAY_ADDRESS 环境变量:

$ export RAY_ADDRESS="http://127.0.0.1:8265"

或者,您也可以将 --address=http://127.0.0.1:8265 标志明确传递给每个 Ray Jobs CLI 命令,或者在每个命令前加上 RAY_ADDRESS=http://127.0.0.1:8265

此外,如果您希望为每个HTTP请求传递标头到集群,请使用 RAY_JOB_HEADERS 环境变量。此环境变量必须为JSON格式。

$ export RAY_JOB_HEADERS='{"KEY": "VALUE"}'

要提交作业,请使用 ray job submit。确保在 --working-dir 参数中指定工作目录的路径。对于本地集群,此参数并非严格必要,但对于远程集群,此参数是必需的,以便将工作目录上传到集群。

$ ray job submit --working-dir your_working_directory -- python script.py

# Job submission server address: http://127.0.0.1:8265

# -------------------------------------------------------
# Job 'raysubmit_inB2ViQuE29aZRJ5' submitted successfully
# -------------------------------------------------------

# Next steps
#   Query the logs of the job:
#     ray job logs raysubmit_inB2ViQuE29aZRJ5
#   Query the status of the job:
#     ray job status raysubmit_inB2ViQuE29aZRJ5
#   Request the job to be stopped:
#     ray job stop raysubmit_inB2ViQuE29aZRJ5

# Tailing logs until the job exits (disable with --no-wait):
# hello world

# ------------------------------------------
# Job 'raysubmit_inB2ViQuE29aZRJ5' succeeded
# ------------------------------------------

此命令在 Ray 集群的头节点上运行入口脚本,并等待作业完成。请注意,它还会将入口脚本的 stdoutstderr 流回客户端(在本例中为 hello world)。Ray 还通过将作为 --working-dir 传递的目录内容下载到集群中的所有节点,使其对 Ray 作业可用。

备注

双破折号 (--) 用于分隔入口命令的参数(例如,python script.py --arg1=val1)与 ray job submit 的参数。

备注

默认情况下,入口脚本在头节点上运行。要覆盖此行为,请在 ray job submit 命令中指定 --entrypoint-num-cpus--entrypoint-num-gpus--entrypoint-resources--entrypoint-memory 参数之一。有关更多详细信息,请参阅 指定 CPU 和 GPU 资源

与长时间运行的作业交互#

对于长时间运行的应用程序,您可能不希望客户端等待作业完成。为此,请将 --no-wait 标志传递给 ray job submit,并使用其他 CLI 命令来检查作业的状态。尝试这个修改后的脚本,该脚本在无限循环中每秒提交一个任务:

# script.py
import ray
import time

@ray.remote
def hello_world():
    return "hello world"

ray.init()
while True:
    print(ray.get(hello_world.remote()))
    time.sleep(1)

现在提交任务:

$ ray job submit --no-wait --working-dir your_working_directory -- python script.py
# Job submission server address: http://127.0.0.1:8265

# -------------------------------------------------------
# Job 'raysubmit_tUAuCKubPAEXh6CW' submitted successfully
# -------------------------------------------------------

# Next steps
#   Query the logs of the job:
#       ray job logs raysubmit_tUAuCKubPAEXh6CW
#   Query the status of the job:
#       ray job status raysubmit_tUAuCKubPAEXh6CW
#   Request the job to be stopped:
#       ray job stop raysubmit_tUAuCKubPAEXh6CW

我们可以稍后使用提供的 ray job logs 命令获取标准输出:

$ ray job logs raysubmit_tUAuCKubPAEXh6CW
# Job submission server address: http://127.0.0.1:8265
# hello world
# hello world
# hello world
# hello world
# hello world

使用 ray job status 获取作业的当前状态:

$ ray job status raysubmit_tUAuCKubPAEXh6CW
# Job submission server address: http://127.0.0.1:8265
# Status for job 'raysubmit_tUAuCKubPAEXh6CW': RUNNING
# Status message: Job is currently running.

最后,要取消作业,请使用 ray job stop:

$ ray job stop raysubmit_tUAuCKubPAEXh6CW
# Job submission server address: http://127.0.0.1:8265
# Attempting to stop job raysubmit_tUAuCKubPAEXh6CW
# Waiting for job 'raysubmit_tUAuCKubPAEXh6CW' to exit (disable with --no-wait):
# Job 'raysubmit_tUAuCKubPAEXh6CW' was stopped

$ ray job status raysubmit_tUAuCKubPAEXh6CW
# Job submission server address: http://127.0.0.1:8265
# Job 'raysubmit_tUAuCKubPAEXh6CW' was stopped

使用远程集群#

前面的示例是针对本地 Ray 集群的。当连接到 远程 集群时,您需要通过 HTTP 访问集群的仪表板端口。

访问端口的一种方式是将本地机器上的 127.0.0.1:8265 端口转发到头节点上的 127.0.0.1:8265。如果你使用 Ray 集群启动器 启动了远程集群,那么你可以使用 ray dashboard 命令设置自动端口转发。详情请参见 监控集群

在您的本地机器上运行以下命令,其中 cluster.yaml 是您用于启动集群的配置文件:

ray dashboard cluster.yaml

一旦此命令运行,验证您可以在本地浏览器中查看 Ray Dashboard,地址为 http://127.0.0.1:8265。同时,验证您已将环境变量 RAY_ADDRESS 设置为 "http://127.0.0.1:8265"。完成此设置后,您可以像前面的示例一样在本地机器上使用 Jobs CLI 与远程 Ray 集群进行交互。

在 Kubernetes 上使用 CLI#

前面的说明仍然适用,但你可以使用 kubectl port-forward 实现仪表盘端口转发:https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/

或者,您可以通过HTTP设置Ingress到集群的仪表板端口:https://kubernetes.io/docs/concepts/services-networking/ingress/

依赖管理#

要运行分布式应用程序,请确保所有工作节点在相同的环境中运行。如果同一 Ray 集群中的多个应用程序具有不同且冲突的依赖项,这种配置可能会很具有挑战性。

为了避免依赖冲突,Ray 提供了一个称为 运行时环境 的机制。运行时环境允许应用程序覆盖 Ray 集群上的默认环境,并在一个隔离的环境中运行,类似于单节点 Python 中的虚拟环境。依赖项可以包括文件和 Python 包。

Ray Jobs API 提供了一个选项,在提交作业时指定运行时环境。在 Ray 集群上,Ray 会在所有工作节点上安装运行时环境,并确保该作业中的任务在相同的环境中运行。为了演示此功能,此 Python 脚本在 Ray 任务中打印 requests 模块的当前版本。

import ray
import requests

@ray.remote
def get_requests_version():
    return requests.__version__

# Note: No need to specify the runtime_env in ray.init() in the driver script.
ray.init()
print("requests version:", ray.get(get_requests_version.remote()))

使用默认环境提交此作业。此环境是您启动 Ray 集群的环境。

$ ray job submit -- python script.py
# Job submission server address: http://127.0.0.1:8265
#
# -------------------------------------------------------
# Job 'raysubmit_seQk3L4nYWcUBwXD' submitted successfully
# -------------------------------------------------------
#
# Next steps
#   Query the logs of the job:
#     ray job logs raysubmit_seQk3L4nYWcUBwXD
#   Query the status of the job:
#     ray job status raysubmit_seQk3L4nYWcUBwXD
#   Request the job to be stopped:
#     ray job stop raysubmit_seQk3L4nYWcUBwXD
#
# Tailing logs until the job exits (disable with --no-wait):
# requests version: 2.28.1
#
# ------------------------------------------
# Job 'raysubmit_seQk3L4nYWcUBwXD' succeeded
# ------------------------------------------

现在使用一个固定 requests 模块版本的运行时环境提交任务:

$ ray job submit --runtime-env-json='{"pip": ["requests==2.26.0"]}' -- python script.py
# Job submission server address: http://127.0.0.1:8265

# -------------------------------------------------------
# Job 'raysubmit_vGGV4MiP9rYkYUnb' submitted successfully
# -------------------------------------------------------

# Next steps
#   Query the logs of the job:
#     ray job logs raysubmit_vGGV4MiP9rYkYUnb
#   Query the status of the job:
#     ray job status raysubmit_vGGV4MiP9rYkYUnb
#   Request the job to be stopped:
#     ray job stop raysubmit_vGGV4MiP9rYkYUnb

# Tailing logs until the job exits (disable with --no-wait):
# requests version: 2.26.0

# ------------------------------------------
# Job 'raysubmit_vGGV4MiP9rYkYUnb' succeeded
# ------------------------------------------

备注

如果Driver和Job都指定了运行时环境,Ray会尝试合并它们,如果它们冲突则抛出异常。更多详情请参见 运行时环境