第 3 篇|KubeRay 并发:一个 Operator 如何管理 100 个 RayCluster

第 3 篇|KubeRay 并发:一个 Operator 如何管理 100 个 RayCluster

💡 原文中文,约9900字,阅读约需24分钟。
📝

内容提要

KubeRay Operator 通过工作队列和协调协程管理大量 RayCluster。并发数限制同时执行的 Reconcile 轮数,默认 1,设为 2 则两个协程轮流处理不同对象。同一对象按键锁定,不会被并发处理。由于缓存滞后,需用 scale expectations 避免重复创建 Pod。版本冲突靠 resourceVersion 乐观并发检查处理。是否提高并发应依据队列积压、协调耗时和错误率等指标判断。

🔎

延伸解读

并发数配置的实际含义

KubeRay 的 --reconcile-concurrency 默认值为 1,它限制的是每个 Controller 同时执行的 Reconcile 轮数,而非 Ray 集群数量。设为 2 时,RayCluster、RayJob、RayService 三个 Controller 各自最多有两轮在途协调,合计可达六轮。提高该值可能缩短其他对象的排队时间,但不会直接提升 Ray task 或 actor 的执行并发,也不能据此推导可承载的集群总数。

同一对象串行与缓存滞后的应对

同一 Controller 内,队列通过键锁定确保同一个 RayCluster 不会被两个协程同时处理。但即使串行,由于写入 API Server 后 informer 缓存可能尚未更新,仍可能基于旧列表重复创建 Pod。KubeRay 用 scale expectations 记录待观察的创建或删除结果,在下一轮检查前跳过未满足的组,避免重复扩缩容。创建预期在能读到 Pod 或超时 30 秒后放行,删除预期则要求读取返回 NotFound。

版本冲突与重试机制

当用户同时修改 RayCluster spec 时,Controller 写入 status 可能因 resourceVersion 不匹配而返回 Conflict。此时协调函数会返回错误和 RequeueAfter,但框架优先处理错误,通过限速队列重新入队,忽略 RequeueAfter。重试时会重新读取最新对象并计算,不能原样重试旧对象。版本检查仅保护单次更新,不会将 Pod 创建与 status 更新组成事务,因此已成功的 Pod 创建不会因后续冲突而回滚。

判断是否提高并发的依据

是否提高协调并发数应基于指标观察,而非集群数量。可关注 controller_runtime_active_workers 是否长期占满、workqueue_depth 是否持续积压、reconcile_time_seconds 是否变慢、reconcile_errors_total 是否上升。若协程占满且队列积压,而单轮耗时和 API 请求稳定,可尝试提高并发验证;若 API 已变慢或限流等待增加,继续增加协程可能加剧争用。验证时应固定 Pod 规模和变更负载,比较调整前后的排队耗时、错误速率及就绪耗时。

Q&A

KubeRay Operator 的 --reconcile-concurrency 参数默认值是多少?它控制什么?

默认值是 1。它控制一个 Controller 同时执行多少轮 Reconcile,即协调协程的数量。

为什么同一个 RayCluster 不会被两个协调协程同时处理?

因为队列会按键锁定。当某个键正在处理时,队列会跳过已锁定的键,直到本轮结束调用 Done 解除锁定,其他协程才能再次取到该键。

KubeRay 为什么需要 scale expectations?它解决什么问题?

因为写入 API Server 成功后,本地 informer 缓存可能尚未更新,导致下一轮协调基于旧列表重复创建 Pod。scale expectations 记录尚待观察到的 Pod 创建或删除结果,在缓存滞后时避免重复扩缩容判断。

当多个 Controller 共享同一个 ReconcileConcurrency 配置时,并发数如何分配?

同一个 config.ReconcileConcurrency 分别传给 RayCluster、RayJob、RayService 三个 Controller,每个 Controller 各自最多有该数量的在途协调。例如设为 2 时,三个 Controller 合计最多可有 6 轮在途协调,而不是整个 Operator 共用两个名额。

KubeRay 如何处理对象版本冲突?

使用 resourceVersion 进行乐观并发检查。当 Update 提交旧版本时,API Server 会拒绝并返回 Conflict 错误。主流程会返回错误和 RequeueAfter,后续协调重新读取最新对象并重新计算,而不是用旧对象原样重试。

判断是否应该提高协调并发数时,应该关注哪些指标?

应关注 controller_runtime_active_workers、controller_runtime_max_concurrent_reconciles(在途协调是否占满名额)、workqueue_depth、workqueue_queue_duration_seconds(积压和等待时间)、controller_runtime_reconcile_time_seconds(单轮耗时)、controller_runtime_reconcile_errors_total(错误速率),以及 API 请求耗时和限流等待。

🏷️

标签

➡️

继续阅读