在本地测试自动扩缩容#

测试自动扩缩容行为对于自动扩缩容器开发和依赖自动扩缩容器行为的应用程序的调试非常重要。您可以使用以下方法之一在本地运行自动扩缩容器,而无需启动真实的集群

使用 RAY_FAKE_CLUSTER=1 ray start#

说明

  1. 导航到您在本地克隆的 Ray 仓库的根目录。

  2. 找到 fake_multi_node/example.yaml 示例文件,并填写本地机器作为头节点类型的 CPU 和 GPU 数量。该 YAML 遵循与集群自动扩缩容配置相同的格式,但某些字段不受支持。

  3. 根据需要在 YAML 文件中配置 worker 类型和其他自动扩缩容配置。

  4. 在本地启动伪集群

$ ray stop --force
$ RAY_FAKE_CLUSTER=1 ray start \
    --autoscaling-config=./python/ray/autoscaler/_private/fake_multi_node/example.yaml \
    --head --block
  1. 使用 ray.init("auto") 将您的应用程序连接到本地伪集群。

  2. 运行 ray status 查看集群状态,或运行 cat /tmp/ray/session_latest/logs/monitor.* 查看自动扩缩容器监控日志

$ 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)

使用 ray.cluster_utils.AutoscalingCluster#

要以编程方式创建伪多节点自动扩缩容集群并连接到它,您可以使用 cluster_utils.AutoscalingCluster。以下是一个基本自动扩缩容测试的示例,该测试启动触发自动扩缩容的任务

cluster = AutoscalingCluster(
    head_resources={"CPU": 2},
    worker_node_types={
        "cpu_node": {
            "resources": {
                "CPU": 4,
                "object_store_memory": 1024 * 1024 * 1024,
            },
            "node_config": {},
            "min_workers": 0,
            "max_workers": 2,
        },
        "gpu_node": {
            "resources": {
                "CPU": 2,
                "GPU": 1,
                "object_store_memory": 1024 * 1024 * 1024,
            },
            "node_config": {},
            "min_workers": 0,
            "max_workers": 2,
        },
        "tpu_node": {
            "resources": {
                "CPU": 2,
                "TPU": 4,
                "object_store_memory": 1024 * 1024 * 1024,
            },
            "node_config": {},
            "min_workers": 0,
            "max_workers": 2,
        },
        "tpu_v5e_node": {
            "resources": {
                "CPU": 4,
                "TPU": 8,
                "object_store_memory": 1024 * 1024 * 1024,
            },
            "node_config": {},
            "min_workers": 0,
            "max_workers": 2,
        },
        "tpu_v6e_node": {
            "resources": {
                "CPU": 4,
                "TPU": 8,
                "object_store_memory": 1024 * 1024 * 1024,
            },
            "node_config": {},
            "min_workers": 0,
            "max_workers": 2,
        },
    },
    autoscaler_v2=autoscaler_v2,
)

try:
    cluster.start()
    ray.init("auto")

    # Triggers the addition of a GPU node.
    @ray.remote(num_gpus=1)
    def f():
        print("gpu ok")

    # Triggers the addition of a CPU node.
    @ray.remote(num_cpus=3)
    def g():
        print("cpu ok")

    # Triggers the addition of a TPU node.
    @ray.remote(resources={"TPU": 4})
    def h():
        print("tpu ok")

    # Triggers the addition of a 8-chip TPU node.
    @ray.remote(resources={"TPU": 8})
    def i():
        print("8-chip tpu ok")

    ray.get(f.remote())
    ray.get(g.remote())
    ray.get(h.remote())
    ray.get(i.remote())
    ray.shutdown()
finally:
    cluster.shutdown()

Python 文档

class ray.cluster_utils.AutoscalingCluster(head_resources: dict, worker_node_types: dict, autoscaler_v2: bool = False, **config_kwargs)[source]#

创建一个用于测试的本地自动扩缩容集群。

有关端到端示例,请参阅 test_autoscaler_fake_multinode.py。

开发者 API:此 API 在 Ray 的次要版本中可能会发生变化。

start(_system_config=None, override_env: Dict | None = None)[source]#

启动集群。

此调用返回后,您可以使用 ray.init(“auto”) 连接到集群。

shutdown()[source]#

终止集群。

fake_multinode 的特性和限制#

自动扩缩容器的大多数功能在伪多节点模式下都受到支持。例如,如果您更新 YAML 文件的内容,自动扩缩容器将拾取新配置并应用更改,就像在真实集群中一样。节点选择、启动和终止由与真实集群相同的 bin-packing 和空闲超时算法管理。

然而,存在一些限制

  1. 所有节点的 raylets 在本地机器上非容器化运行,因此它们共享相同的 IP 地址。有关替代的本地多节点设置,请参阅 fake_multinode_docker 部分。

  2. 不支持用于认证、设置、初始化、Ray 启动、文件同步以及任何云特定项的配置。

  3. 必须限制节点数量 / 节点 CPU / 对象存储内存,以避免本地机器过载。

使用 Docker compose 在本地测试容器化多节点#

为了更进一步,并在本地测试每个节点使用自己的容器(从而拥有独立的 文件系统、IP 地址和 Ray 进程)的多节点设置,您可以使用 fake_multinode_docker 节点提供程序。

设置与 fake_multinode 提供程序非常相似。但是,您需要启动一个监控进程 (docker_monitor.py),该进程负责运行 docker compose 命令。

前提条件

  1. 确保已安装 docker

  2. 确保已安装 docker compose V2 插件

使用 RAY_FAKE_CLUSTER=1 ray up#

说明

  1. 导航到您在本地克隆的 Ray 仓库的根目录。

  2. 找到 fake_multi_node/example_docker.yaml 示例文件,并填写本地机器作为头节点类型的 CPU 和 GPU 数量。该 YAML 遵循与集群自动扩缩容配置相同的格式,但某些字段不受支持。

  3. 根据需要在 YAML 文件中配置 worker 类型和其他自动扩缩容配置。

  4. 确保主机系统上的 shared_volume_dir 为空

  5. 启动监控进程

$ python ./python/ray/autoscaler/_private/fake_multi_node/docker_monitor.py \
    ./python/ray/autoscaler/_private/fake_multi_node/example_docker.yaml
  1. 使用 ray up 启动 Ray 集群

$ RAY_FAKE_CLUSTER=1 ray up -y ./python/ray/autoscaler/_private/fake_multi_node/example_docker.yaml
  1. 使用 ray.init("ray://localhost:10002") 将您的应用程序连接到本地伪集群。

  2. 或者,在头节点上获取 shell

$ docker exec -it fake_docker_fffffffffffffffffffffffffffffffffffffffffffffffffff00000_1 bash

使用 ray.autoscaler._private.fake_multi_node.test_utils.DockerCluster#

此工具用于编写使用多节点行为的测试。可以使用 DockerCluster 类在临时目录中设置 Docker-compose 集群,启动监控进程,等待集群启动,连接到它,并更新配置。

请参阅 API 文档和示例测试用例,了解如何使用此工具。

class ray.autoscaler._private.fake_multi_node.test_utils.DockerCluster(config: Dict[str, Any] | None = None)[source]#

Docker 集群包装器。

创建一个用于启动伪多节点 docker 集群的目录。

包含用于在测试中根据需要更新集群配置以及启动和连接集群的 API。

connect(client: bool = True, timeout: int = 120, **init_kwargs)[source]#

连接到 docker-compose Ray 集群。

假定集群位于 RAY_TESTHOST(默认为 127.0.0.1)。

参数:
  • client – 如果为 True,则使用 Ray client 连接到集群。如果为 False,则使用 GCS 连接到集群。

  • timeout – 连接超时时间,单位为秒。

  • **init_kwargs – 要传递给 ray.init() 的 kwargs 参数。

remote_execution_api() RemoteAPI[source]#

创建一个对象,用于在集群内部控制集群状态。

static wait_for_resources(resources: Dict[str, float], timeout: int = 60)[source]#

等待 Ray 集群资源可用

参数:
  • resources – 此函数返回前所需的最低资源。

  • timeout – 超时时间,单位为秒。

update_config(config: Dict[str, Any] | None = None)[source]#

更新自动扩缩容配置。

对基础配置进行深度更新,使用新配置覆盖。这可以改变自动扩缩容行为。

参数:

config – 用于更新当前配置的部分配置。

setup()[source]#

设置 docker compose 集群环境。

创建临时目录,写入初始配置文件,并在需要时拉取 docker 镜像。

teardown(keep_dir: bool = False)[source]#

拆除 docker compose 集群环境。

参数:

keep_dir – 如果为 True,集群目录在终止后不会被移除。

start()[source]#

启动 docker compose 集群。

启动监控进程并运行 ray up

stop()[source]#

停止 docker compose 集群。

运行 ray down 并停止监控进程。

kill_node(node_id: str | None = None, num: int | None = None, rand: str | None = None)[source]#

杀死节点。

如果给出 node_id,则杀死该节点。

如果给出 num,则从该数字构造 node_id,并杀死该节点。

如果给出 rand(作为 workerany),则杀死一个随机节点。

fake_multinode_docker 的特性和限制#

伪多节点 docker 节点提供程序在自己的容器中提供完整的节点。但是,仍然存在一些限制

  1. 不支持用于认证、设置、初始化、Ray 启动、文件同步以及任何云特定项的配置(但将来可能会支持)。

  2. 必须限制节点数量 / 节点 CPU / 对象存储内存,以避免本地机器过载。

  3. 在 docker-in-docker 设置中,必须遵循仔细的设置才能使伪多节点 docker 提供程序工作(见下文)。

docker 环境中的共享目录#

容器将挂载两个位置到主机存储

  • /cluster/node:此位置(在容器中)将指向 cluster_dir/nodes/<node_id>(在主机上)。此位置是每个节点独立的,但主机可以使用它来检查存储在此目录中的内容。

  • /cluster/shared:此位置(在容器中)将指向 cluster_dir/shared(在主机上)。此位置在节点之间共享,并有效地充当共享文件系统(类似于 NFS)。

在 Docker-in-Docker (dind) 环境中设置#

在 Docker-in-Docker (dind) 环境中设置时(例如 Ray OSS Buildkite 环境),必须记住一些事情。为了明确这一点,请考虑以下概念

  • 主机 是执行代码的非容器化机器(例如 Buildkite runner)

  • 外部容器 是直接在主机上运行的容器。在 Ray OSS Buildkite 环境中,会启动两个容器 - 一个 dind 网络主机和一个包含 Ray 源代码和 wheel 的容器。

  • 内部容器 是由伪多节点 docker 节点提供程序启动的容器。

多节点 docker 节点提供程序的控制平面位于外部容器中。然而,docker compose 命令是在连接的 docker-in-docker 网络中执行的。在 Ray OSS Buildkite 环境中,这是在主机 docker 上运行的 dind-daemon 容器。如果您例如从主机挂载 /var/run/docker.sock,那它将是主机 docker 守护程序。从现在起,我们将两者统称为 主机守护程序

外部容器修改必须挂载到内部容器中的文件(并且也可以从内部容器中修改)。这意味着主机守护程序也必须能够访问这些文件。

类似地,内部容器暴露端口 - 但由于容器实际上是由主机守护程序启动的,因此这些端口也只能在主机(或 dind 容器)上访问。

因此,对于 Ray OSS Buildkite 环境,我们设置了一些环境变量

  • RAY_TEMPDIR="/ray-mount"。此环境变量定义了集群文件临时目录的创建位置。此目录必须可由主机、外部容器和内部容器访问。在内部容器中,我们可以控制目录名。

  • RAY_HOSTDIR="/ray"。在共享目录在主机上具有不同名称的情况下,我们可以动态地重写挂载点。在此示例中,外部容器通过 -v /ray:/ray-mount 或类似命令启动,因此主机上的目录是 /ray,而外部容器中的目录是 /ray-mount(参见 RAY_TEMPDIR)。

  • RAY_TESTHOST="dind-daemon" 由于容器是由主机守护程序启动的,我们不能只连接到 localhost,因为端口未暴露给外部容器。因此,我们可以使用此环境变量设置 Ray 主机。

最后,docker-compose 显然需要一个 docker 镜像。默认的 docker 镜像为 rayproject/ray:nightly。该 docker 镜像需要安装并启用 openssh-server。在 Buildkite 中,我们从 rayproject/ray:nightly-py38-cpu 构建一个新镜像,以避免为每个节点即时安装(这是默认方式)。此基础镜像是在之前的构建步骤中构建的。

因此,我们设置

  • RAY_DOCKER_IMAGE="rayproject/ray:multinode-py38"

  • RAY_HAS_SSH=1

以使用此 docker 镜像并通知我们的多节点基础设施 SSH 已安装。

本地开发#

如果您正在对伪多节点 docker 模块进行本地开发,可以设置

  • FAKE_CLUSTER_DEV="auto"

这将把 ray/python/ray/autoscaler 目录挂载到已启动的节点。请注意,这可能在您的 docker-in-docker 设置中不起作用。

如果您想指定要挂载哪些顶层 Ray 目录,可以使用例如

  • FAKE_CLUSTER_DEV_MODULES="autoscaler,tune"

这将在节点容器中挂载 ray/python/ray/autoscalerray/python/ray/tune 两个目录。模块列表应以逗号分隔,且没有空格。