ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

电商AI系统灾备:优雅降级、多活架构与特征容灾

电商AI系统灾备:优雅降级、多活架构与特征容灾 做电商AI系统的灾备难度和做交易系统的灾备完全不是一个量级。交易系统挂了用户看到的是报错页面、下单失败问题定位和影响边界都很清晰AI系统挂了很多时候用户根本看不到任何报错他只会在心里觉得这个App今天是不是不对劲推荐的东西怎么乱七八糟的搜索结果怎么这么蠢领券怎么老是被风控拦下来。这种无声的劣化比直接宕机更让架构师头疼。以头部电商平台为例大促期间每天有数亿用户依赖推荐、搜索、价格弹性、营销权益、智能客服这些AI服务做决策任何一个环节的可用性打了折扣损失的都是真金白银的成交和用户体验。这篇文章想聊的就是这个命题架构师要怎么做才能让电商AI服务在机房故障、数据链路异常、模型推理集群雪崩这类极端场景下仍然能给出足够好的决策我结合这些年在高并发系统、AI工程化领域看到的大量一线实践以京东这类头部电商平台的AI系统灾备场景为引子把背后的架构设计思路、核心取舍、落地细节一次讲透。适合正在做AI平台架构、数据平台架构或者负责电商核心链路稳定性的工程师和架构师参考。1. 电商AI系统为什么是灾备难度最高的业务形态之一很多人对灾备的理解还停留在数据库主备切换多机房部署定期备份快照这个层面。这套思路应对传统业务系统没问题但套在电商AI系统上处处都是窟窿。1.1 AI服务与普通交易服务的故障容忍度差异普通交易服务强调强一致和快速失败。数据库挂了、接口超时了直接抛错、有限流、有降级页用户的预期是系统忙请稍后再试。但AI服务不一样它的核心价值是持续给出决策——推荐列表不能因为模型服务挂了就整个空白搜索引擎不能因为向量检索超时就返回空结果。哪怕只能返回次优结果也比返回错误或者空结果好得多。这就导致一个反直觉的结论AI系统的灾备目标并不是系统不挂而是系统挂了之后用户体验的劣化幅度要在可接受范围内。用行业里的黑话说就是 graceful degradation优雅降级。做到这一点比单纯做数据复制和机器冗余难多了。1.2 链路长导致故障边界模糊一条电商AI请求从用户点击到最终展示结果中间往往要穿过API网关、意图识别、召回、粗排、精排、重排、业务策略控制、特征服务、模型推理集群好几个环节。每个环节都有独立的依赖还涉及在线特征、离线特征、实时特征等多路数据源。这里有个很典型的故障场景特征服务是AI链路里最底层、最容易被忽视的依赖。特征服务一旦出现大规模超时上游的推荐、搜索、营销模型会全部拿到空的特征张量。模型面对空特征不会直接报错它只会默默输出一个偏差很大的预测结果推荐出来的商品用户完全不感兴趣。等业务方发现转化率异常下跌的时候故障可能已经持续几个小时了。这种级联失效的排查难度远高于传统服务。传统服务看监控、看日志、看链路追踪就能定位AI服务要靠评估指标波动、特征覆盖率、模型输出的分布变化来反推对架构师的全局视野要求很高。1.3 电商场景放大了AI灾备的复杂度以京东这种体量的平台为例AI系统承载的不是一个模型而是几十上百个模型组成的模型族谱有排序模型、有召回模型、有价格预测、有用户分层、有智能客服对话、有供应链需求预测。这些模型之间还有依赖关系用户分层的输出可能作为价格模型的输入特征价格模型的输出又影响推荐排序的候选集。更麻烦的是电商的业务规则天然是动态的——大促期间要调整流量策略新品上架要冷启动实时竞价要修改出价参数。AI系统的灾备方案如果只盯着模型和算力不考虑业务策略配置的同步切流之后就会发生模型没问题但策略配置还是老一套的错位问题。所以电商AI灾备本质上是在治理一个多层依赖、多模型协作、业务规则实时变化的复杂系统。后面聊的每一块设计都是围绕这个复杂度展开的。2. 先定义灾难电商AI系统实际遭遇的几类故障灾备设计的第一步不是写方案而是把所有可能发生的故障场景掰开揉碎列出来。我梳理了电商AI系统里出现频率最高、影响面最大的几类故障按故障域和影响类型做了分类。2.1 基础设施级别机房故障与GPU资源池熔断这是最基础的灾备场景。机房断电、网络分区、光缆被挖断这一类故障的特征是影响面巨大通常整个可用区的所有服务同时受损。AI系统的特殊之处在于它对GPU资源池的依赖——推荐排序、向量召回这些重计算模型推理集群一旦跨可用区断连新请求无法路由到健康的GPU实例整个链路瞬间失去决策能力。GPU资源池的雪崩效应值得单独拎出来说。GPU推理服务有个特点它的排队机制比CPU服务敏感得多。CPU服务线程池满了会快速失败但GPU推理框架通常会做请求排队队列一长不仅延迟飙升还会因为显存占用导致已经加载的模型无法继续推理最终整个实例假死。这个场景下人工介入重启实例根本来不及必须依赖自动化的熔断和摘除机制。2.2 数据链路级别特征服务大规模超时特征服务故障是AI系统灾备里最隐蔽的敌人。它不像GPU集群那样有明显的高负载指标特征服务挂在哪儿了模型不一定立刻报错只是推理质量悄悄下降。典型场景是特征存储的缓存集群出现大量热点。大促开门红瞬间流量是平时的十倍以上特征读取的key分布如果出现严重倾斜少数几个热key所在的缓存分片会被打爆。这时候模型拿不到完整特征只能靠默认值填充排序质量直线下降。更麻烦的是特征服务通常是多路数据源合并读取一路超时会导致整个请求的超时窗口被拉长最终拖垮模型的可用性。2.3 模型服务级别推理集群雪崩与模型文件损坏模型服务自身的故障也分好几种。最经典的是推理集群雪崩流量上涨 - 单实例延迟升高 - 上游重试 - 更多请求堆积 - 实例彻底无响应。电商大促期间重试放大效应尤其明显因为推荐链路本身是嵌套调用的parent接口重试一次子链路可能被重复调用几十次。模型文件损坏是个低频但致命的故障。模型文件部分损坏不会导致服务启动失败但推理结果会系统性偏差。这类故障最可怕的地方在于常规监控根本发现不了只有业务转化率掉下来才有人警觉。所以模型文件的完整性校验和灰度发布机制在灾备设计里必须占据一席之地。2.4 业务策略级配置漂移与规则失效电商AI服务最终输出前往往还要过一层业务策略控制——比如价格区间约束、库存可用性过滤、营销活动黑名单。这层策略通常由配置中心下发灾备切换时如果配置中心的数据没有同步到目标单元就会出现用户看到的推荐商品全部缺货、价格异常之类的乌龙。这类故障虽然不是模型本身的问题但架构师必须把配置同步纳入灾备切换的检查清单。我见过最典型的翻车现场就是模型服务切流成功了但策略配置还留在老单元新单元的服务拿到的是一份过期配置推荐结果里全是已经下架的商品导致切流后转化率断崖式下跌。表格几类故障的特征对比故障类型故障域用户感知主要恢复手段机房/可用区故障基础设施局部服务不可用单元化切流GPU推理集群雪崩计算资源响应变慢/推荐失效熔断、弹性扩容、切轻量模型特征服务超时数据链路推荐质量下降无声降级默认值、多路特征容灾模型文件损坏模型仓库系统性结果偏差灰度发布、版本回滚、完整性校验配置中心漂移业务策略规则错乱配置多单元同步、切换前校验3. 从单机房到多活AI系统灾备的架构演进路线没有一个AI系统是一开始就是多活的。我把常见演进路线拆成三个阶段每个阶段的驱动力都是不同的业务痛点。看完这一段你会理解为什么多活不是靠堆机器堆出来的而是一步步被逼出来的。3.1 冷备阶段能重建但不能切换最早期的做法通常很朴素在线模型服务跑在主集群离线任务定期把模型文件、特征快照备份到对象存储数据库做跨机房同步。这个阶段的核心保障是数据不丢服务能重建但恢复时间是以小时计的。冷备阶段有个常被忽略的技术细节模型文件不是备份了就能直接用。模型文件里记录的特征名、特征版本如果和线上特征服务对不上加载出来的模型就是一个半残废状态推理可以跑但效果不对。所以我一直强调模型备份必须连特征schema版本一起备份否则恢复出来的模型等于废品。3.2 主备切换阶段能切换但切换很痛苦业务对RTO的要求逐渐提高之后就会演进到主备阶段。特征是双写的模型仓库是准实时同步的推理集群在两个机房都常驻主集群负责全量流量备集群空转待命。这个架构最大的问题在于容量成本。备集群为了在切换后能接住全量流量必须按照主集群同样的规模部署但平时完全不承载业务流量。电商大促期间GPU资源本来就紧张备集群还空着吃预算这笔帐很难算平。而且主备切换涉及缓存预热、连接池重建、模型冷启动加载不是一键切域名就完事的实际操作中经常出现备集群容量够但服务启动后模型加载耗时过长导致切换窗口远超预期。主备切换最容易翻车的点发生在备集群长时间空转后的状态漂移。备集群的模型版本、特征数据、配置文件全靠同步任务维持哪怕只滞后五分钟切换时都可能产生明显的效果回退。所以主备切换必须配合常态化的切换演练 数据校验不能把备集群养在温室里。3.3 多活单元化阶段按用户分片流量随时可调成熟的电商AI系统最终都会走向单元化多活。核心思路是按照用户维度做分片每个单元Unit是一个自包含的部署单元拥有完整的AI服务组件——入口网关、特征服务、模型推理、业务策略配置全部在单元内闭环。正常状态下每个单元负责一部分用户流量故障状态下把故障单元的流量整体切到其他单元。单元化之所以适合电商AI系统是因为推荐、搜索这类AI服务天然具备用户维度无状态的特性。单个用户的请求只依赖该用户的历史行为和当前上下文不需要跨单元访问另一个用户的数据。这种特性让按用户维度切流成为可能而且切换对单个用户的影响面可以精确控制。多活的代价是每个单元的数据必须是完整且一致的。用户的特征数据要在所有单元同步模型版本要在所有单元保持一致业务策略配置要确保所有单元同时生效。这背后需要一整套数据复制和一致性校验的机制复杂度比主备阶段高了一个量级但换来的是接近零RTO的切换能力和完全弹性的容量调度。4. 核心设计一模型与推理服务的无状态化改造所有AI灾备方案的底层基础是先让模型推理服务变成一个可以被随时拉起、随时销毁的无状态进程。如果推理服务和本地状态绑得太死任何灾备方案都是空中楼阁。4.1 模型文件与推理进程分离很多团队第一个踩的坑就是模型文件直接放在推理实例的本地磁盘上或者跟着镜像一起打包。这种做法在单机部署时代没什么问题但到了多活架构里就成了灾难——新实例启动要把几个GB的模型文件从镜像仓库拖下来冷启动时间直接拉长到十几分钟。正确的做法是把模型文件放到分布式对象存储里推理进程启动时从远端拉取模型文件到本地缓存目录。这个看似简单的改动解决了几个关键问题实例可以随时弹性扩容新实例不需要重新构建镜像模型版本更新不用发版同一套镜像可以加载不同版本的模型文件故障恢复时任何一台新机器都能快速变成推理节点。以主流电商平台的实践为例模型仓库加对象存储的方案基本已经成为标配。4.2 推理服务的多副本与优雅伸缩无状态化的第二个要求是推理服务可以水平伸缩。这里要聊一个具体的技术点GPU推理服务的扩缩容和普通CPU服务完全不同。GPU显存是硬资源一个实例能同时加载的模型数量和批次大小是有上限的盲目扩容有时候不仅不解决问题还会因为显存碎片化导致更多实例启动失败。业界常见的做法是两层伸缩第一层是实例级伸缩根据GPU利用率和排队长度决定实例数量第二层是模型级伸缩同一个GPU实例内动态加载和卸载不同模型让显存在多个模型之间共享。灾备切换场景下模型级伸缩的价值特别大——故障单元的流量切过来之后存量实例可以优先加载故障单元的核心模型而不是等新实例慢慢启动。4.3 降级到轻量模型电商AI灾备里的王牌手段架构师在灾备设计中最有价值的决断是提前准备一套轻量模型作为兜底方案。重型精排模型效果最好但依赖大量特征、算力消耗高、部署链路复杂轻量模型可能只用几十个核心特征、结构也简单得多效果虽然差一些但胜在健壮——依赖少、启动快、不容易受特征故障影响。故障发生时最忌讳的做法是硬扛着重型模型硬等恢复。正确的思路是分级降级特征服务故障严重时自动把推理链路切换到轻量模型轻量模型也扛不住的时候才退到规则兜底。这一套降级链的切换逻辑应该通过配置中心和自动化决策引擎提前编排好而不是故障发生时靠人工判断。降级策略的设计有个关键原则降级动作本身必须比故障更轻。切换轻量模型的决策要能在毫秒级内完成如果降级逻辑本身还要查一堆依赖、做一堆判断大概率在故障期也执行不了。有时候最原始的规则降级反而是最可靠的——比如推荐服务全部挂了直接展示热门榜虽然个性化没了但用户至少还能看到商品。5. 核心设计二特征数据多活与一致性兜底特征服务是整个AI链路里最容易成为故障放大器的一环。模型挂了影响的是一个环节特征挂了影响的是所有依赖特征的模型。所以在灾备设计里特征数据多活的价值不亚于模型推理多活。5.1 特征存储的跨单元双写与就近读取多活架构下的特征数据必须做到写多份、读就近。在线特征从业务事件产生开始就要同步写入多个单元的特征存储每个单元的模型推理只读本单元的特征数据。这个设计保证了切流之后目标单元已经拥有该用户完整的特征记录不会因为历史特征缺失导致模型效果严重退化。这里要特别注意实时特征的一致性。用户刚发生的点击、加购行为通常会写入实时特征存储。如果双写链路有延迟用户切到新单元后新单元里没有刚刚那次点击的特征推荐结果对用户最新行为的反馈就会慢半拍。在电商场景里这种实时性的劣化直接影响转化率。所以特征双写链路必须做延迟监控正常情况下要求实时特征的跨单元延迟控制在秒级以内。5.2 特征缺失时的默认值策略与兜底填充特征多活做得再好也不能保证百分之百不丢数据。所以每个模型在训练和推理时都必须考虑特征缺失这个分支。好的做法是在训练阶段就引入特征缺失的模拟——把一部分训练样本随机抹掉某些特征让模型学会在特征不完整时仍然给出合理的预测。这样到了线上真的发生特征缺失模型输出的劣化幅度是平滑的而不是直接崩掉。默认值的填充也很有讲究。直接把缺失特征填0或者填均值在很多模型里会产生误导性的信号。更稳妥的做法是给每个特征预设缺失标志位模型可以学到这个特征缺失了本身就是一个状态。以电商推荐为例如果用户历史点击特征全缺失模型不应该把用户当作什么都没干过的新用户来对待而应该认识到这是数据链路故障给出更保守的推荐结果。5.3 离线与在线特征的恢复节奏特征数据还有一个常被忽略的灾备维度离线特征和在线特征的恢复节奏。离线特征通常由T1的批处理任务产出在线特征依赖实时计算。故障发生时优先恢复的应该是实时特征链路因为用户实时的行为信号最不可丢失离线特征由于已经落库恢复起来相对从容但要注意批处理任务堆积导致的数据延迟问题。电商平台经常遇到的一个实际场景是大促期间实时计算集群出现故障Kafka消息堆积实时特征更新停滞。这时候如果只恢复了在线服务没有恢复消息消费链路实时特征会持续老化推荐效果随时间推移越来越差。所以灾备方案里一定要包含消息链路的容量检查和消费延迟的恢复预案否则做的多活只是个空壳。6. 流量调度与切换编排架构师最容易忽视的部分很多架构师把精力都放在了模型和数据的多活上却忽视了最后一道关键环节流量怎么切、切多少、什么时候切回来。切换编排做得不好前面所有的工作都会白费。6.1 网关层的AI服务路由与单元内闭环单元化多活的流量调度核心落在入口网关的智能路由上。网关要能识别每个请求的用户维度标识根据分片规则把请求固定到某个单元。正常的按用户哈希路由在故障切换时存在一个天然问题哈希取模会让每个单元的流量比例相对固定想要把某个单元的流量切走必须依赖网关的路由规则热更新能力。以推荐服务为例网关层的路由策略通常是比例切流 白名单切流的组合。故障发生时架构师不是直接把故障单元流量全部切走而是一步步放大切换比例——先切1%验证目标单元的健康度确认模型效果指标稳定再逐步扩大到10%、50%、100%。这个过程不是人为拍脑袋而是由自动化决策系统根据目标单元的RT、错误率、推荐效果指标动态推进。目标单元一旦出现指标劣化切换自动暂停甚至回滚。6.2 灾备容量规划里的安全系数容量规划是灾备切换能否成功的前置条件。每个单元的日常容量通常按本单元峰值流量的1.5倍到2倍做冗余这部分冗余不只是为了应对业务增长更是为了给故障场景预留切流空间。假设A单元故障流量全部切到B单元B单元要承接双倍流量如果平时只按1倍容量部署切换必然导致B单元过载雪崩。这里有个电商场景特有的细节AI推理服务的容量规划要考虑效果损耗系数。流量切换后目标单元面对的是全新的用户群体缓存命中率下降特征读取压力上升推理批次大小的最优值也会偏移。整体上跨单元切流后的容量需求通常比线性叠加还要高20%到30%。容量规划时不考虑这个余量切换后照样出问题。6.3 全自动切换编排与人工确认按钮切换编排的SOP一定要沉淀成可执行的自动化工单而不是靠人在故障时翻文档。故障发生后从监控告警触发、故障定界、决策是否切换到执行切流、验证恢复、通知业务方这一整条链路都要有相应的编排工具支撑。人工要做的只是在关键决策点做确认而不是在一堆运维命令里手忙脚乱。编排系统里最容易被忽略的是切换后验证这一步。切流不是改个网关配置就完事必须有一套自动化的质量验证手段——在目标单元发一批真实的业务探测请求验证推荐结果非空、响应延迟正常、特征覆盖率达标、转化率监控无异常。只有验证全部通过切换才算真正完成。7. 演练与常态验证灾备能力不是写出来的是练出来的灾备方案写得再漂亮如果一年到头没跑过一次真正的切换演练到了故障发生那天大概率是跑不起来的。这个道理做架构的人人都懂但实际执行层面演练的优先级总是被业务需求挤到后面。我在这里想分享几个关于演练的实践观察。7.1 故障注入用混沌工程验证灾备边界混沌工程在AI系统上的应用重点不在随机杀几个Pod而是要精准地模拟前面提到的那几类高危故障。比如把特征服务的一个分片直接断掉看模型输出的劣化幅度是否符合预期或者把GPU集群的某个型号实例全部摘掉看调度系统能否自动把流量切到其他实例。故障注入最重要的产出不是验证系统没挂而是记录系统在故障下的行为边界。每次演练都要输出一份报告标明哪些环节是按预期降级了、哪些环节出现了预期之外的异常行为。这些发现会反向推动灾备方案和代码逻辑的迭代。我见过不少团队第一次做AI链路故障注入时被吓得够呛因为发现了大量平时根本想不到的隐性依赖。7.2 大促前的全链路压测对灾备的检验电商行业有个不成文的规矩大促前必须做全链路压测。压测的价值每个人都认可但从灾备的角度看压测里藏着一个很关键的问题——你有没有在压测的同时模拟故障大促前的全链路压测通常大家都在验证容量够不够、性能是否达标。真正优秀的团队会在压测中注入故障场景比如压到峰值流量的时候同时把某个单元的特征服务降级掉看系统是否还能维持住全局的 SLA。这种组合场景比单纯压测容量有价值得多因为大促期间最怕的不是流量大而是流量大的时候某个组件顶不住挂掉进而引发雪崩。7.3 回切演练比切过去更难的是切回来大多数团队的灾备演练都停留在切过去这一步很少有人认认真真演练切回来。但实际故障场景里回切才是最考验人的环节。故障单元修复之后流量不可能永远留在临时单元——容量不够、数据延迟、业务规则差异都会要求你切回原单元。回切的动作不是简单地把流量反向切一次它要求原单元的状态已经完全恢复模型版本同步、特征数据追平、缓存预热完成、容量检查通过。任何一项没准备好就贸然回切很可能刚恢复的单元又被流量打垮造成二次故障。回切演练做得多的团队才能真正把灾备能力变成肌肉记忆。8. 架构师在AI系统灾备设计中的几个底线原则最后把这几年做AI系统稳定性和灾备设计的经验沉淀成几条原则。这些原则不是从书本上抄的都是实际踩坑踩出来的。8.1 不引入无法兜底的强依赖AI链路里每引入一个新依赖都要先问一个问题这个依赖挂了我们怎么办如果答不上来这个依赖就不应该在核心链路上。比如某些模型推理依赖外部第三方服务第三方抖动一次推荐引擎跟着遭殃这种强依赖必须做超时控制、熔断和降级预案或者在架构层面直接解耦。在电商AI场景里我见过最典型的反面案例就是为了短期效果提升把一个外部商家的价格接口直接同步嵌入了推荐排序的特征链路结果商家接口在大促期间响应超时整个推荐链路全部被拖慢。这种问题从灾备角度看几乎无解——你永远无法控制第三方服务的可用性只能从架构上把这种依赖降级为异步更新或本地缓存快照。8.2 降级预案比多活架构更优先很多架构师一聊灾备就兴奋地谈单元化、多活、跨城部署但我想泼一盆冷水多活是最高级的手段但不是最优先的手段。对大多数电商AI系统来说先把降级预案做好性价比远远高于硬上多活架构。这里的逻辑是多活架构解决的是机房挂了怎么续命的问题但AI系统里大量故障是局部功能劣化——特征丢了一部分、某个模型效果变差了、算力资源紧张了。这些场景下有成熟的降级链路切轻量模型、降级规则兜底、关闭非核心AI功能就够了不需要大动干戈做全量切流。先盘点核心链路有哪些可以接受的降级档位再考虑要不要投入巨大成本做多活这个顺序不要反。8.3 用SLO驱动灾备投入而不是凭感觉灾备方案要做到什么程度应该有明确的数据指标驱动而不是架构师拍脑袋觉得这个应该做双活那个应该做三副本。核心AI服务建议制定一套完整的SLO体系包括可用性指标、效果指标、延迟指标每个指标对应明确的目标值。哪个指标不达标对应的灾备投入优先级就更高。以推荐服务为例可以把推荐结果非空率设定为可用性指标99.99%以上的请求必须返回非空推荐把个性化效果衰减幅度设定为效果指标故障降级时的效果衰减不能超过日常效果的一定比例。这些指标既指导线上监控告警也指导灾备建设的优先级排序——预算有限的情况下优先投入在那些最容易突破SLO的环节上。回到最开始的问题架构师如何保障电商AI服务答案不是某一个具体的技术方案而是一整套从故障定义、架构设计、容量规划到演练验证的闭环方法论。这里面没有银弹每个决策都伴随着成本与效果的取舍但有一条核心逻辑是不变的——让每一个故障场景都有预案让每一次降级动作都经过演练让每一份灾备投入都有指标可衡量。能做到这三点AI系统的抗风险能力就已经超过了绝大多数电商平台。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进