上回咱们浅聊了抢红包的算法,但如果老板要求你设计一个满足三高(高并发、高性能、高可用)还防盗刷的不会翻车的红包系统,怎样才能像老司机一样把车开稳呢?来,上车,阿雾带你上手写一份行业内的技术调研报告吧。

引言
2014 年春节,微信红包以一个“不经意开放”的入口改变了中国人的过年方式。此后,QQ、支付宝、微博、抖音纷纷入局,将红包从个人社交行为演变为数亿人同时参与的全民狂欢。2015 年微信春晚摇一摇峰值达到 1400 万次 / 秒,2016 年除夕微信红包收发 142 亿个,2017 年 QQ 红包参与用户达 3.42 亿,支付宝“咻一咻”累计互动 1808 亿次——这些数字的背后,是一套从接入层到存储层、从客户端到数据库的完整技术体系。
本文横向对比 QQ、微信、支付宝、微博、抖音五大平台的红包系统设计,梳理了一幅海量高并发金融交易系统的技术全景图。
一、红包系统的架构总览
1.1 三层模型:信息流、业务流、资金流
几乎所有平台的红包系统都采用了三层分离的架构设计。
信息流负责用户交互的请求通信和红包消息的流转——用户摇一摇、点开红包、看到结果。这一层要求极致的响应速度和巨大的吞吐量。微信春晚摇一摇的信息流峰值达到 1400 万次 / 秒,处理逻辑被直接嵌入接入层,实现零 RPC 调用和零数据库存储。
业务流承载红包的核心业务逻辑——包红包、拆红包、计算金额、状态推进。这一层涉及复杂的数据库事务,但巧妙的异步化设计使得抢红包和拆红包两个操作可以被分离:抢(在信息流完成)和拆(在业务流完成)各自独立,互不阻塞。
资金流处理背后的资金转账和入账,由财付通或支付宝的支付系统完成。微信红包系统中,资金流完全异步于用户体验——用户看到“已到账”之前,后台已经通过异步队列完成了对账和转账。

1.2 核心架构组件
各平台的架构虽然在具体实现上各有侧重,但存在高度一致的分层模式:
| QQ 红包 | 微信红包 | 支付宝红包 | 微博红包 | 抖音红包 | 字节红包 | |
|---|---|---|---|---|---|---|
| 接入层 | 一致性 Hash 寻址 | 18 个接入集群,638 台服务器 | LVS → Spanner → Gateway 漏斗模型 | nginx+lua 高 QPS 服务 | 网关层按红包单号路由 | 统一网关层 |
| 逻辑层 | 抽奖系统 + 发货系统 | 红包 API + 业务逻辑服务 | 单元化部署 + 弹性计算 | 模块化独立服务 | Core 服务 + 内存锁排队 | 资产订单中心 + 活动钱包 API |
| 缓存层 | 本地 Memcached | Memcached CAS 原子操作 | 多级缓存 | Nginx 缓存 + L0 本地缓存 | Redis 限流 | Redis + 本地缓存 |
| 存储层 | Grocery(腾讯 NoSQL) | MySQL + SET 化分库分表 | 分布式数据库集群 | Redis + MySQL + MC | MySQL 按 uid 分片 | 账户数据库集群 |
| 消息队列 | 本地文件 + Daemon | RocketMQ | 异步队列 | 异步调用 | MQ 削峰 | MQ 异步入账 |
| CDN | CDN 分发 + 离线包 | 预下载系统,峰值 1Tb/s | CDN + 客户端预埋 | 三机房部署 | 资源预下载系统 | 多端资源预加载 |
1.3 异地多活与南北分布
微信红包系统在架构层面实现了深圳、上海两地部署,订单层南北独立体系,数据不同步。用户就近接入后,系统在红包单号中打上南北标识,后续的抢、拆、查操作根据单号标识路由到对应城市闭环处理。
南北分布架构示意图:

四种请求场景:
深圳用户发 → 深圳用户抢:订单落深圳,深圳闭环,无跨城
深圳用户发 → 上海用户抢:订单落深圳,上海用户通过专线跨城到深圳完成
上海用户发 → 上海用户抢:订单落上海,上海闭环,无跨城
上海用户发 → 深圳用户抢:订单落上海,深圳用户通过专线跨城到上海完成
设计收益:
流量分摊:南北系统各自承载约 50% 的流量,降低单点风险
跨城容灾:支持南北流量灵活调控,可在秒级将全部流量切换到单侧
DB 故障转移:当某地 DB 故障时,可将业务流量调到另一地,实现数据库级容灾
用户数据采用“写多读少”的特性设计:全量存储在深圳,通过 MQ 异步写入,查询时允许一侧跨城。由于用户数据查询入口隐藏较深(在微信钱包中),访问量不大且实时性要求不高,后台通过定时对账保证数据完整性即可。
二、高并发:从百万到千万 QPS 的演进之路
高并发是红包系统面临的第一道技术壁垒。各平台的应对策略虽路径不同,但遵循着共通的设计哲学:分流、排队、异步、降级。
微信红包系统架构全景图:

2.1 SET 化:分而治之
微信红包系统的 SET 化是高并发设计的典范。早期架构中,所有订单 SERVER 共用同一接入层,连接所有 DB,存在三大问题:DB 连接数爆炸、单机故障影响放大、扩缩容困难。SET 化改造后,系统按物理 DB 机器划分 SET,每个 SET 包含独立的 DB 接入机和存储节点。
SET 化架构对比图:

SET 化设计要点:
按订单号划分:红包单号中的
xx位(如201704160123456789中的倒数 3-4 位)决定所属 SET三园区部署:同一 SET 中的 DB 接入机对等部署在三个园区,任一园区故障不影响服务
请求路由:业务逻辑层按订单号 hash 到对应 SET 的 SERVER,再 hash 到具体 DB
故障隔离:单组 DB 故障仅影响对应 SET(如 100 组 SET 则影响面仅 1%)
这套设计将海量并发洪流分散为多股小流,单组 DB 的并发性能因此提升了约 8 倍,同时控制了 DB 连接数并隔离了故障影响。
QQ 红包则采用一致性 Hash 寻址,保证同一用户的请求落在同一台抽奖逻辑机器上,配合本地 Memcached 缓存,大幅减少了对存储层的查询压力。
支付宝采用了单元化(LDC)架构,将应用服务器按用户维度划分到不同的逻辑数据中心,每个单元独立承载业务流量。
抖音在设计后续规划中明确提出服务 SET 化方向:将 Server 和对应存储划分为独立 Set,实现流量拆分和故障隔离,并在 Set 之间建立数据备份。
字节红包的多端统一架构: 2022 年字节春节活动需要支持八端 APP(抖音/抖音火山/抖音极速版/西瓜/头条/头条极速版/番茄小说/番茄畅听)的奖励互通,面临 360w QPS 的发奖峰值。系统通过资产订单中心收敛八端入账链路,提供统一接口协议,并通过 actID(基于手机号生成的唯一标识)打通不同账号体系,实现奖励数据在八端的互通查询。
2.2 请求排队串行化
微信红包系统设计了一个精妙的 FIFO 排队机制:同一红包的拆红包请求在逻辑 Server 层按红包 ID 排队,串行进入 DB 执行事务操作。这从根本上消除了 DB 层面的“并发抢锁”问题。同时,利用同机部署的 Memcached CAS 原子操作,控制同时进入 DB 的请求数,超出阈值则直接拒绝。
抖音红包面对的是视频 Feed 流场景——用户刷视频时才会触发红包领取,天然实现了流量打散。因此抖音选择了相对简单的方案:使用 Redis 按红包单号限流(允许剩余个数 ×1.5 的请求通过),并在 Core 服务内基于 Channel 实现内存锁排队,将 DB 锁冲突转移到廉价的内存资源中处理。
2.3 漏斗型限流
支付宝构建了一个经典的漏斗模型来处理峰值 2.95 亿次 / 秒的请求洪流。
支付宝漏斗限流模型:

奖品发放能力被精确控制在 100 万 / 秒,使得 6000 万个现金红包可以在几分钟内平稳发完,而不是瞬间被秒光。
2.4 异步削峰
微信摇一摇系统将抢红包(信息流)和账务处理(业务流 + 资金流)彻底异步化。接入服务直接处理摇一摇逻辑并发放红包(零 RPC 调用、零数据库存储),抢完红包后请求进入异步队列,再由支付后台完成后续的账务逻辑。
拆红包入账异步化流程图:

微信红包的拆红包入账异步化是信息流与资金流分离的经典案例:
拆红包时: DB 中记下拆红包凭证(快操作),立即返回用户“已抢到”
异步入账:通过 MQ 异步请求转零钱入账(慢操作)
补偿机制:入账失败通过补偿队列重试
对账保障:红包凭证与用户账户流水对账,保证最终一致性
这一设计的理论基础是快慢分离:用户抢完红包只关心详情列表中的“最佳手气”,很少立即查看零钱是否到账,因此只需展示拆红包凭证即可,真实入账可异步完成。
QQ 红包的发货系统使用 RocketMQ 实现异步削峰:抽奖系统将发货请求写入消息队列,礼券发货模块按各业务的限速阈值均匀调用业务接口。实现了“快慢分离”——现金通道和礼券通道互不干扰,礼券发放的延时不会影响现金红包的实时到账。
抖音的 B2C 红包补贴发放同样采用了 MQ 削峰方案:用户参与活动后先下发加密 Token,补贴入库异步完成,用户在核销时再主动触发入账。
字节红包的同步 vs 异步入账权衡:面对 180w TPS 的现金红包发放峰值,字节团队对比了两种方案:
同步入账:需要 1152 个数据库实例,成本极高但开发简单
异步入账:仅需部分资源,通过 MQ 削峰,但需要处理入账延迟和补偿逻辑
最终采用混合方案:大额红包实时转账,小额红包入队列异步转账,极端情况下所有红包异步入账并事后凭单据批量入账,在成本与体验之间取得平衡。
三、高可用性:从 99.99% 到除夕零故障
3.1 两地三中心与 SET 隔离
微信红包系统在两个城市部署,每个城市至少三个 IDC,每个服务在三个 IDC 之间均衡部署,且冗余三分之一服务能力。微信后台实现了基于 Quorum 算法的 KvSvr 存储系统,在三个数据园区之间保证数据的强一致性——即使一个园区完全不可用,另外两个园区也能无损承接全部请求。
SET 化的另一个关键收益是故障隔离。早期架构中,所有订单 SERVER 连接所有 DB,一组 DB 性能下降会拖垮整个系统。SET 化后,每组 DB 只影响对应 SET 的订单 SERVER,影响范围从 100% 降到 10%(若扩到 100 组则降到 1%)。
3.2 DB 故障自愈
微信红包系统实现了一个巧妙的 DB 故障自愈机制,这是 SET 化架构带来的关键能力。
DB 故障自愈流程图:

故障自愈流程:
故障检测:订单 SERVER 监控 DB 失败情况,单位时间内失败次数达到预设值时直接报错
订单号切换:业务逻辑层写发红包订单失败时,生成另一个 SET 的订单号重试
流量绕行:新发红包请求的订单号自动落到健康的 SET,完全绕过故障 DB
存量保护:已发未拆的红包等待机器恢复或过期退款,不产生增量压力
效果:故障后业务自愈,新业务无影响,用户几乎无感知。这一设计将传统的“故障 → 人工介入 → 切换恢复”流程缩短为“故障 → 系统自动绕行”,恢复时间从分钟级降至秒级。
3.3 柔性降级
QQ 红包系统中,个性化红包业务设计了多层次的容灾措施:个性字体提前绘制并缓存到本地、资源预加载到 CDN、功能开关实时控制降级。当个性红包系统异常时,可以平滑退化为普通红包,用户发红包的核心体验不受影响。
微信春晚摇一摇系统同样预设了多级降级方案:红包文件按时段切分,某个园区故障时保证下一时段的红包能通过其他园区正常发放;客户端在服务器控制下减少请求频率;当红包发放速度超过后端处理能力时,异步队列积压保证用户请求不失败,仅入账延时。
微信红包系统的多层柔性降级:
下单 cache 故障降级 DB: cache 故障时降级为直接落地 DB,使用 ID 生成器独立生成订单号
抢时 cache 故障降级 DB: cache 故障时降级 DB 查询,同时打开 DB 限流保护开关
拆时资金入账多级柔性:
正常:大额红包实时转账,小额红包入队列异步转账
降级:所有红包进队列异步转账
极端:实时流程不执行转账,事后凭单据批量入账
用户列表降级: cache 中只缓存两屏,系统压力大时限制用户只查两屏
手 Q 红包的柔性设计从用户核心诉求出发:看到礼包列表、选择区服、领取到账。礼包内容作为前端静态数据预下发,后台接口只提供排序,失败了有默认列表;领取操作在 RocketMQ 故障时可打开容灾开关,走分时段对账替代实时发货。
补充说明:
1、下单 cache 故障降级 DB有关键保护措施:
预订单机制的缓冲:
正常情况:订单先写 cache(轻量操作),支付成功后才写 DB Cache 故障时:直接写 DB,但发红包需要支付这个天然门槛限制了写入速度 用户支付操作本身就是一个"限流器",不会像查询那样瞬间打爆 DB
ID生成器的独立性:
使用独立的 ID 生成器
不依赖 cache 的
incr操作保证 cache 故障时订单号生成不受影响

具体的限流保护措施:
令牌桶限流
根据 DB 实际承载能力设置 QPS 上限(如 5000 QPS)
超出部分直接拒绝,返回"系统繁忙,请稍后重试" 宁可牺牲部分用户体验,也要保证核心系统不崩溃
熔断器机制
监控 DB 响应时间和错误率 超过阈值时快速熔断,避免雪崩 熔断期间直接返回降级响应
负载脱落(Load Shedding)
根据 DB 负载动态调整通过率 负载 < 50%:全部通过 负载 50-80%:通过 50% 负载 > 80%:通过 10%,其余拒绝
排队机制
前面提到的 FIFO 排队在这里发挥作用 将并发请求串行化,减少 DB 锁冲突 队列满了直接拒绝新请求
3、为什么要降级到DB
回到最初的问题:既然会增加DB压力,为什么不直接返回错误?这里涉及到业务优先级的权衡:
场景1:发红包(下单)
必须保证成功:用户已经支付了,不能因为 cache 故障就让用户发不出红包
流量相对可控:发红包需要支付操作,天然限流
降级策略:直接写 DB,配合支付限流,DB 压力可控
场景2:抢红包(查询+写入)
部分失败可接受:红包本来就是"先到先得",晚来的抢不到很正常
流量巨大:一个红包可能被几百人同时抢
降级策略: 1. 开启DB限流保护 2. 通过的请求降级读DB 3. 被限流拒绝的请求返回“红包已抢完”或“系统繁忙” 4. 用户会以为是网络慢或红包被抢光了,体验上可接受
场景3:拆红包(资金入账)
正常:大额红包实时转账,小额红包入队列异步转账 降级:所有红包进队列异步转账 - 极端:实时流程不执行转账,事后凭单据批量入账
这里完全绕过了 cache 故障的影响:
拆红包凭证写入 DB(必须保证) 资金入账走异步队列(可以延迟) 即使 DB 压力大,也只影响入账速度,不影响用户"抢到红包"的体验

只有故障 SET 的 cache 降级到 DB 其他 SET 正常运行 新红包可以通过 DB 故障自愈机制路由到健康 SET
影响面从 100% 降至 10%(假设 10 个 SET)
- 限流保护:严格控制降级到 DB 的请求量
- 熔断机制:DB 响应慢时快速失败
- 负载脱落:根据负载动态拒绝请求
- 排队串行化:减少 DB 锁冲突
- SET 隔离:故障影响面控制在单个 SET
- 业务降级:牺牲成功率保证核心功能
- 异步化:非核心操作(如入账)走异步队列
不是维持性能,而是防止雪崩 不是保证体验,而是保证核心功能可用 牺牲 90% 的请求,保护 DB 不被击穿 用户看到的是"系统繁忙"而不是"系统崩溃"
90% 的用户看到"系统繁忙"或"红包已抢完" 10% 的用户成功抢到红包(降级读 DB) 系统整体不崩溃,DB 负载可控 故障恢复后立即恢复正常
3.4 过载保护
微信的过载保护体系覆盖了客户端到接入层的完整链路。客户端的摇一摇操作被计数后定时(1~3 秒)异步批量提交,而非每次操作都发请求。接入层实时计算 CPU 负载,根据负载等级引导客户端使用不同的限速频率。系统设计容量为预估峰值的 2.5 倍——评估 2000 万次 / 秒,实际部署 5000 万次 / 秒的处理能力,除夕当晚峰值 2500 万次 / 秒,负载低于 50%。
QQ 红包通过错峰策略平滑流量峰值:不同分组的用户活动开始时间错开 1~5 分钟;手 Q 2020 年进一步引入基于地理位置的错峰方案——用户按 adcode 划分为区域批次,同一批次的用户在相同时间段内看到活动入口,避免了随机错峰导致的“别人都有入口我没有”的体验问题。
四、存储层:冷热分离与平行扩缩容
4.1 双维度分库表
微信红包的存储层演进经历了从简单分库到双维度分库表的过程。初期按红包 ID Hash 值分为多库多表,随着数据量膨胀,单表性能急剧下降。
双维度分库表设计图:

设计优势:
Hash 维度:将订单打散到不同 DB 服务器,均衡压力
循环日维度:避免单表数据无限扩张,每天都是一张空表
冷热分离:热数据(3 天内)保留在 SSD,冷数据定时迁移到低成本存储
改进后的方案采用双维度分库表:db_xx.t_y_dd,其中 xx/y 为红包 ID Hash 值后三位,dd 为循环天(01~31)。这种设计在红包 ID 维度之外增加了以天为单位的冷热分离维度,使得数据搬迁简单而优雅。
4.2 冷热分离
红包数据的访问热度在发出三天后急剧下降——99% 的用户不会再点开三天前的红包。微信红包利用这一特点,将热数据保留在 SSD 核心数据库中,冷数据定时迁移到低成本的冷存储。这不仅降低了存储成本,也保证了核心数据库的表容量不会无限增长导致性能下降。
QQ 红包在存储层选用的是腾讯内部的 Grocery(而非 CKV),原因在于 Grocery 支持带条件判断的分布式原子算数运算——一次接口调用就能完成奖品计数值与配额的判断以及计数增加——这对奖品发放的精确控制至关重要。(注: Grocery和CKV都是腾讯内部自研的NoSQL 分布式键值存储系统,前者拥有更强的异地容灾能力)
4.3 平行扩缩容
微信红包早期扩容面临严重瓶颈。
早期扩容方案的问题:

改进后的平行扩缩容:

关键改进:
订单号重新设计:预留三位物理机器标识
xxx(如201704160123456789xxx),最多可扩容 1000 组无停服扩容:搭建新 SET 后,逻辑服务层直接开始生成落到新 SET 的订单号,数据自动写入新 DB
无数据迁移:新订单走新 SET,老订单保留在原 SET,通过冷热分离自然淘汰
弹性缩容:停止生成某号段订单,该 SET 的数据随时间推移变为冷数据后下线
整个过程无需停服、无需数据迁移,扩缩容时间从小时级降至分钟级。
支付宝则得益于金融云的高弹性能力,在 1 周内完成了数万台机器的资源调配部署,包括应用服务器、存储和网络设备。
4.4 空间换时间与预订单机制
微信红包系统采用了多种“空间换时间”策略:按不同维度组织表(订单维度、用户维度),适应不同请求场景;非核心表适当冗余以减少多次请求;红包数据中较长的字符串(昵称、祝福语)被切分到 NoSQL 存储,核心表只保留最关键字段。
预订单机制流程图:

预订单方案优势:
支付前:订单落 cache(不落 DB),利用 cache 的原子
incr操作顺序生成红包订单号支付后:订单才真正写入 DB
优点: cache 的轻量操作提升性能,同时减少 DB 废单
订单表字段优化:
关键字段(用户 ID、单号、金额、时间、状态)存 DB
非关键字段(用户头像、昵称、祝福语)只存 cache,可柔性降级
cache 不命中时从实时接口查询补偿,失败则展示默认头像与昵称
这一设计维持了订单表的轻量高效,同时通过多级降级保证核心交易流程不受影响。读写分离、水平切分、垂直切分、锁优化等 MySQL 分布式基础策略被系统性地组合运用。
五、红包算法:从“拍脑袋”到线段分割
红包算法是整个系统中唯一带有“产品玄学”色彩的部分。微信团队的技术人员在 2015 年的分享中直言算法是“一个简单的拍脑袋算法”——不是绝对均等,手气最佳只有一个,先抢到的那个最佳。
5.1 二倍均值算法与上下水位
微信红包的核心随机逻辑是:每次拆红包时,金额在 0.01 元和剩余平均值 ×2 之间随机。一个总金额为 M 元、总个数为 N 的红包,单次可抢到的最大金额为 M × 2 /N(且不超过 M)。这个算法并非事先计算好所有红包金额,而是在拆的瞬间实时计算,更新剩余金额和个数。
红包算法流程图:

算法的精细化实现(上下水位机制):
单个红包直接发完:如果红包只剩一个,本轮直接使用全部金额
计算下水位:假设本轮领到最小值 0.01 元,接下来每次都领 200 元能否领完?
能领完 → 下水位为 0.01 元
不能领完 → 按接下来每次领 200 元计算,剩下的本轮应全部领走
计算上水位:假设本轮领 200 元,剩下的钱还够接下来每轮领 0.01 元吗?
够领 → 上水位为 200 元
不够 → 按接下来每轮领 0.01 元,计算本轮上水位
均值调整:如果上水位金额大于两倍红包均值,使用两倍均值作为上水位
随机取值:获取随机数并用上水位取余,结果比下水位小则使用下水位,否则使用随机金额
这一设计保证了:
不会出现负数或超额:通过上下水位约束
金额不会太悬殊:通过两倍均值限制
红包必定发完:最后一个红包拿走全部剩余金额
经测试,该算法在多次重复(200 次、2000 次)后,每个位置抢到金额的概率均值趋近相等,从随机性来说较为合理。但存在一个细微特征:越后抢的人风险和收益都更大,有较高几率获得“手气最佳”。
5.2 算法的精细化修正
微信红包算法中有一个值得注意的细节:发红包时系统会预先为每个红包保留 0.01 元的最低金额。这意味着随机计算的基础是“总金额减去 N×0.01”,然后再在每个随机结果上加上 0.01 元。这一设计保证了每个人至少能抢到 0.01 元。一个可以验证的极端案例是:发 N 个红包,总金额为 (N+1) × 0.01 元,最后一个领取的必定是手气最佳。
5.3 线段分割算法
业界还有一种更公平的红包算法——线段分割法。将总金额视为一条线段,随机选择 N-1个切割点将其分为 N 份。这个算法的随机区间比二倍均值更大,随机性更强,但传统实现存在随机值碰撞的问题——当切点接近总值时碰撞率显著升高。利用 PHP 的 array_rand 函数优化后(该函数一次取出多个随机值且自带去重),线段分割算法的性能甚至超过了二倍均值。
六、客户端优化:从离线包到智能错峰
6.1 资源预加载
微信春晚摇一摇活动期间,后台通过资源预下载系统提前数天将 H5 页面、图片、视频等静态资源推送到客户端。2015 年除夕,从 2 月 9 日到 2 月 18 日共下发资源 65 个,累计流量 3.7PB,峰值带宽 1Tb/s。资源覆盖率需要达到 90% 左右才有实际意义,最终命中率超过 90%。
QQ 红包使用离线包机制,在用户手机空闲时将红包静态资源预加载到本地,大幅降低 CDN 带宽压力——按 83 万 / 秒峰值计算,一个页面 200KB 即需 158.3G CDN 带宽,离线包将这一压力几乎归零。
2020 年手 Q 红包的资源预下载方案进一步细化:对 CDN 带宽进行离线与在线双维度的公式化预估,根据资源的入口级别分为 4 个等级分配请求峰值,并设计了按需更新的离线包版本检查机制。
6.2 客户端缓冲与流量控制
QQ 红包的移动端优化是最为系统的:用户每次“刷”的操作并不直接发起后台请求,而是客户端本地计数,定时(1~3 秒)异步批量提交;用户已中奖数达到限值后,请求不再发向后台,由客户端直接告知“未中奖”;后台负载升高时,客户端根据负载等级动态减少请求量。
2020 年的手 Q 红包引入了地理位置错峰方案——将全国用户按 adcode 划分为区域批次,同一批次用户在相同时段看到活动入口,批次内再用 hash(uin) % interval 做二次随机错峰。相比早期纯随机的 hash(uin) % gap 方案,这一设计消除了“身边人都看到了我却没有”的体验割裂感。
6.3 柔性策略保护核心业务
2020 年手 Q 红包还设计了一套完善的柔性策略:活动期间禁止刷新消息列表(视觉上有假刷新过程,但不触发拉取离线消息请求);活动页面的 URL 跳过安全检查(减少检查后台压力的同时加快页面加载);离线包页面通过 URL 参数屏蔽更新检查。这些措施确保红包活动的高并发流量不会冲击手 Q 的正常消息收发。
七、创新技术方案:Token 压单与热 Key 优化
7.1 字节红包雨 Token 方案
字节红包在 2022 年春节面临一个核心矛盾:预估发放 180w TPS,实际入账能力仅 30w TPS。如果采用同步入账需要 1152 个数据库实例,成本极高;如果采用异步入账,用户会有十几分钟的入账延迟,客诉量巨大。
字节红包资产中台架构图:

红包雨 Token 创新方案在用户体验和资源成本之间找到了平衡点:
Token 方案流程图:

核心设计:
发红包时生成加密 Token: 使用非对称加密,包含红包金额、actID、发放时间等元信息
Token 双端存储:分别存储在客户端和服务端(容灾互备),每个用户维护一个 Token 列表
Redis 记录入账状态:每次发红包在 Redis 中标记该 Token 的入账状态
合并展示逻辑:用户在活动钱包页看到的数据 = 已入账红包列表 + Token 列表 - 已入账/入账中 Token
提现时强制入账:用户进入提现页或点击提现时,将未入账的 Token 列表强制入账,保证余额准确
Token 数据结构(Protobuf 格式):
type RedPacketToken struct { AppID int64 // 端ID ActID int64 // ActID ActivityID string // 活动ID SceneID string // 场景ID Amount int64 // 红包金额 OutTradeNo string // 订单号 OpenTime int64 // 开奖时间 RainID int32 // 红包雨ID Status int64 // 入账状态}
技术收益:
存储消耗比 JSON 少一半,节约网络带宽和存储成本
用户查看与提现体验不感知压单过程
实际入账能力从 30w TPS 支撑了 180w TPS 的发放峰值
7.2 热 Key 读写优化:本地缓存 + 定时同步
字节红包的活动钱包页需要展示累计收入,面临180w QPS 读取、30w QPS 写入的超高并发。单个 Redis 实例瓶颈仅 3w QPS,传统的“拆分 100 个 key”方案存在读扩散和存储成本高的问题。
热 Key 优化方案架构图:

优化方案:本地缓存 + 中心化存储:
写入流程:
使用 Go 的
atomic. AddInt64原子性累加本地写缓存定时任务(每秒)将本地写缓存复制到临时变量
使用 Redis
incr命令将本地累加的增量值同步到中心化单 key
读取流程:
定时任务(每秒)读取 Redis 单 key 的值
如果获取值大于本地缓存,更新本地缓存
对外暴露的 SDK 直接返回本地缓存值
技术收益:
读写都在本地缓存完成,性能提升数十倍
Redis 仅作为中心化存储,保证最终一致性
大幅减少 Redis 资源占用,降低存储成本
补充说明:
服务重启时有两种潜在的数据丢失场景:
- 本地写缓存未同步:如果服务在定时任务执行之前重启,那一秒内累加到本地写缓存的数据会丢失
最大丢失窗口:由于定时任务每秒执行一次,理论上最多丢失 1 秒内的写入数据
可参考的容灾补偿机制(根据字节红包的其他设计,如token双端存储):
Token方案兜底:由于红包雨使用了 Token 方案,即使累计收入统计有偏差,用户的实际权益(Token)是有保障的
客户端+服务端双存储:Token 同时存储在客户端和服务端,可以作为数据恢复的依据
异步对账:通过后台对账系统定期校验和修正数据
这是一个典型的“最终一致性”方案,服务重启确实可能丢失最后 1 秒的统计数据,但通过 Token 方案保证了用户实际权益不受影响。这种设计在高并发场景下是合理的工程权衡。
7.3 订单号幂等与预算控制
字节红包的订单号设计:
${actID}_${scene_id}_${rain_id}_${award_type}_${stage}从单号设计层面保证不超发,每个场景的奖励用户最多只领一次。
八端奖励互通方案图:

大流量发券的预算控制流程图:

强弱依赖梳理与降级策略:

八、安全体系:资金安全与防刷
8.1 多重加密与密钥管理
微信摇一摇红包系统面临的核心安全挑战是:预红包数据存放在接入机上有被攻陷获取或篡改的风险。解决方案是分层加密——预红包数据使用密钥加密后部署,密钥库和解密库独立维护,数据在传输和存储的整个过程中保持加密状态。
更精细的设计是“分散风险”:整个预生成的红包数据使用几百到几千个密钥分别加密,单个密钥加密的红包资金量控制在 20~30 万元。解密库还支持密钥 ID 的白名单和黑名单机制,未被使用的密钥不可被利用,确认泄漏的密钥即时拦截。
红包数据被极限压缩到每条 26 字节(红包 ID、金额、批次 ID、密钥 ID 压缩到 16 字节),百亿级红包的总数据量因此控制在可管理的范围内。
8.2 对账体系
微信红包系统构建了多层对账机制来保障资金安全。流水系统定时对领用失败的请求进行重做和对账;红包系统的订单数据与微信支付的订单数据需要对账以保证资金一致性;订单数据与用户收发记录对账以保证列表完整性;已拆红包数据与预红包数据的对账是最后的兜底——只有在完成这笔对账后,才会真正执行转账入账。
大额红包(约占 10%)被导入高速 KV 缓存中,拆红包时即时校验并即时入账;未被命中的红包则等待对账完成后异步入账。这平衡了资金安全和到账体验。
手 Q 游戏红包的发货系统同样建立了完善的对账补送机制:每个小时运行一次增量对账,计算应发流水 - 实发流水 - 队列堆积流水得到补发流水,再调用发货接口补送。配合订单号的唯一键去重,保证了“不多发也不漏发”。
8.3 防刷策略
微博红包的防刷体系基于用户行为分析:通过注册环节拦截机器注册账号、通过验证码和身份验证提高自动化登录门槛、通过实名认证和微博动态计算账号质量、通过实时登录状态和常用设备判断是否正常用户。
微信摇一摇系统主要通过 Cookie + Agent 本机校验来防止用户超领。对于“人海战术”(持有几万甚至几十万个账号批量抢红包),微信团队承认没有完美方案,主要依靠大数据分析用户养号行为进行识别和拦截。
九、平台对比:殊途同归的技术选择
9.1 场景决定架构
不同平台的红包系统因为产品形态的差异,在关键技术选型上呈现了有趣的分化。
微信的场景是社交群聊,一个群红包同时被几百人争抢,面临最极端的单点并发热点问题。因此微信选择了 SET 化 + 请求排队 + 二倍均值实时计算这条路径。
QQ 的场景更为复杂——刷一刷、AR 红包、答题红包,每种玩法都需要抽奖系统的支持。因此 QQ 的架构重点在于抽奖系统的配额管理(精确控制发放速率)、流水系统(抽奖记录的异步持久化)和发货系统(快慢分离)。
支付宝的场景是春晚“咻一咻”,互动次数达到 1808 亿次,远超其他平台。支付宝的应对策略体现了阿里的技术基因——漏斗型限流、LDC 单元化、全链路压测和金融云的高弹性能力。
微博的场景是社交媒体,红包面向所有微博用户开放,防刷是最大挑战,因此微博将大量精力投入到账号质量分析和多级监控体系上。
抖音的场景是视频 Feed 流,用户通过刷视频发现红包,天然实现了流量打散,热点并发问题反而较轻。抖音的挑战更多在于通用红包系统的抽象设计、补贴大流量的异步处理,以及压测脚本如何模拟“发-领-查”的全链路真实行为。
9.2 核心数据对比
| 维度 | 微信 | 支付宝 | 微博 | 抖音 | |
|---|---|---|---|---|---|
| 峰值请求 | 83 万/秒 | 1400 万摇/秒,76 万收发/秒 | 2.95 亿次/秒(咻一咻) | 平时峰值 10 倍 | 未公开 |
| 活动规模 | 3.42 亿用户,37.77 亿红包 | 142 亿收发(除夕) | 1808 亿次互动 | 1.34 亿用户,8 亿次抢 | 未公开 |
| 核心架构 | 一致性 Hash + 本地缓存 | SET 化 + 请求排队 | 漏斗限流 + LDC | 模块独立 + nginx+lua | 内存锁 + 异步削峰 |
| 存储方案 | Grocery(腾讯 NoSQL) | MySQL 双维度分库表 | 分布式数据库集群 | Redis + MySQL | MySQL 按 uid 分片 |
| 算法特点 | 配额分级 + 平滑限频 | 二倍均值实时计算 | 奖品控制系统 | 未公开 | 预拆分 + 锁粒度细化 |
| 主要难点 | 多业务系统协调 | 极端并发抢锁 | 超大规模弹性计算 | 防刷体系 | 全链路压测脚本 |
9.3 共性与趋势
尽管场景各异,所有平台的红包系统在几个方向上是高度一致的。信息流与资金流的异步分离是最核心的设计原则——用户的核心体验(抢到红包)必须在尽可能少的环节内完成,账务处理可以延后。多层缓存的系统覆盖——从 CDN 到客户端本地缓存,从接入层内存到分布式缓存,层层削减到达数据库的流量。对账兜底的安全理念——不假设任何环节不出错,而是通过多级对账保证资金安全的最终一致性。SET 化或单元化的架构方向——从微信的 SET 化到支付宝的 LDC 到抖音的 Set 化规划,隔离故障、平行扩展是行业共识。
十、结语
红包系统本质上是一个极端场景下的分布式金融交易系统——它在几分钟内承载平时数月的交易量,要求资金绝对安全、用户体验丝滑流畅。这个场景逼迫着技术团队在看似矛盾的需求之间找到精妙的平衡点:实时随机算法与资金精确对账、零数据库操作与事务一致性保证、海量并发与系统资源有限。
这些技术跨越了 QQ、微信、支付宝、微博、抖音五个平台,时间跨度从 2015 年到现在,共同构成了一幅中国互联网高并发系统设计的演进图谱。它们的价值不仅在于技术细节本身,更在于展示了一个原则:在极限压力下,最有效的方案往往是做减法——缩短关键路径、分离非核心逻辑、在离用户最近的地方解决问题。
夜雨聆风