4、集群架构设计:集群拓扑结构、节点角色划分、数据同步策略

集群架构设计,说白了就是决定你的 Ollama 集群长什么样、谁干什么活、数据怎么串起来。我见过不少团队一上来就堆机器,结果节点之间互相打架,数据乱成一锅粥。嗯,咱们今天就把这事捋清楚。

4.1 集群拓扑结构:选对路子,少走弯路

我个人习惯把集群拓扑分成三种主流模式。你想想看,不同的业务场景,适合的拓扑完全不一样。

4.1.1 星型拓扑(中心化架构)

这是最直观的方案。一个主节点(Master)负责调度和元数据管理,多个工作节点(Worker)只负责跑推理任务。我在项目中遇到过,初期用这种结构最省心,因为控制逻辑集中,排查问题方便。

适用场景:中小规模集群(10-50节点),团队运维能力有限。

优点:管理简单,一致性容易保证。

缺点:主节点单点瓶颈,挂了整个集群就瘫了。

4.1.2 环型拓扑(去中心化架构)

每个节点只跟左右邻居通信,数据沿着环转一圈。这种结构在分布式存储里很常见,比如 Cassandra 的 Gossip 协议就是类似思路。我曾经在某个日志分析项目里试过,节点多了以后,环的延迟会线性增长,不太适合实时推理场景。

注意:环型拓扑在 Ollama 集群里不太推荐。因为模型加载和推理对延迟敏感,环型通信的累积延迟会让你抓狂。

4.1.3 树型拓扑(分层架构)

这是我个人最偏爱的方案。顶层是全局调度器,中间层是区域代理,底层是实际的工作节点。说白了,就是把星型的单点压力分散到多个层级。我在一个 200 节点的集群里用过这种结构,效果相当稳。

下面这张图展示了树型拓扑的核心逻辑:

Ollama 集群树型拓扑结构 全局调度器 区域代理 A 区域代理 B 区域代理 C Worker 1 Worker 2 Worker 3 Worker 4 Worker 5 Worker 6 调度节点 代理节点 工作节点

4.2 节点角色划分:各司其职

节点角色不能乱分。我建议至少划分三种角色,每种角色干好自己的事,别越界。

角色名称 核心职责 资源要求 典型数量
调度节点 请求路由、负载均衡、健康检查 CPU 密集型,4核8G起步 2-3个(高可用)
模型节点 加载模型、执行推理、缓存管理 GPU 密集型,显存越大越好 根据业务量弹性伸缩
存储节点 模型文件存储、日志收集、元数据持久化 磁盘密集型,SSD 推荐 3-5个(副本保证)

我的经验:调度节点千万别跟模型节点混用。我曾经图省事把调度和推理放一起,结果高并发时调度进程把 CPU 吃光了,推理请求全部超时。嗯,那次教训挺深刻的。

4.3 数据同步策略:别让数据成为短板

数据同步是集群里最容易出幺蛾子的地方。说白了,就是模型文件、配置信息、推理状态这些数据,怎么在节点之间保持一致。

4.3.1 模型文件同步

模型文件通常很大(几个 GB 到几十 GB),不能每次都从中央仓库拉。我建议用分层同步策略:

  • 本地缓存优先:每个模型节点维护一个本地模型缓存目录。请求来的时候,先查本地有没有,有就直接用。
  • 增量同步:用 rsync 或类似工具,只同步模型文件的差异部分。我实测过,对于大模型,增量同步比全量快 5-10 倍。
  • 懒加载:模型不用提前全部加载到内存。哪个模型被请求了,才从磁盘加载到 GPU 显存。

避坑指南:我曾经遇到过所有节点同时从中央存储拉模型,结果把存储的带宽打满了,导致其他业务也受影响。后来加了限流和随机延迟,问题才解决。

4.3.2 配置信息同步

集群的配置信息(比如节点列表、模型版本、路由规则)需要强一致性。我推荐用 etcd 或 Consul 这类分布式键值存储:

# 配置信息示例(etcd 存储结构)
/cluster/nodes/node-01    {"ip":"192.168.1.10","role":"worker","status":"active"}
/cluster/models/llama2    {"version":"7b","path":"/models/llama2-7b","checksum":"abc123"}
/cluster/routing/default  {"strategy":"least_connections","fallback":"round_robin"}

每个节点启动时,从 etcd 拉取全量配置。运行期间,通过 Watch 机制监听变更,增量更新。这样既保证了一致性,又避免了频繁全量拉取。

4.3.3 推理状态同步

这个很多人会忽略。比如一个推理请求被调度到节点 A,但节点 A 挂了,请求需要重新调度到节点 B。如果节点 A 已经算了一半,节点 B 得知道从哪继续。

我个人习惯用 Redis 做中间状态存储:

  • 每个推理请求分配一个全局唯一的 RequestID
  • 节点在处理过程中,定期把中间结果写入 Redis(带 TTL)
  • 如果节点挂了,调度器把请求重新分配给其他节点,新节点从 Redis 读取中间状态继续算

关键点:状态同步的粒度要把握好。太细了(比如每算一个 token 就同步一次)性能扛不住;太粗了(整个推理完成才同步)又失去了容错的意义。我一般建议每完成一个推理步骤(比如每 10 个 token)同步一次。

4.4 小结

集群架构设计没有银弹。树型拓扑适合大多数场景,节点角色要严格分离,数据同步策略要分层处理。你想想看,这些设计原则其实都是围绕一个核心目标:让集群在故障时还能继续干活,在扩容时不影响在线业务。

嗯,这一章的内容就到这里。记住,架构设计不是一次性的,随着业务增长,你得不断调整拓扑、优化角色划分、完善同步策略。这才是 SRE 的日常。


公众号:蓝海资料掘金营,微信deep3321