5.1 大促峰值实战复盘


文档摘要

5.1 大促峰值实战复盘 当我们把「接入削峰、缓存减负、路由提质」三件套讲完,最容易产生的错觉是:每一层都配好了,系统就稳了。但真实世界不会按你写的文档出牌。这一节我用一次真实感很强的大促复盘,把前四章的打法放进同一个时间轴,看它们在「QPS 从 5 万飙到 120 万」的那几十分钟里,到底是怎么咬合、又在哪里差点翻车的。 复盘的起点:不是「会不会崩」,而是「崩在哪里用户无感」 先说背景(量级为示意):某对话类产品,日常 QPS 约 5 万,大促零点峰值冲到 120 万,是日常的 24 倍。更麻烦的是,这 120 万不是均匀来的——零点前 3 分钟是一个陡峭的尖峰,紧接着是持续 20 分钟的高位平台,之后缓慢回落。特征是典型的「尖峰 + 长尾」。

5.1 大促峰值实战复盘

当我们把「接入削峰、缓存减负、路由提质」三件套讲完,最容易产生的错觉是:每一层都配好了,系统就稳了。但真实世界不会按你写的文档出牌。这一节我用一次真实感很强的大促复盘,把前四章的打法放进同一个时间轴,看它们在「QPS 从 5 万飙到 120 万」的那几十分钟里,到底是怎么咬合、又在哪里差点翻车的。

复盘的起点:不是「会不会崩」,而是「崩在哪里用户无感」

先说背景(量级为示意):某对话类产品,日常 QPS 约 5 万,大促零点峰值冲到 120 万,是日常的 24 倍。更麻烦的是,这 120 万不是均匀来的——零点前 3 分钟是一个陡峭的尖峰,紧接着是持续 20 分钟的高位平台,之后缓慢回落。特征是典型的「尖峰 + 长尾」。

团队当时的目标很明确,不是「绝对不丢请求」,而是**「付费用户和高价值会话 0 感知,免费用户的轻微延迟可接受,绝不出现大面积 5xx」。这个目标的措辞很重要:它一开始就定了优先级**——不是所有流量平等,而是分层的。这正是第 2 章「限流哲学」里反复强调的:限流不是把人挡在门外,而是把有限资源先留给最关键的人。

大促峰值的形状与分层目标

第一层咬合:接入层削峰,把「不可控」变成「可控排队」

零点前 3 分钟,连接数瞬间翻倍。如果按日常配置,单机 fd 和连接表内存会先被打爆——这是第 2 章讲过的「连得住」问题。当时接入层做了三件事:

  1. 四层 LB 先卸载:把海量长连接接在 L4,避免直接冲击七层网关;连接表的内存预算提前按峰值预留,而不是按需增长(按需增长在尖峰时恰恰会来不及)。
  2. 令牌桶 + 优先级排队:这是关键。普通用户的请求进入一个带令牌桶的队列,令牌耗尽时不是拒绝,而是排队等待(排队上限内);付费用户走一条独立的高优先级通道,令牌配额单独保留。结果就是:免费用户在尖峰时可能多等 200~500ms,但付费用户几乎无感。
  3. 背压外溢:七层网关发现下游模型路由层开始变慢时,主动减速接收,而不是无脑转发把下游冲垮。

这里值得停下来想一个问题:为什么是「排队」而不是「拒绝」?因为对话产品不是抢购秒杀——用户发一句「在吗」被拒了,他可能就走了,且不再回来。排队只是多等几百毫秒,体验上仍「活着」。这就是第 2 章说的「堵得住」的真谛:堵的不是用户,是洪峰的势头。

接入层削峰与优先级排队

第二层咬合:缓存把模型调用「打折」,尖峰下救了 GPU 一命

如果 120 万 QPS 全部真实打到模型,GPU 集群会瞬间被压垮——这根本不是加卡能解决的(你不可能 3 分钟内扩出 24 倍的卡)。这时候第 3 章的缓存就成救命层了。

复盘里最亮眼的一个数据是:语义缓存把模型实际调用量削减了约 35%。怎么做到的?大促期间大量请求是「活动规则问答」「优惠计算」「重复的热门话题」,这些语义高度重复的请求,即使措辞不同,命中缓存后直接返回,根本不进模型。再加一层「上下文压缩」——把长对话历史压缩成摘要再进模型,单次 token 消耗也明显下降。

但这里有个差点翻车的点:缓存的热点 Key。活动主会场的相关问答,几乎同一时刻被百万级请求击中,如果 Key 设计成「话题 + 时间戳」这种带随机量的,缓存根本命中不了;团队把它改成「话题 + 标准化语义向量哈希」,热点才真正被兜住。这和第 3 章讲的「缓存键设计」完全对得上——Key 设计错了,缓存就是摆设。

缓存减负与热点Key命中

第三层咬合:路由把请求「挑着调」,成本掉下来体验没掉

即便削峰 + 缓存之后,剩下的真实模型调用仍有几十万 QPS。这时第 4 章的路由上场。复盘里最实在的一个结论是:小模型承接了约 60% 的简单问题,GPU 成本下降约 40%,而用户侧感知的「答得变差」比例不到 2%

为什么能这么省?因为大促流量里有大量「格式转换、活动规则、闲聊问候」类请求,小模型完全胜任。路由层按「难度 + 成本 + 延迟」三维,把这类请求稳定导给小模型,只把真正复杂的多步推理、代码生成留给旗舰。更关键的是合规硬约束:涉及金融、医疗的场景,路由直接锁地域、锁指定模型,优先级高于成本——这一点在峰值下也不能松动,否则就是合规事故。

但也暴露了一个坑:分类器在尖峰初期误判率短暂升高(因为流量结构突变,训练分布偏移)。团队的做法不是「硬扛」,而是给分类器加了一条「置信度低于阈值就走默认强模型」的兜底,宁可多花点钱,也不赌关键请求。这正是第 4 章说的「路由层自身不能成为单点,且要有失败默认链路」。

路由分层与兜底

第四层咬合:多供应商容灾,单点故障无中断

大促最怕的不是「压力大」,而是「压力大 + 某供应商恰好挂了」。复盘当晚,主供应商其中一个区域确实出现了抖动。但因为第 4 章编排层早就配了多供应商容灾 + 总预算护栏,流量在秒级切到备用供应商,用户侧只是「某条回答稍慢」,没有中断。

值得强调的是「总预算护栏」:切换供应商不是为了无限兜底,而是设了成本上限——如果备用供应商价格过高,策略会自动收敛到「只保核心链路」,非关键请求允许排队甚至降级,而不是无脑全量切过去把账单也冲爆。这是把「可用性」和「成本」放在同一架天平上权衡,而不是顾一头。

多供应商容灾与预算护栏

四层协同的全景:它们是怎么咬合的

把上面四层放在同一张图里,你会发现它们的关系不是「串联」,而是「层层减负 + 各自兜底」:

  • 接入层把 120 万砍到「排队后可控的流入」;
  • 缓存再把流入里的 35% 直接截胡,不进模型;
  • 路由把剩下的请求按难度分拣,60% 走小模型;
  • 容灾在任一环节出问题时,保证「不中断、不破产」。

每一层都在为下一层减负,同时每一层都有自己的失败默认链路。这才是「协同」的真正含义——不是谁依赖谁,而是谁都能在别人出问题时兜住。

四层协同全景与各自兜底

复盘里哪些是可复制的,哪些只是运气

诚实复盘,必须区分这两种。

可复制的(请立刻沉淀成清单):

  • 接入层「优先级排队而非拒绝」的设计哲学;
  • 缓存 Key 用「标准化语义哈希」而非「带随机量的拼接」;
  • 路由分类器「低置信度走默认强模型」的兜底;
  • 容灾「带成本护栏的切换」而非无脑全切。

只是运气的(不能当经验):

  • 当晚备用供应商恰好有余量——这不可控,平时就要做容量预留和演练;
  • 尖峰形状「预测得比较准」——真出意外形状(比如被刷量)时,上述机制能否撑住要打问号。

我的建议是:把「可复制」那四条写成你的大促作战清单,每半年做一次故障演练(故意掐掉一个供应商、故意放大尖峰),验证兜底链路真的通,而不是纸面通。

一个容易被忽略的第五个细节:排队超时的预期管理

5.1 讲了接入层「排队而非拒绝」,但排队不是无限的。尖峰持续 20 分钟,如果用户的请求在队列里排了 10 秒还没出去,体验同样会崩。所以接入层还必须配「排队超时」:超过阈值的请求,要么返回「系统繁忙,请稍后再试」的友好态,要么降级到一个极简应答(比如「当前咨询量大,已为你预约,稍后回复」),而不是让用户对着转圈圈干等。

这背后是一个被很多人忽视的命题:延迟也是一种拒绝,只是更温柔。你用排队换来了「用户没被拒」,但排队太久本质还是把用户推走了。所以排队上限、超时阈值、降级话术,三者必须一起设计,不能只配令牌桶就完事。大促复盘里,团队把免费用户的排队上限设为「不超过 800ms 自动降级」,换来的就是「虽然慢,但每次都有回应」的体感——这比「一半请求转圈超时」好太多。

把四层收益量化成一张总账

最后,把前面四层的收益合并成一张总账,你会更清楚「协同」到底值多少钱(量级为示意,用于讲逻辑):

动作 量化收益(示意) 用户侧感知
接入层 优先级排队 付费用户 0 感知 免费用户多等 200~500ms
缓存层 语义缓存截胡 模型调用 -35% 无(命中即返回)
路由层 小模型承接 GPU 成本 -40% 变差 <2%
容灾层 多供应商切换 故障 0 中断 偶发稍慢

这张表也是你向老板、向业务方证明「架构投入值得」的最硬材料:每一层的收益都能被量化,叠加起来就是「扛住 24 倍峰值 yet 成本可控」。我反复说「用数字说话」不是客套,而是因为架构的价值,只有被量化成总账,才会在资源争夺战里活下来。

给你的可复用清单

如果你也要扛一次类似峰值,这张清单可以直接拿去改:

  1. 提前按峰值预留连接表内存,不要运行时按需增长。
  2. 令牌桶 + 优先级排队,付费/高价值流量单独配额,绝不「一刀切拒绝」。
  3. 语义缓存 Key 用标准化语义哈希,热点话题单独压测命中率。
  4. 路由分类器设置信度兜底,低置信度默认走强模型,不赌关键请求。
  5. 容灾切换必须带成本护栏,防止「保住可用性却冲爆账单」。
  6. 大促前做一次真实故障演练,验证每一层的失败默认链路真的通。

到这里,5.1 的复盘就完整了:从接入层的优先级排队,到缓存的热点兜底,到路由的置信度兜底,再到容灾的成本护栏,最后补上排队超时的预期管理——六个动作构成一张可复制的大促作战清单。

小结:这一节的复盘想说的不是「我们多厉害」,而是「分层架构在真实洪峰下是怎么咬合的」。接入削峰、缓存减负、路由提质、容灾兜底,四层各自减负、各自兜底,才让 120 万 QPS 从「系统噩梦」变成「可管理的流量」。下一节,我们把视角拉远,看扛住之后,下一步该往哪里演进。


发布者: 作者: 转发
评论区 (0)
U