Ray 于 2026 年 11 月 4 日发布 2.60.0,其中 Ray Serve 为滚动更新加入 max_surge_percent,允许先启动替代副本,再停止旧副本。对维护在线模型推理、重排或 AI API 的团队,这意味着更新期间可以少一次主动缩减服务容量的过程。本文拆解它怎样工作、需要预留什么资源,以及新版本启动失败时究竟能保住什么。来源:Ray 2.60.0 发行说明

Ray Serve 滚动更新概念图:旧副本继续服务,新副本逐步就绪

原创 AI 概念图,以灯塔表示服务副本,不代表实际部署状态,也不承诺请求零失败。

[配图建议:四座蓝色灯塔持续亮灯,旁边的新灯塔逐步点亮,维护中的一座保留施工标记 + 沙色、灰蓝与陶土色的水彩技术插画风格。]

一、改变更新顺序,为什么会影响用户等待

先把“副本”理解为同一服务的多个运行实例:它们承接请求,背后各自占用一定的 CPU、内存或 GPU 资源。模型文件已经下载,不等于新实例已经准备好;初始化、加载权重和检查依赖,都可能发生在开始接流量之前。

如果先停一部分旧副本,再启动替代者,在新实例就绪前,可承接请求的实例数量会暂时减少。流量不变时,排队和等待就值得关注。这里讨论的是部署过程中的可用容量,不是模型每秒生成多少 Token。

Ray Serve 这次提供另一种顺序:先申请额外副本,等替代者运行起来,再分批停止旧副本。相关实现说明还写明,资源不够时,替代者会等待,旧副本继续服务。来源:先启后停实现说明

这并不表示升级后自动启用。固定在 ray-2.60.0 标签的接口说明确认,max_surge_percent 默认是 0,保留先停旧、再起新的行为;设置正值才启用额外副本策略。来源:2.60.0 接口源码

因此,判断一次更新是否用到了新策略,要看实际配置,而不能只看安装版本。对于已经接近资源上限的服务,还要先决定:希望更新快一些,还是愿意保留旧服务等待资源?新开关让这个取舍更明确。

[配图建议:两条时间线分别显示“先停后启”和“先启后停”,将新副本就绪前的区间清楚标出 + 简明二维时序图风格,不填虚构延迟。]

二、四个副本加 50%,不是账单只多一半

假设一个服务的目标是四个副本,配置额外副本比例为 50%,对应允许增加两个替代副本。这是根据配置规则计算的示例,不是本站集群测试数据。

把下面字段放入既有 Serve 配置的对应 deployment 中,可以表达这一意图:

deployments:
  - name: Model
    num_replicas: 4
    max_surge_percent: 50

这是配置片段,需要与自己的应用声明组合使用。参数按目标副本数计算,允许值为 0—100,并向上取整到完整副本;采用成组部署时,则按完整组取整。来源:参数定义

更重要的细节在停止阶段:接口说明指出,正在停止、排空请求的副本不计入该限制。因此,实际存活 Actor 数和资源使用量,可能高于“目标数加额外副本数”。不能据此把 50% 直接当作 GPU 占用或费用的严格上限。

对模型服务,资源账本至少要包含三段:旧副本仍在处理的请求、新副本的初始化资源,以及过渡期间同时存活的状态。若一个副本背后需要多张 GPU,就应按完整资源组合判断能否调度,而不是只看集群空闲显存的总和。

这也解释了谁更适合尝试:有一定资源余量、初始化较慢、又在意更新期间容量波动的团队,更容易从先启后停中获得价值。只有一套刚好够用的资源时,先做容量安排,通常比直接调大比例更有帮助。

[配图建议:目标四个、额外两个与正在排空请求的副本分别画在三个区域,资源账本保留独立统计 + 不把副本数等同 GPU 数的编辑信息图风格。]

三、新版本起不来时,保住剩余副本也有边界

同一版本还调整了失败更新的处理。过去可能出现这样的情况:旧版本副本仍健康运行,部署却被标为不可用,调用得到 HTTP 503。对应修复让仍在运行的副本保持可路由,健康检查继续剔除不健康实例。来源:保留旧副本路由

另一项改动让反复失败的滚动更新在达到既有启动失败阈值后停止,进入 DEPLOY_FAILED,避免继续替换健康旧副本。该状态会保留,直到新的部署改变目标;控制器重启也会保留这个失败状态。来源:停止失败更新

但开发者在实现说明中明确提醒:小规模部署仍可能在达到阈值前失去全部旧副本。而保留路由只让幸存副本继续工作,不会自动恢复原来的容量,也不会自动回滚。若一个副本都没有存活,服务依然不可用。

可以把三个结果分开看:

观察到的结果 可以说明什么
还有旧副本响应请求 剩余实例仍可提供服务
部署停在失败状态 此次更新尚未完成,需要处理
重新部署健康配置后恢复 完成了一次明确的恢复操作

不要因为入口还能返回成功,就忽略失败状态;也不要把“停止继续恶化”当作“已经恢复”。剩余副本可能暂时撑住低流量,一到高峰仍暴露容量不足。

上述 PR 讨论开始于 9 月,本轮关注的是它们被列入 11 月 4 日正式版本的交付,而不是把早期实现日期包装成今天的新开发。文中也不采用开发者测试中的零失败数字作为你的线上保证。

[配图建议:失败的新副本停止推进,剩余旧副本仍接请求,旁边单独保留“重新部署健康配置”的恢复路径 + 克制的状态图风格。]

四、先演练一次失败,再决定怎样用于生产

最小试点可以使用一个能返回版本标识的轻量服务,不必一开始就加载昂贵的大模型。先让旧版本稳定接收连续请求,再发布一个健康的新版本,观察替代副本何时就绪、旧副本何时停止,以及请求是否出现异常。

下一轮在独立测试环境让新版本初始化明确失败,检查系统是否停在预期状态、旧副本是否仍可访问,再显式部署健康配置完成恢复。这是本文建议的演练方法,不是声称本站已经复现。

需要保留的记录可以很短:

  • 请求侧:成功与失败数量、等待时间、实际返回的版本标识。
  • 副本侧:运行、启动与停止中的数量变化。
  • 资源侧:更新期间的使用峰值,以及调度等待。
  • 恢复侧:失败状态、处理动作和恢复后的结果。

完成轻量试验后,再用真实模型观察权重加载、健康检查与长请求排空。前一个试验验证更新顺序,后一个试验才接近真实资源条件;把两步拆开,出了问题更容易定位。

此外,并非所有修改都需要重启。官方文档区分了轻量配置更新与代码更新,并建议大规模代码变化采用新集群部署后切换流量的方式。新策略是滚动更新的一种选择,不能代替对发布方式的判断。来源:原地更新与代码更新说明

[配图建议:轻量服务演练与真实模型验证依次排列,每一步都记录请求、状态和资源,最后再选择发布方式 + 清晰的试点流程图风格。]

今天先算一次更新时的重叠资源

Ray Serve 2.60 值得在线推理团队关注的,是更明确的替换顺序和失败处理。已经使用 Ray Serve、且能预留资源的团队可以先试;尚未遇到发布容量问题的项目,不必仅为这项功能迁移服务框架。

今天可做的一步:画出旧副本、新副本与排空请求同时存在的区间,确认资源是否装得下。你当前更难处理的是新版本启动慢,还是失败之后不知道怎样恢复?这会决定下一次演练重点。

资料核查于北京时间 2026 年 11 月 5 日,依据正式发行说明、固定版本源码及实现 PR 分析;本文未部署实测。

[配图建议:一张重叠资源时间表旁放着可执行的恢复记录 + 与封面一致的水彩收尾风格,不标注未经测量的资源峰值。]