2. Ray与Ray Serve基础

在金融多模型Serving场景中,我们往往需要同时托管信用评分、反欺诈、行情预测、NLP舆情等多个模型,并且要求低延迟、高并发、可弹性伸缩。Ray Serve正是建立在Ray分布式运行时之上的在线服务框架。理解Ray的核心概念与Serve的架构分层,是后续实战部署的前提。

一、Ray核心概念:任务、Actor与对象存储

Ray把分布式计算抽象为三个基本原语,它们共同构成了Serve的底层执行基础。

  • Task(任务):无状态的远程函数调用,通过 @ray.remote 装饰普通函数,调用时返回 ObjectRef 而非立即结果。适合并行特征计算、批量打分。
  • Actor(参与者):有状态的远程类实例,通过 @ray.remote 装饰类。每个Actor拥有独立进程与内部状态,适合加载模型权重、维护会话缓存。
  • Object Store(对象存储):基于共享内存的分布式对象存储,Task与Actor的返回值以不可变对象形式存放,支持零拷贝读取与自动垃圾回收。

此外,Ray还提供 Placement Group(资源亲和调度)、Ray Dataset(分布式数据管道)等能力。在Serve中,每个模型副本本质上就是一个长期存活的Actor,而请求分发则依赖Ray的异步任务调度。

关键理解:Ray Serve不是独立进程模型,它把“模型副本”映射为Ray Actor,把“请求处理”映射为异步Task,从而复用Ray的调度、容错与资源管理能力。

二、Serve架构分层:Controller、Proxy与Replica

Ray Serve的运行时由三类角色组成,它们各司其职,形成清晰的控制面与数据面分离。

组件角色定位核心职责
Controller控制面接收Deployment配置,管理副本生命周期、扩缩容、版本更新与健康检查
Proxy数据面入口监听HTTP/WebSocket端口,解析请求路由,转发到目标Replica
Replica数据面执行实际加载模型、执行推理逻辑,每个副本是一个Ray Actor
Handle调用句柄Deployment之间互相调用的异步引用,支持链式组合

请求的完整路径为:客户端 → Proxy → 路由匹配 → Replica队列 → 模型推理 → 返回响应。Controller不参与数据转发,只负责“决定谁在跑、跑几个、跑哪个版本”。

三、部署图与请求流转

下面这张部署图展示了Controller、Proxy与多个Replica之间的控制流与数据流关系。控制流用虚线表示,数据流用实线表示,便于区分“管理”与“转发”两类行为。

Ray Serve 部署架构与请求流转 客户端 HTTP / gRPC Proxy 路由 / 负载均衡 Controller 副本管理 / 扩缩容 Replica-1 信用评分模型 Replica-2 反欺诈模型 Replica-3 舆情NLP模型 推理结果返回客户端

图中虚线为控制流:Controller向各Replica下发配置与生命周期指令;实线为数据流:Proxy根据路由规则把请求分发到对应Replica。这种分离设计使得扩缩容、版本切换不会阻塞在线请求。

四、最小可运行示例与参数说明

下面是一个最小Serve部署示例,展示Deployment定义、副本数与资源声明。

import ray
from ray import serve
from fastapi import FastAPI

app = FastAPI()

@serve.deployment(
    num_replicas=2,
    ray_actor_options={"num_cpus": 0.5, "num_gpus": 0.0},
    max_concurrent_queries=32
)
@serve.ingress(app)
class CreditScoring:
    def __init__(self):
        self.model = load_model("credit_v3.pkl")

    @app.post("/score")
    async def score(self, payload: dict):
        return {"score": self.model.predict(payload["features"])}

serve.run(CreditScoring.bind(), route_prefix="/credit")
  • num_replicas:副本数量,决定并发处理能力与资源占用。
  • ray_actor_options:每个副本占用的CPU/GPU资源,直接影响调度与成本。
  • max_concurrent_queries:单副本最大并发请求数,超过则排队或拒绝。
  • route_prefix:Proxy对外暴露的HTTP路径前缀。
在金融场景中,建议把GPU密集型模型与CPU预处理模型拆分为不同Deployment,通过Handle组合调用,避免单副本资源争抢导致尾延迟升高。

五、常见误区与复盘要点

  1. 把Controller当数据入口:Controller只做管理,不转发请求。所有流量必须经过Proxy。
  2. 副本数越多越好:副本数受CPU/GPU配额限制,盲目增加会导致调度失败或资源碎片。
  3. 忽略max_concurrent_queries:默认值较小,高并发下会大量排队,需根据模型推理耗时压测后调整。
  4. 在__init__中做重活:副本启动时会阻塞,建议把耗时加载放在初始化并配合健康检查,避免流量打到未就绪副本。
复盘提示:当出现请求超时但CPU利用率不高时,优先检查Proxy路由是否命中、Replica队列是否积压、以及max_concurrent_queries是否成为瓶颈,而不是直接扩容。

掌握Ray的Task/Actor/Object Store三原语,理解Serve的Controller-Proxy-Replica分层,并能在部署图中定位控制流与数据流,就具备了后续构建金融多模型Serving系统的架构基础。