用 ray status 与 Ray State CLI/SDK 监控集群与应用状态
2026/9/20 22:52:37 网站建设 项目流程

用 ray status 与 Ray State CLI/SDK 监控集群与应用状态

【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray

导读

Ray 为监控和调试集群与应用状态提供了两条路径:一条是运行在 head 节点上的ray status命令,用于快速查看节点状态与资源使用;另一条是更强大的 Ray State API,通过 CLI 命令(ray summaryray listray getray logs)或 Python SDK 访问集群当前状态的快照,覆盖 Actors、Tasks、Objects、Nodes、Jobs、Placement Groups、Workers、Runtime Envs 等全部资源类型。读完本文,你将掌握如何使用这些命令定位节点无法缩容、任务长期未调度、Actor 异常等典型问题,并能从集群外部(VM 集群或 KubeRay)远程执行这些诊断命令。

一、ray status:集群节点与资源的一线观测

ray status需要在 head 节点上执行,它从 GCS(Global Control Service)中读取自动扩缩容器(autoscaler)维护的状态并打印出来。其底层实现在 python/ray/scripts/scripts.py 的status(address, verbose)函数中,通过gcs_client.internal_kv_get(ray_constants.DEBUG_AUTOSCALING_STATUS.encode())读取内部 KV 存储中由 autoscaler 周期性写入的状态字符串,再交给debug_status格式化输出(见 python/ray/scripts/scripts.py)。因此ray status反映的是 autoscaler 视角的集群状态。

它的输出分为两大块:

  • Node Status(节点状态):正在运行并参与扩缩容的节点、各节点的地址、Pending(等待中)节点和最近失败的节点。
  • Resource Usage(资源使用):整个集群的 Ray 资源用量,例如所有 Ray Task 与 Actor 请求的 CPU 数、已使用的 GPU 数、内存与 object store 内存占用。

典型输出如下:

$ ray status ======== Autoscaler status: 2021-10-12 13:10:21.035674 ======== Node status --------------------------------------------------------------- Healthy: 1 ray.head.default 2 ray.worker.cpu Pending: (no pending nodes) Recent failures: (no failures) Resources --------------------------------------------------------------- Usage: 0.0/10.0 CPU 0.00/70.437 GiB memory 0.00/10.306 GiB object_store_memory Demands: (no resource demands)

解读要点:

  • Healthy列出健康节点及其数量(本例为 1 个 head 节点和 2 个 CPU worker 节点);Pending列出正被云供应商创建、尚未注册到集群的节点;Recent failures给出最近创建/启动失败的节点及其原因。
  • Usage已用/总量的形式展示各类资源;Demands展示当前存在资源需求的 Task/Actor 请求(可用于判断集群是否需要扩容)。

当需要更详细的逐节点信息时,使用ray status -v

$ ray status -v

-v(verbose)模式会输出每个节点的详细信息,包括节点 IP、资源总量与可用量、标签等。文档特别指出,当你要排查"为什么某些节点没有自动缩容"这类问题时,-v模式非常有用——比如某个节点上有长时间存活的对象引用或未释放的资源,仅看汇总信息难以定位。

二、Ray State API 概览:CLI 与 Python SDK 的两种用法

除了ray status,Ray 还提供了一组 State API,用于访问集群当前状态(快照)。其中CLI 命令被标记为 stable(稳定),而 Python SDK 属于 Developer API(开发者 API),文档明确建议优先使用 CLI;两者底层走同一条 HTTP 通道——StateApiClient向 dashboard 的 API server 发起 REST GET 请求(见 python/ray/util/state/api.py)。

前置条件(原文档明确说明):

  • 需要完整安装 Ray:pip install "ray[default]"
  • 需要 dashboard 组件可用,即启动集群时包含 dashboard(ray startray.init()的默认行为就是如此)。若 API server 不可达,客户端会提示检查 dashboard 是否可用并确认依赖是否安装完整(见 python/ray/util/state/api.py)。

快速上手:准备一个示例应用

以下脚本会运行 2 个 Task 并创建 2 个 Actor(每个 Task 睡 300 秒,便于观察运行中状态):

import ray import time ray.init(num_cpus=4) @ray.remote def task_running_300_seconds(): time.sleep(300) @ray.remote class Actor: def __init__(self): pass # Create 2 tasks tasks = [task_running_300_seconds.remote() for _ in range(2)] # Create 2 actors actors = [Actor.remote() for _ in range(2)]

运行后稍等片刻(让 Task 完成提交),即可用下面的命令观察状态。如果命令没有立刻返回输出,重试一次即可。

查看 Task 汇总

ray summary tasks

输出示例:

======== Tasks Summary: 2022-07-22 08:54:38.332537 ======== Stats: ------------------------------------ total_actor_scheduled: 2 total_actor_tasks: 0 total_tasks: 2 Table (group by func_name): ------------------------------------ FUNC_OR_CLASS_NAME STATE_COUNTS TYPE 0 task_running_300_seconds RUNNING: 2 NORMAL_TASK 1 Actor.__init__ FINISHED: 2 ACTOR_CREATION_TASK

Python SDK 等价写法:

from ray.util.state import summarize_tasks print(summarize_tasks())

返回的字典中,cluster.summaryfunc_or_class_name分组,state_counts统计各状态下的数量;同时给出total_taskstotal_actor_taskstotal_actor_scheduled等全局统计。

列出所有 Actor

ray list actors

输出示例:

======== List: 2022-07-23 21:29:39.323925 ======== Stats: ------------------------------ Total: 2 Table: ------------------------------ ACTOR_ID CLASS_NAME NAME PID STATE 0 31405554844820381c2f0f8501000000 Actor 96956 ALIVE 1 f36758a9f8871a9ca993b1d201000000 Actor 96955 ALIVE

Python SDK 等价写法:

from ray.util.state import list_actors print(list_actors())

返回的是ActorState对象列表,包含actor_idclass_namestatejob_idnamenode_idpidray_namespaceserialized_runtime_envrequired_resourcesdeath_causeis_detachedplacement_group_idrepr_name等字段。

获取单个 Actor 的详细状态

# 在本例中,ACTOR_ID 为 31405554844820381c2f0f8501000000 ray get actors <ACTOR_ID>

输出示例(YAML 格式):

--- actor_id: 31405554844820381c2f0f8501000000 class_name: Actor death_cause: null is_detached: false name: '' pid: 96956 resource_mapping: [] serialized_runtime_env: '{}' state: ALIVE

Python SDK 等价写法:

from ray.util.state import get_actor print(get_actor(id=<ACTOR_ID>))

读取 Actor 日志

ray list actors # 在本例中,ACTOR_ID 为 31405554844820381c2f0f8501000000 ray logs actor --id <ACTOR_ID>

输出示例:

--- Log has been truncated to last 1000 lines. Use `--tail` flag to toggle. --- :actor_name:Actor Actor created

Python SDK 等价写法:

from ray.util.state import get_log for line in get_log(actor_id=<ACTOR_ID>): print(line)

注意输出顶部提示:日志默认截断为最后 1000 行,可通过--tail标志调整(对应 SDK 参数tail-1表示获取完整日志,默认常量DEFAULT_LOG_LIMIT = 1000,见 python/ray/util/state/common.py)。

三、核心概念:states、resources 与四类 API

理解 Ray State API,先掌握三组名词:

  • states(状态):对应资源的集群状态。状态由不可变元数据(如 Actor 的 name)和可变状态(如 Actor 的调度状态或 pid)组成。
  • resources(资源):由 Ray 创建的对象,例如 actors、tasks、objects、placement groups 等。
  • 四类 API:
    • summary:返回资源的汇总视图(例如按函数名分组的任务数量);
    • list:返回资源的每一个实体(逐条列出,支持过滤);
    • get:返回单个实体的详细信息(按 ID 查询);
    • logs:访问 Actor、Task、Worker 或系统日志文件的日志。

从实现看,StateResource枚举定义了全部可用资源类型:ACTORSJOBSPLACEMENT_GROUPSNODESWORKERSTASKSOBJECTSRUNTIME_ENVSCLUSTER_EVENTS;其中SummaryResource仅支持 actors、tasks、objects 三类(见 python/ray/util/state/common.py)。这也是为什么ray summary只有这三个子命令,而ray list/ray get覆盖更多资源。

CLI 与 SDK 的对应关系如下:

操作CLI 命令Python SDK
汇总ray summary actors/tasks/objectssummarize_actors()/summarize_tasks()/summarize_objects()
列出ray list <resource>list_actors()/list_tasks()/list_nodes()
单个查询ray get <resource> <ID>get_actor(id=...)/get_task(id=...)
日志ray logs ...get_log(...)/list_logs(...)

完整导出清单见 python/ray/util/state/init.py。CLI 的过滤、分页、输出格式等公共选项定义在 python/ray/util/state/state_cli.py 起的 click 选项中。

四、summary:按类型汇总资源状态

官方建议的监控起点是 summary API:先用它发现异常(例如长时间运行的 Actor、长时间未调度的 Task),再用listget深入定位某个异常的实体。

汇总所有 Actor

ray summary actors
from ray.util.state import summarize_actors print(summarize_actors())

输出示例:

{'cluster': {'summary': {'Actor': {'class_name': 'Actor', 'state_counts': {'ALIVE': 2}}}, 'total_actors': 2, 'summary_by': 'class'}}

汇总所有 Task

ray summary tasks
from ray.util.state import summarize_tasks print(summarize_tasks())

输出示例(与第一节示例一致,按func_name分组):

{'cluster': {'summary': {'task_running_300_seconds': {'func_or_class_name': 'task_running_300_seconds', 'type': 'NORMAL_TASK', 'state_counts': {'RUNNING': 2}}, 'Actor.__init__': {'func_or_class_name': 'Actor.__init__', 'type': 'ACTOR_CREATION_TASK', 'state_counts': {'FINISHED': 2}}}, 'total_tasks': 2, 'total_actor_tasks': 0, 'total_actor_scheduled': 2, 'summary_by': 'func_name'}}

汇总所有 Object

ray summary objects
from ray.util.state import summarize_objects print(summarize_objects())

注意:默认情况下 Object 按 callsite(调用点)汇总,但 Ray 默认并不记录 callsite。要获得调用点信息,需要在启动集群时设置环境变量RAY_record_ref_creation_sites=1

RAY_record_ref_creation_sites=1 ray start --head

未开启 callsite 时的输出中会出现'callsite_enabled': False与按'disabled'归组的统计(total_objectstotal_size_mbtotal_num_workerstotal_num_nodestask_state_countsref_type_counts)。

五、list:按类型列出所有实体(支持过滤)

ray list返回某类资源的完整列表。可列出的资源包括:

  • Actors:Actor ID、State、PID、death_cause(输出 schema 为ActorState);
  • Tasks:名称、调度状态、类型、runtime env 信息(TaskState);
  • Objects:object ID、callsite、引用类型(ObjectState);
  • Jobs:开始/结束时间、entrypoint、状态(JobState);
  • Placement Groups:名称、bundles、统计(PlacementGroupState);
  • Nodes(Ray worker 节点):node ID、node IP、节点状态(NodeState);
  • Workers(Ray worker 进程):worker ID、类型、退出类型与详情(WorkerState);
  • Runtime environments:runtime env、创建时间、所在节点(RuntimeEnvState)。

这些数据类 schema 统一定义在 python/ray/util/state/common.py 中,CLI 的表格列即按这些 dataclass 字段顺序生成(见 python/ray/util/state/state_cli.py)。

列出所有节点

ray list nodes
from ray.util.state import list_nodes list_nodes()

列出所有 Placement Group

ray list placement-groups
from ray.util.state import list_placement_groups list_placement_groups()

注意 CLI 中资源名使用连字符(placement-groups),而 SDK 中为下划线(placement_groups),这是_get_available_resources中做_-替换的结果(见 python/ray/util/state/state_cli.py)。

按条件过滤:--filter/-f

listAPI 支持一个或多个过滤条件,CLI 使用-f/--filter,SDK 使用filters参数(元素为(key, predicate, value)三元组,predicate 支持=!=)。

列出某进程创建的本地引用对象:

ray list objects -f pid=<PID> -f reference_type=LOCAL_REFERENCE
from ray.util.state import list_objects list_objects(filters=[("pid", "=", 1234), ("reference_type", "=", "LOCAL_REFERENCE")])

列出存活 Actor:

ray list actors -f state=ALIVE
from ray.util.state import list_actors list_actors(filters=[("state", "=", "ALIVE")])

列出运行中的 Task:

ray list tasks -f state=RUNNING
from ray.util.state import list_tasks list_tasks(filters=[("state", "=", "RUNNING")])

列出非运行状态的 Task(不等于):

ray list tasks -f state!=RUNNING
from ray.util.state import list_tasks list_tasks(filters=[("state", "!=", "RUNNING")])

组合条件:列出名为指定函数名、且正在运行的 Task:

ray list tasks -f state=RUNNING -f name="task_running_300_seconds()"
from ray.util.state import list_tasks list_tasks(filters=[("state", "=", "RUNNING"), ("name", "=", "task_running_300_seconds()")])

从源码看,CLI 的_parse_filter会解析key=valkey!=val两种形式(!后必须紧跟=,否则报格式错误),并在过滤前对 key 做大小写归一化(STATE=RUNNING也会被归一化为state=RUNNING);若 key 不在该资源的 schema 列中,会直接报错提示可用列名,而不是返回空结果(见 python/ray/util/state/state_cli.py)。SDK 侧,filters会被转换为filter_keysfilter_predicatesfilter_values三个查询参数(见 python/ray/util/state/api.py)。

列出更详细的 Task 信息(--detail):

指定--detail时,API 会查询更多的数据源以获取详细的状态信息:

ray list tasks --detail
from ray.util.state import list_tasks list_tasks(detail=True)

六、get:查询单个实体的详细状态

get按 ID 精确查询单个实体。

获取某个 Task 的状态:

ray get tasks <TASK_ID>
from ray.util.state import get_task get_task(id=<TASK_ID>)

获取某个节点的状态:

ray get nodes <NODE_ID>
from ray.util.state import get_node get_node(id=<NODE_ID>)

实现细节上,get并不是单独的查询通道:客户端会把id转换成对应的过滤条件(如 nodes 用node_id、actors 用actor_id、tasks 用task_id)并强制detail=True后走 list 接口(见 python/ray/util/state/api.py)。注意并非所有资源都支持按 ID 查询——jobsruntime-envs目前不支持get(代码中RESOURCE_ID_KEY_NAME未包含这两者时会抛出ValueError)。此外,一个 task_id 可能对应多次重试产生的多个 attempt,此时get会返回列表而非单个对象。

七、logs:获取与流式跟踪日志

State API 还允许访问 Ray 日志。使用约束如下:

  • 无法从已死亡的节点读取日志
  • 默认从head 节点打印日志(CLI 与 SDK 行为一致)。

列出 head 节点上所有可获取的日志文件名

ray logs cluster
from ray.util.state import list_logs # 与 CLI 的默认行为对齐,需要显式传入 head 节点 ID list_logs(node_id=<HEAD_NODE_ID>)

head 节点 ID 可从ray list nodes的输出中获得。

获取某个节点上的特定日志文件

# 先从 `ray list nodes` 获取节点 ID / 节点 IP ray logs cluster gcs_server.out --node-id <NODE_ID> # `ray logs cluster` 在使用 glob 查询时是 `ray logs` 的别名 ray logs gcs_server.out --node-id <NODE_ID>
from ray.util.state import get_log # Node IP 可从 list_nodes() 或 ray.nodes() 获取 for line in get_log(filename="gcs_server.out", node_id=<NODE_ID>): print(line)

流式跟踪某个日志文件

# 先从 `ray list nodes` 获取节点 ID / 节点 IP ray logs raylet.out --node-ip <NODE_IP> --follow # 或者, ray logs cluster raylet.out --node-ip <NODE_IP> --follow
from ray.util.state import get_log # Node IP 可从 list_nodes() 或 ray.nodes() 获取 # 循环在 follow=True 时会阻塞并持续输出新日志 for line in get_log(filename="raylet.out", node_ip=<NODE_IP>, follow=True): print(line)

按 Actor ID 流式跟踪 Actor 日志

ray logs actor --id=<ACTOR_ID> --follow
from ray.util.state import get_log # Actor ID 可从 `ray list actors` 的输出获取 # 循环在 follow=True 时会阻塞并持续输出新日志 for line in get_log(actor_id=<ACTOR_ID>, follow=True): print(line)

按 PID 流式跟踪 Worker 日志

ray logs worker --pid=<PID> --follow
from ray.util.state import get_log # Node IP 可从 list_nodes() 或 ray.nodes() 获取 # 当 worker 的输出被定向到 driver(默认行为)时,很容易从中拿到运行 Actor 的 PID # 循环在 follow=True 时会阻塞并持续输出新日志 for line in get_log(pid=<PID>, node_ip=<NODE_IP>, follow=True): print(line)

从 SDK 签名可以看到get_log支持的全部查询维度与选项:node_id/node_ip/filename(相对 Ray 日志目录的文件名)/actor_id/task_id/pid(按 pid 查询时必须同时提供 node_id 或 node_ip)/follow(流式)/tail(-1 表示全部)/timeout/suffix(按 ID 查询时默认 "out")/encoding/errors/submission_id/attempt_number(按 task 查询时指定尝试次数)/filter_ansi_code(是否过滤 ANSI 转义码)等(见 python/ray/util/state/api.py)。需要留意:对于 concurrent actor,应按actor_id查询日志而非task_id

八、失败语义:State API 的可靠性边界

State API不保证任何时候都返回一致、完整的集群快照。默认情况下,所有 Python SDK 在输出缺失时会抛出异常,而 CLI 返回部分结果并给出警告信息。以下三类情况可能造成输出缺失:

查询失败(Query Failures)

State API 会查询多个"数据源"(如 GCS、raylet 等)来构建集群快照。当某个数据源不可用(宕机或过载)时,API 返回部分(不完整)快照,并通过警告消息告知输出不完整。所有警告通过 Python 的warnings库打印,可以被抑制。在 SDK 侧,raise_on_missing_output=True(默认)时遇到部分失败会抛出RayStateApiException,可显式设为False允许缺失输出(见 python/ray/util/state/api.py)。

数据截断(Data Truncation)

当返回的实体数量过大(超过约 10 万条)时,API 会截断输出数据以保障系统稳定性(截断发生时用户无法选择保留哪些数据)。触发截断时会通过 Python 的warnings模块提示。截断与限流的默认阈值由环境变量控制:RAY_MAX_LIMIT_FROM_API_SOURCE(API server 到客户端的最大条目数,默认 10000)与RAY_MAX_LIMIT_FROM_DATA_SOURCE(数据源如 raylet 处的截断阈值,默认 10000),相关常量定义见 python/ray/util/state/common.py。此外客户端默认limit为 100(DEFAULT_LIMIT),返回条目数超限时同样会给出"使用--filter缩小范围或调高--limit"的提示。

已垃圾回收的资源(Garbage Collected Resources)

取决于资源生命周期,部分"已结束(finished)"的资源因为已被垃圾回收而无法通过 API 访问。不要依赖该 API 获取已结束资源的准确信息。例如 Ray 会周期性垃圾回收 DEAD 状态 Actor 的数据以降低内存占用;当 Task 的血缘(lineage)超出作用域时,也会清理其 FINISHED 状态。

九、在集群外部使用 Ray CLI 工具

上述 CLI 命令必须在 Ray 集群内的节点上执行。若需要从集群外部的机器执行,可按部署方式选择以下方案。

VM 集群(Cluster Launcher)

使用ray exec在集群上执行命令:

$ ray exec <cluster config file> "ray status"

KubeRay

使用kubectl exec与配置的 RayCluster 名称执行命令。Ray 使用指向 Ray head pod 的 Service 在集群上执行 CLI 命令:

# 首先,找到 Ray head service 的名称。 $ kubectl get pod | grep <RayCluster name>-head # NAME READY STATUS RESTARTS AGE # <RayCluster name>-head-xxxxx 2/2 Running 0 XXs # 然后,使用 Ray head service 的名称执行 `ray status`。 $ kubectl exec <RayCluster name>-head-xxxxx -- ray status

同理,ray summaryray listray getray logs等命令也可以这样在集群外部执行——这为把监控诊断能力集成到 CI、运维脚本或远程排障流程中提供了标准通道。

十、进一步参考

  • State CLI 命令完整参考(ray summary/ray list/ray get的所有参数与输出格式):doc/source/ray-observability/reference/cli.rst
  • State SDK(Python API)完整参考:ray.util.state模块下各函数文档与StateApiClient,见 doc/source/ray-observability/reference/api.rst
  • Log CLI 参考:ray logs子命令参数,见 doc/source/ray-observability/reference/cli.rst
  • SDK 核心实现:客户端与查询逻辑在 python/ray/util/state/api.py,CLI 命令定义与输出格式化在 python/ray/util/state/state_cli.py,资源枚举、schema 与默认阈值常量在 python/ray/util/state/common.py
  • 输出格式支持default(表格)、jsonyamltable四种,可通过 CLI 的--format选项指定(见 python/ray/util/state/state_cli.py),便于在脚本中做程序化解析

小结:推荐的问题排查路径

把本节内容串成一条可落地的排障流程:先在 head 节点执行ray status观察集群整体健康度与资源水位;发现异常后,用ray summary actors/tasks/objects定位是哪一类资源、哪个函数/类出了问题;再用带-f过滤条件的ray list缩小到具体实体(例如-f state=RUNNING-f state!=RUNNING);接着用ray get <resource> <ID>查看单个实体的完整字段(如 Actor 的death_cause、Task 的状态与尝试信息);最后用ray logs拉取或--follow流式跟踪相关 Actor/Worker/系统日志。整个过程既可以在集群内直接执行,也可以通过ray execkubectl exec从集群外部发起。

【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询