ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI服务多地域部署实战:从单地域扩容的架构拆分与踩坑记录

AI服务多地域部署实战:从单地域扩容的架构拆分与踩坑记录 这篇博文我以一位亲手把AI服务从单地域扛到多地域的从业者视角来写重点放在扩容前的决策、架构拆分、数据同步、灰度切换和踩坑经验上。关于你输入里的那部分网络热词涉及VPS、专线IP这类话题和本文主题无关就不展开了咱们只谈正经的AI系统多地部署工程细节。1. 先回答那个最关键的问题单地域到底卡在了哪里去年下半年我们的AI推理服务在华北地域已经稳定跑了快两年QPS从最初的两三百涨到四千多看起来一切正常。直到几个客户同时反馈最近响应变慢了你们的接口是不是限流了我才意识到问题没那么简单。先说延迟。所谓单地域指的是所有计算资源、模型服务、存储都集中在一个可用区。用户分布在全国各地统一从这个地域入口走公网访问跨省跨运营商的网络链路损耗是实打实的。我们当时做过一次全链路压测从华东地区访问华北地域的推理接口P99延迟大约在180ms左右而华北本地的用户只有80ms。对LLM流式输出这种动辄三秒到十几秒的长连接场景来说这点差异感觉不明显但换成OCR、语音识别、向量检索这种对时延敏感的在线服务用户体感差别非常大。再说可用性。单地域的故障域天然就是整个地域。我们经历过一次底层交换机异常导致网络抖动服务没挂但P99从100ms飙到2.5秒持续了大概二十分钟。这二十分钟里所有依赖该服务的下游业务全部出现积压客户那边直接炸锅。事后复盘时大家聊到一个无奈的事实单地域做得再冗余终究躲不过地域级故障就像把鸡蛋放在同一个篮子里篮子再结实也没用。最后是被很多团队忽略的合规与数据驻留要求。随着业务扩张我们开始有华南、西南地区的客户他们明确要求某些核心业务数据的计算过程不能离开本地甚至要求推理过程必须在本地节点完成。这个需求单靠集中式部署根本满足不了。所以多地域部署不是高可用的奢侈品而是业务走到一定阶段的必答题。什么时候算该扩容了我给自己定了一个判断框架供参考全网实测P99延迟超过150ms且地域差异超过100ms单地域故障导致业务中断的次数一年内超过三次新签客户中对数据本地化有硬性要求的占比超过30%主地域的CPU、GPU利用率长期超过70%扩容主地域机房成本已高于新建地域当一个团队开始频繁讨论如果这个地域挂了怎么办的时候就是该启动多地域方案评估的时候了。当然多地域不是万能药在扩容前一定要想清楚你的目标到底是解决延迟、解决容灾还是解决合规。这三个目标对应的架构方案差异巨大如果一上来就想要全部项目大概率会烂尾。2. 多地域架构的核心思路把有状态和无状态分开对待AI系统和普通业务系统有个本质区别它不仅有用户数据还有模型权重、特征字典、版本标签这些AI专属状态。普通Web服务做多地域写个负载均衡、把数据库搞成主从复制就差不多了AI系统不行。你得先把系统拆成可独立扩展的平面再谈多地域。2.1 控制面与数据面AI系统扩容的基石所有分布式系统都逃不开控制面和数据面的分离AI系统尤其如此。所谓控制面就是负责模型版本管理、配置下发、特征更新、路由规则这套不直接承担请求的逻辑数据面则是真正跑推理、做向量检索、处理流量的计算节点。我见过不少团队一上来就在多个地域同时部署完整的推理服务模型文件、配置、代码全部打包到一个镜像里。表面上看很完整实际上每次更新模型都要重新发布整个服务发布期间新旧请求混在一起灰度只能靠流量比例硬切非常痛苦。正确的做法是控制面集中在单一地域或双活控制面数据面按业务需要放在多个地域。控制面负责统一管理所有地域的计算节点把模型文件、配置信息、路由规则推送到各个地域。各地域数据面只认版本号和摘要拿到新版本就拉取对应模型拉不到就用旧版本继续服务。这样模型管理、灰度、回滚全部集中在控制面各地域的机器形态高度一致扩容就是加服务器、注册到控制面这么简单。2.2 全局负载均衡流量路由的入口设计多地域的流量入口不再是一个SLB而是一套全局负载均衡GSLB加上各地域内部的负载均衡组成的两级结构。GSLB根据用户来源IP、DNS解析结果、各地域的健康状态做就近调度。这一层最好选择云厂商提供的全局流量管理服务自己搭的话要处理DNS劫持、缓存的麻烦事。需要特别注意的是GSLB不只是转发流量它还要承担健康检查和故障切换两个职责。我们当时的做法是让各个地域的推理节点每10秒上报一次心跳到控制面控制面把这些心跳信息同步给GSLB。当地域A连续三次心跳超时GSLB就把该地域的流量自动切到其他地域整个过程不需要人工干预。但这里有个隐藏的成本问题。就近接入看起来很美实际上对AI推理这种场景请求还有可能访问本地没有的数据。比如用户请求带了一个上游业务传过来的上下文ID需要从中心化的存储里读取会话状态。如果这个状态不在本地就得跨地域调用。所以流量调度必须聪明一点先看请求所需的数据是否在本地域可满足如果不满足要么做数据预读要么直接把这个请求转发到数据所在的地域而不是盲目就近。这个数据亲和性问题我在文章后面详细讲。2.3 模型热更新从全量发版到版本递增模型更新是AI系统最频繁、最影响稳定性的操作。早期我们是新老模型版本号各占一半流量由网关随机分发。后来发现这会有个问题同一个用户两次请求可能命中不同模型导致结果不稳定回放日志根本对不上。后来我们改成按用户ID哈希的灰度方式取用户ID的后几位小于某个阈值去新模型大于阈值走旧模型。这样同一个用户在一段灰度窗口内始终命中同一个模型版本问题消失。同时控制面会记录每个版本的分发比例先在华北一条线上灰度5%观察一小时后放到20%再放50%最后全量推平。整个过程在控制面用一条配置变更加一次版本校验就能搞定不用重新发容器。模型热更新还有一个容易被忽略的环节模型服务启动时要预热。TensorFlow Serving和TorchServe这类框架默认会在请求过来时才加载模型首个请求的延迟能到几百毫秒甚至几秒。我们要求新版本发布时节点启动后必须先跑一组预热请求确认P99延迟回到正常水位后才允许加入负载均衡组。这个校验逻辑写在控制面的发布流程里虽然只多了几分钟但能避免大量用户被慢请求命中。3. 数据同步与一致性多地域部署里真正容易拖垮人的地方常见认知是多地域部署最麻烦的是网络实际上最折磨人的是数据。AI系统涉及的数据类型比普通业务系统多得多用户画像、特征值、模型embedding、会话上下文、推理日志。每一类数据对时延、一致性的要求都不一样采取的方案也得不一样。3.1 特征数据最终一致够用别硬上强一致在线推理服务经常需要读取特征数据。比如一个推荐模型要用到用户的近七天行为特征、商品的特征向量这些特征由离线任务周期性产出更新频率从每小时到每天不等。多地域部署后最自然的想法是把中心数据库做成多个地域间的主从复制让每个地域都能读到完整数据。实测下来跨地域数据库同步最大的坑是延迟和冲突。我们在华北和华东之间同步一张核心特征表正常情况下延迟在20ms左右但网络一波动延迟能飙到几百毫秒主从复制会短暂拉开差距。如果业务代码里用了读主库、写从库这种隐式依赖很容易读到半新不旧的脏数据。对特征数据我强烈建议用最终一致性别一直惦记着强一致。特征本来就是过期数据晚几分钟到、偶尔新旧掺杂只要不是结构性错误不会对推理结果产生致命影响。我们的做法是离线特征统一写入对象存储各地域的推理节点定期拉取差异文件版本落后的节点自动降级用本地缓存兜底。缓存命中率维持在95%以上实际很少真正跨地域读特征服务。3.2 会话状态与上下文必须考虑数据亲和性AI对话、Agent这类服务的会话状态是实时写入的。用户每发一条消息会话状态都可能变化这个状态需要在下一条消息到达时立即可用。多地域部署下如果用户第一次请求落到地域A第二次请求被GSLB转发到了地域B会话状态怎么办一种方案是把会话状态放在中心化的Redis集群里所有地域读写同一个。但问题随之而来跨地域访问Redis的延迟是几十毫秒到上百毫秒高并发下Redis连接数容易被占满成因复杂、很难排查。我们后来做了一个会话亲和性方案GSLB根据用户ID的哈希值把用户绑定到固定地域绝大多数请求都落在同一边会话状态存本地Redis即可。只有在本地故障切换时才允许请求落到备份地域这时通过中心Redis读取最近快照恢复会话。这个方案把99%的请求锁死在本地域避免了最容易被拖垮的跨地域热路径。3.3 推理日志与训练回流异步是唯一的出路在线推理会产生大量日志包括请求入参、出参、延迟、模型版本、命中规则等。单地域部署时日志直接写本地Kafka就完事。多地域之后不能指望三个地域的日志全实时汇集到一个中心本地Kafka写进去了但不实时同步离线训练任务就要等待更久的数据回流。我们的解决方式是三级日志链路每个地域的节点先写本地Kafka缓冲再由独立消费者任务把日志批量同步到中心Kafka每两分钟一批中心Kafka只负责给离线训练平台和BI报表取数在线业务不碰这批数据。这样中心数据最多延迟两分钟训练任务调度时加了5分钟的等待窗口实测对模型迭代影响很小。这个方案的好处是不管什么地域故障日志最多丢两分钟缓冲量对训练场景完全可以容忍。4. 灰度切换与跨地域回滚扩容最怕的不是上线而是上线后改不回来多地域部署的第一版方案往往不是直接全量切流量而是从单地域平稳过渡到双地域、再到多地域。这个过程里最容易出事的不是上线动作本身而是上线之后发现问题想回滚却回不去。4.1 流量染色灰度前先学会偷偷看在真正切流量之前先做一轮流量染色是非常值得的。所谓染色就是在请求头里打一个特殊的识别标记网关识别到这个标记后把请求转发到新地域的测试节点。这个标记可以是内部调试专用的Header也可以是按用户ID白名单匹配。染色的价值在于不需要真实用户流量就能验证新地域的接口和主地域返回一致而且完全不影响线上服务的节奏。我们当时用染色验证了一周重点比对新地域的模型返回与主地域的差异率。比较有意思的是模型文件虽然校验了MD5一致但因为GPU机型不同、推理框架的浮点精度差异两个地域的推理结果依然可能出现微小偏差一般在个位数的百分之一概率内。这个偏差在内测染色阶段就暴露了如果直接全量切流量客户投诉时你根本分不清是网络问题还是模型问题。4.2 分阶段切流比例、配额、回滚三步走染色通过后切流一定要用比例配额灰度窗口的方式。三个地域都上线后我们从5%流量切到新地域开始每两个小时增加10%到20%直到100%。但单纯按比例切流有个坑如果某个用户被切到新地域后体验下降他会反复重试把新地域的流量顶得比预期更高导致切流比例失真。所以每条切流规则要绑定配额地域维度QPS封顶值、单用户并发限制、单请求超时时间。新地域QPS达到设定阈值后网关宁可将请求转发回主地域也不允许新地域被打爆。这个配额像汽车上的限速器灰度期间的流量增长必须被压在可控范围。回滚预案要提前演练不是等到出问题才写文档。我们每隔两周做一次切换演练模拟新地域故障看GSLB能否自动切回主地域以及切换过程会不会导致会话状态丢失。演练下来发现最初版本的GSLB健康检查依赖TCP探活探活成功不代表推理服务质量正常新地域CPU满载时TCP连接照样能建立。后来改成HTTP级别的探活每次探活请求都走一遍完整的推理链路只是把响应体缩小到健康检查专用格式。这个改动花了半天但避免了一次真实的故障扩大。4.3 全链路可观测没有Trace就谈不上跨地域排障多地域部署之后的排查难度比单地域高了一个数量级。同一个用户请求可能先落到华北的网关又被转发到华东的计算节点最后结果从华南的出口返回。没有一套全链路Trace系统出了问题只能来回对时间戳效率极低。我们在每个AI服务的HTTP入口和内部的GRPC调用链路上都埋了Trace点Trace ID从网关开始一直透传到模型推理服务、特征服务、Redis、MySQL所有日志、指标、调用链都带上地域标签。这样一来在监控大屏上能直接按地域筛选延迟分布能清晰地看到华南地区P99高是因为本地Redis慢而不是笼统地归因于网络。这里必须强调Trace的采样策略。AI推理服务QPS高全量采样成本扛不住我们最终采用动态采样正常流量按1%采样但凡是延迟超过P95阈值的慢请求100%采样。这样既控制了成本又保证了慢请求必能查到根因。5. 扩容不是终点上线后半年里踩过的那些坑多地域代部署从启动到全量切流我们花了大概三个月。但真正让人长记性的是上线后半年里陆续踩到的一些坑。这些坑不大但在特定流量模式下会突然爆发这里挑几个典型的说一下。第一个坑是模型文件分发的不一致性。控制面虽然会校验MD5但实际运行中发现由于下载超时和重试策略配置不当某些节点会拿到一个半截的模型文件启动时加载失败节点反复重启。服务看起来正常但容量始终上不来。后来花了大力气做两件事第一模型文件一律先下载到本地临时目录校验完MD5后通过原子重命名的方式替换正式文件第二节点启动时如果校验失败直接上报控制面并进入隔离状态宁可少一个节点也不用坏的模型拖累整体。第二个坑是跨地域数据库连接池被打爆。初期我们把中心Redis和MySQL连接池大小设置成了各地域之和结果华南地域的流量一上来连接数直接翻倍数据库CPU没被打满连接数先打满了。解决方案是把连接池改成按地域动态调整每个地域最多占用固定比例同时把纯读取流量切到本地只读副本中心库只保留写流量和强一致读。这个教训让我意识到多地域不是把机器加一倍那么简单数据库这类共享资源的连接配额必须提前规划。第三个坑是慢启动现象。某个地域的节点因为共享宿主机负载高了首次加载模型到显存的时间从5秒变成30秒加上预热不充分就加入了负载均衡结果该地域的P99瞬间飙到1.2秒。单地域时这个问题不明显因为所有节点同时加速启动总有快的能顶住多地域时不同地域的节点启动速度差异被放大很容易形成一个慢地域拖垮全链路的假象。解法很简单节点启动后必须通过健康检查含预热延迟指标才能上线健康检查失败则自动不参与调度等待下一轮重试。第四个坑是关于到底哪些数据必须同步的定力问题。有段时间团队想把所有表都做多地域同步理由是万一地域故障不至于丢数据。结果同步链路越来越复杂延迟抖动、冲突、存储成本一起上来。后来我们做了一次严格的分类把数据分成核心持久数据必须多副本冗余、本地缓存数据允许丢失、中间状态数据允许短暂不一致三类每类采用不同的复制策略整个系统的复杂度立刻降下来不少。多地域部署的一个核心理念就是要接受不是所有数据都值得跨地域同步。6. 如果让我重新做一次我会这样规划项目做完后我复盘过很多次如果要给正准备做多地域扩容的团队一份路线图我会这么说。第一步先用两周时间做容量和延迟基线梳理。把所有在线服务的调用拓扑画出来标记哪些是强依赖链路会话状态、特征、模型、哪些是弱依赖日志、异步报表区分清楚。这是后面所有决策的基础。第二步选择一个高可用但可控的过渡架构不需要一上来就全部地域对等。可以先用主地域一个备份地域的模式跑两个月备份地域平时承担零流量只做数据同步和定期健康检查。等团队对整个流程熟悉了再逐步升级成多地域对等调度。别急着一步到位。第三步把模型管理和发布流程完全自动化。控制面是AI系统的心脏这一步如果用手工脚本做后面每次发版都是噩梦。我们做了一套简单的发布流水线代码仓库推送触发构建构建产物上传对象存储控制面按地域分批下发配置各地区节点拉取新版本并自动执行预热、检查、上线。整个流程人工参与的部分只剩审批发布按钮。第四步做好成本核算。多地域部署不是免费的每个地域至少一套推理集群加上跨地域的对象存储同步和数据库复制费用成本翻倍是必然的。我们当时算了一笔账多地域方案比单地域多出65%的算力成本但因为容灾能力提升、延迟下降带来的客户留存提升半年内就回本了。如果业务量没到一定程度先别急着多地域把单地域的冗余做扎实可能更划算。第五步也是最容易被忽略的人。多地域意味着运维团队要具备7x24小时处理跨地域故障的能力值班习惯、故障升级路径、跨地域协调成本都会变高。我强烈建议至少安排两名同学专门负责多地域体系的日常巡检和演练而不是让所有人兼任。多地域部署这条路走完回头看其实没有特别神秘的魔法核心就是把该分离的分离控制面与数据面、该同步的同步数据与模型、该限制的限制流量与配额、该观察的观察Trace与监控。把这些做扎实单地域到多地域的跨越就只是工程量的叠加而不是技术上的生死考验。希望这篇实战记录能给正在踩坑或者准备上车的你一点参考。
返回列表