3. 模型服务架构设计:单体架构 vs 微服务架构、服务发现与负载均衡、无状态设计原则

模型服务架构是决定推理系统可扩展性、运维复杂度与资源效率的核心决策层。本章从单体与微服务的架构对比出发,深入剖析服务发现与负载均衡的工程实现,并强调无状态设计在模型服务中的关键作用。

3.1 单体架构 vs 微服务架构

在模型服务早期阶段,单体架构因其简单性被广泛采用;随着业务规模增长,微服务架构逐渐成为主流选择。下表从多个维度对比两种架构的差异:

对比维度 单体架构 微服务架构
部署单元 单个进程/容器,包含预处理、推理、后处理 每个功能模块独立部署为独立服务
扩展粒度 整体扩缩容,资源浪费明显 按模块独立扩缩容,资源利用率高
故障隔离 单点故障导致整个服务不可用 故障被限制在单个服务内,不影响全局
开发效率 初期开发快,但随代码膨胀协作成本剧增 团队可并行开发,技术栈灵活
运维复杂度 低,只需管理一个服务 高,需要服务发现、负载均衡、链路追踪等基础设施
适用场景 原型验证、低并发、小团队 高并发、多模型、多版本、大规模生产环境
架构选型建议: 对于日均请求量低于 10 万、模型数量少于 3 个的初期项目,单体架构可快速上线;当请求量突破 50 万或需要同时服务多个模型版本时,应尽早迁移至微服务架构。

3.2 服务发现与负载均衡

在微服务架构中,服务实例的动态注册与请求分发是保障高可用的核心机制。服务发现负责维护可用实例列表,负载均衡则决定请求如何分配到具体实例。

常见的服务发现模式包括:

  • 客户端发现: 客户端直接从注册中心获取实例列表,自行选择目标实例(如 Netflix Eureka + Ribbon)。
  • 服务端发现: 客户端请求通过负载均衡器(如 Nginx、Kong),由负载均衡器查询注册中心并转发请求。
  • Kubernetes 原生: 利用 Service 对象与 kube-proxy 实现 DNS 或 IPVS 方式的自动发现与轮询。

负载均衡策略在模型服务场景中的选择:

策略 原理 模型服务适用性
轮询(Round Robin) 依次将请求分配给每个实例 适用于各实例硬件配置一致的场景
最少连接(Least Connections) 优先分配给当前活跃请求最少的实例 适用于推理时间波动较大的模型
一致性哈希(Consistent Hashing) 根据请求特征(如模型 ID)映射到固定实例 适用于模型分片或需要本地缓存加速的场景
加权分配(Weighted) 根据实例的 GPU 显存、CPU 核数等设置权重 适用于异构硬件集群
工程实践: 在 Kubernetes 环境中,推荐使用 Service + Ingress 实现服务端发现,配合 HorizontalPodAutoscaler 基于 GPU 利用率或请求 QPS 自动扩缩容。对于延迟敏感场景,可引入 gRPC 长连接与 Weighted Least Connections 策略。
模型服务微服务架构与服务发现流程 模型服务微服务架构与服务发现流程 客户端 负载均衡器 注册中心 推理服务 A 推理服务 B 推理服务 C 流程说明: 1. 推理服务启动时向注册中心注册自身 IP:Port 与健康状态 2. 负载均衡器定期从注册中心拉取可用实例列表(或订阅变更事件) 3. 客户端请求到达负载均衡器,根据策略(轮询/最少连接/一致性哈希)分发到具体实例

3.3 无状态设计原则

无状态设计是模型服务能够水平扩展的前提。所谓无状态,是指服务实例不存储任何与当前请求相关的会话数据,所有请求所需的上下文信息均由请求本身携带或从外部存储获取。

在模型服务中,无状态设计的具体体现:

  • 模型权重只读加载: 模型参数在服务启动时从共享存储(如 S3、NFS)加载到内存/显存,推理过程中不修改权重。
  • 请求上下文外置: 用户会话信息、历史对话记录存储在 Redis 或数据库,请求时通过 token 或 session ID 获取。
  • 本地缓存可选但非必需: 即使使用本地缓存(如特征哈希表),缓存丢失也不影响正确性,仅影响性能。
  • 日志与监控异步输出: 推理日志通过消息队列发送到集中式日志系统,不依赖本地磁盘。
常见反模式: 将用户特征或模型中间结果存储在服务实例的本地内存中,且未做持久化。当实例被重新调度或扩缩容时,这些数据丢失会导致请求失败或结果不一致。正确的做法是将状态数据外移到 Redis、Memcached 或数据库。
无状态模型服务请求处理流程 无状态模型服务请求处理流程 请求入口 无状态推理服务 Redis / DB 模型权重存储 无状态设计要点: • 推理服务不保存任何请求级状态,所有上下文从 Redis/DB 读取 • 模型权重只读加载,服务重启或扩缩容时从共享存储重新加载

3.4 架构设计决策清单

在实际项目中,架构选型需结合团队规模、请求量级、模型复杂度等因素综合判断。以下决策清单可作为参考:

  1. 评估当前与未来 6 个月的请求 QPS: QPS < 500 可考虑单体架构;QPS > 2000 建议微服务架构。
  2. 确定模型数量与版本管理需求: 多模型或多版本并行服务时,微服务架构更便于独立发布与回滚。
  3. 选择服务发现方案: Kubernetes 环境优先使用 Service + DNS;非 K8s 环境推荐 Consul 或 etcd + 客户端发现。
  4. 配置负载均衡策略: 通用场景使用轮询;推理时间方差大时使用最少连接;需要缓存亲和性时使用一致性哈希。
  5. 审查服务状态依赖: 确保所有会话数据、模型中间结果均外置,服务实例可随时销毁与重建。
推荐阅读: 本章后续内容将深入探讨模型服务的 弹性伸缩策略(第 4 章)与 服务网格集成(第 5 章),帮助你在微服务架构中实现更精细的流量管理与可观测性。