连载中 4/16

号段进阶:双 buffer 与异步预加载

2026-06-07 · 6421 阅读 · 0 评论 · 0 赞

压测暴露的 RT 毛刺

号段模式上线,日常平稳,大促前全链路压测却暴露了毛刺:99 分位 5ms 的发号接口,隔一阵冒出几个 80ms 的尖刺,间隔大致等于段长消耗完的周期。老王顺着毛刺时间点查,答案就在第 3 篇的设计里:号段用尽那一刻,业务请求线程要同步去 DB 领下一段。DB 平稳时这段路只要几毫秒;DB 一抖动(大促时恰恰最爱抖),领号请求全堵在 DB 行锁上,下游一起排队。

问题本质:取号段的动作发生在请求线程的关键路径上。要消毛刺,就得把这段路挪出去——异步预加载,也就是双 buffer。

双 buffer:发号器里的双跑道

设计思路像机场的双跑道:一个在用,一个在备:

当前段 [1 - 1000]      备用段 [1001 - 2000]
       |
       | 用到 900(10% 警戒线)
       v
后台线程异步领取 [2001 - 3000],放入预备位
       |
当前段耗尽 -> 备用段无缝顶上 -> 再异步预取下一段

三个要点:一是触发时机——当前段消耗到警戒线(常见 10% 到 20%)就启动预取,别等用完,给 DB 预留反应时间;二是切换零成本——备用段在内存里原子换位,请求线程永远只从「当前段」取号,感知不到后台动作;三是持续循环——备用顶上成为当前段的同时,后台马上去领下一个备用,双跑道永远保持。

改造后压测:毛刺消失,99 分位稳定在个位数毫秒。取号段的 DB 访问彻底离开了请求关键路径。

动态 step:段长跟着流量走

段长 step 固定值有个尴尬:设小了,低峰期也会频繁回 DB;设大了,服务重启浪费的号段多,容灾窗口计算也失真。工程化的解法是动态 step(美团 Leaf 的思路):按最近一段时间的发号速率自适应——统计过去若干分钟内的号消耗量,取其数倍作为下一次领取的段长。低峰期段自动变小,大促前段自动变大,DB 访问频率始终维持在合理区间。

老王给发号器加了每小时一次的速率统计,step 在 1000 到 50 万之间浮动,大促当天自动拉满,DB 写压力肉眼可见地平。

容灾时间账:DB 挂了能撑多久

双 buffer 还有第 3 篇没讲透的隐藏价值:把 DB 故障的容灾时间变成可计算的账。算给运营看:

参数数值说明
峰值发号速率1 万个每秒大促下单峰值
当前段剩余最多 30 万警戒线 10% 时正好预取
备用段存量30 万双 buffer 常备
可撑时长约 60 秒60 万存量除以 1 万速率

一分钟,够 DB 主从切换跑完,也够值班同学收到告警。想要更长,把 step 上限调大即可——号段模式的容灾是用内存换时间,而代价只是重启时多废几个号。

预取失败的处理也要定好:后台线程重试加指数退避,连续失败触发告警;内存段见底前最后一搏时,请求线程才允许同步领号——这层兜底平时永不触发,触发说明 DB 真出事了。配合第 3 篇说的已发号段持久化,主从切换回跳的窗口也能被拦住。

小结

双 buffer 一句话:当前段加备用段,异步预取离开关键路径,动态 step 跟着流量走,容灾时间用内存换。到这一步,号段模式已经是生产可用的发号器。但老王的野心不止于此——每秒百万级发号、完全去中心化、连 DB 都不依赖,这就是下一篇的主角:雪花算法。

☕
503

10 年全栈工程师 · 503咖啡馆主理人

#分布式ID#双buffer#异步预加载#动态step#Leaf

评论 (0)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9873 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9294 阅读 · 21 评论 · 287 赞