本地测试自动扩展#

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

使用 RAY_FAKE_CLUSTER=1 ray start#

说明:

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

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

  3. 根据需要在YAML文件中配置工作器类型和其他自动扩展配置。

  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,
        },
    },
    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)[源代码]#

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

请参阅 test_autoscaler_fake_multinode.py 以获取端到端示例。

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

start(_system_config=None, override_env: Dict | None = None)[源代码]#

启动集群。

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

shutdown()[源代码]#

终止集群。

fake_multinode 的特性和限制#

自动伸缩器的大多数功能在假的多节点模式下都得到了支持。例如,如果你更新了YAML文件的内容,自动伸缩器将会获取新的配置并应用更改,就像在真实集群中一样。节点的选择、启动和终止都由与真实集群中相同的装箱和空闲超时算法控制。

然而,有一些限制:

  1. 所有节点 raylet 都在本地机器上以非容器化方式运行,因此它们共享相同的 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文件中配置工作器类型和其他自动扩展配置。

  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)[源代码]#

Docker 集群包装器。

创建一个目录以启动一个假的多节点 Docker 集群。

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

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

连接到 docker-compose Ray 集群。

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

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

  • timeout – 连接超时时间(秒)。

  • **init_kwargs – 传递给 ray.init() 的关键字参数。

remote_execution_api() RemoteAPI[源代码]#

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

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

等待直到 Ray 集群资源可用

参数:
  • resources – 此功能返回前所需的最少资源。

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

update_config(config: Dict[str, Any] | None = None)[源代码]#

更新自动扩展配置。

使用新配置对基础配置进行深度更新。这可以改变自动扩展行为。

参数:

config – 部分配置以更新当前配置。

setup()[源代码]#

设置 Docker Compose 集群环境。

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

teardown(keep_dir: bool = False)[源代码]#

拆除docker compose集群环境。

参数:

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

start()[源代码]#

启动 Docker Compose 集群。

启动监视器进程并运行 ray up

stop()[源代码]#

停止 docker compose 集群。

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

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

杀死节点。

如果给出了 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 运行器)

  • 外部容器 是直接运行在 主机 上的容器。在 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。模块列表应以逗号分隔且不带空格。