哪里免费做网站,wordpress主题制作 工具,专业的响应式网站建设,分销商城什么意思视频来源#xff1a;B站 IT老齐 本文为视频学习笔记 扩展整理#xff0c;结合字节跳动、微信等大厂红包雨架构方案。 一、业务背景与核心挑战 1. 业务场景 春节红包雨活动#xff1a;在指定时间段内#xff0c;用户点击屏幕上飘落的红包进行抢夺#xff0c;红包金额随机…视频来源B站 IT老齐本文为视频学习笔记 扩展整理结合字节跳动、微信等大厂红包雨架构方案。一、业务背景与核心挑战1. 业务场景春节红包雨活动在指定时间段内用户点击屏幕上飘落的红包进行抢夺红包金额随机先到先得。2. 核心指标指标数值红包总量10 亿个峰值并发百万级 TPS单次活动时长通常 5~15 分钟核心要求不超发、不漏发、不重领3. 技术挑战高并发读写百万级用户同时点击瞬间流量洪峰数据一致性不能超发红包不能重复领取低延迟用户点击后需毫秒级响应高可用活动期间不能宕机需要完善的容灾方案二、整体架构设计1. 分层架构用户端APP ↓ TCP/HTTP 网关接入层 ↓ 限流、鉴权、防刷 抢红包服务业务层 ↓ Redis Lua 原子操作 Redis 集群缓存层 ↓ 异步入账 MQ 消息队列 ↓ 入账服务 → DB持久层2. 核心流程活动前运营配置红包总金额和个数 → 预拆红包 → 写入 Redis活动中用户点击 → 网关限流 → 执行 Lua 脚本抢红包 → 返回结果活动后异步入账 → 对账校验 → 数据归档三、红包预生成预拆包1. 为什么要预拆方案优点缺点实时拆包节省存储高并发下计算压力大延迟高预拆包推荐抢红包速度最快逻辑简单需要提前占用 Redis 存储2. 拆包算法二倍均值法每次拆包金额 random(0.01, 剩余金额 / 剩余个数 * 2)保证每个红包金额随机但相对均匀最后一个红包取剩余全部金额。3. Redis 存储结构# 红包队列List预拆好的红包按顺序存入 Key: red_packet:pool:{activityId} Type: List Value: [{id:1,amount:1.5}, {id:2,amount:3.2}, ...] # 用户领取记录Hash防止重复领取 Key: red_packet:claimed:{activityId} Type: Hash Field: userId Value: {redPacketId, amount} # 红包领取计数String快速判断是否已抢完 Key: red_packet:count:{activityId} Type: String (atomic counter)四、抢红包核心逻辑Redis Lua1. 为什么用 Lua 而不是 Redis 事务对比项Redis 事务MULTI/EXECLua 脚本原子性EXEC 前 Key 仍可被修改真正的原子执行隔离性无法保证中间状态隔离脚本执行期间不会被打断灵活性不支持条件判断支持 if/else 等逻辑适用场景简单批量操作高并发竞争场景推荐2. Lua 脚本核心逻辑-- 1. 检查用户是否已领取防重localclaimedredis.call(HEXISTS,KEYS[2],ARGV[1])ifclaimed1thenreturnnil-- 已领取直接返回end-- 2. 从红包池中弹出一个红包原子操作localpacketredis.call(LPOP,KEYS[1])ifnotpacketthenreturnnil-- 红包已抢完end-- 3. 记录领取信息redis.call(HSET,KEYS[2],ARGV[1],packet)returnpacket整个抢红包逻辑在 Redis 服务端原子执行Java 端只需一次调用大幅减少网络往返。五、高并发优化策略1. 多级限流层级策略说明客户端按钮防抖 本地频率限制减少无效请求网关层令牌桶/漏桶限流控制总体流量业务层用户维度限流每人每次活动只能抢一次缓存层Redis 集群分片分散单节点压力2. Redis 热 Key 拆分10 亿红包如果都放在一个 Key 里单个 Redis 节点扛不住。解决方案按 activityId 拆分为 N 个子 Keyred_packet:pool:{activityId}:0 red_packet:pool:{activityId}:1 ... red_packet:pool:{activityId}:99拆分为 100 个子 Key分散到不同 Redis 节点请求到来时通过userId % 100路由到对应的子 Key单 Key 压力从百万 QPS 降为万级 QPS3. 本地缓存 异步同步字节跳动方案本地内存缓存atomic.AddInt64 原子累加 ↓ 定时任务1s 间隔 Redis 同步 ↓ 双写 备份 Redis读请求走本地缓存不打 Redis写操作先累加本地计数器定时批量同步到 Redis双写备份 Redis 实现容灾六、异步入账1. 为什么要异步抢红包发奖和入账到余额是两个不同阶段阶段TPS说明发奖180w用户点击抢到红包入账30w红包金额写入用户余额两者存在巨大差距如果同步入账DB 扛不住。2. Token 方案字节跳动用户抢到红包 ↓ 生成加密 Token含金额、actID、时间戳 ↓ Token 存储到客户端 服务端 Redis ↓ 用户余额 已入账金额 未入账 Token 金额之和 ↓ 异步任务逐步将 Token 入账到 DB用户感知上立即到账实际异步处理Token 使用 Protobuf 格式比 JSON 节约 50% 存储用户提现时强制入账所有未结算 Token不阻塞提现3. MQ 削峰抢红包服务 → MQRocketMQ/Kafka→ 入账消费者 → DB通过消息队列削峰填谷保护下游数据库。七、容灾与降级1. 多级降级开关故障场景降级策略Redis 主集群故障切换到备份 Redis 集群分布式锁 Redis 故障跳过锁异步兜底对账Token Redis 故障跳过 Token用户感知入账延迟MQ 故障本地日志 定时任务补偿DB 故障紧急切主最后防线2. 库存防超发Redis incr 原子累加消耗量 ↓ 剩余 10%触发降级发祝福语/兜底券 ↓ 消耗量 总库存直接拒绝 ↓ 预留 5% 缓冲应对超时重试3. 资金对账三维度对账保证资金安全H1 对账活动结束 1 小时后核对发放总额与入账总额H2 复核二次核对准实时反查已入账 → 资产中台 → 活动侧三方交叉验证幂等设计订单号 actID_sceneID_rainID_awardType_status天然防重。八、DB 层优化1. 分库分表分库维度userId hash 分表维度日期循环按天/按周 表结构db_{hash}.t_order_{date}2. 冷热分离热数据库仅存最近几天数据支撑高并发查询历史数据异步迁移到冷存储HBase/对象存储3. 表字段精简订单表仅存关键字段金额、用户ID、状态、时间非关键信息头像、昵称存 Cache不落订单表九、总结核心设计思路预拆包空间换时间 Redis Lua原子抢红包 热 Key 拆分分散压力 异步入账削峰填谷 多级降级容灾兜底 三维对账资金安全面试回答要点问题维度关键回答如何保证不超发Redis 原子操作 Lua 脚本 库存预扣如何扛住百万 TPS热 Key 拆分 本地缓存 多级限流如何保证不重复领取Lua 脚本内 HEXISTS 判重 幂等订单号如何处理入账延迟Token 方案 MQ 异步 提现时强制入账如何容灾双写 Redis 多级降级开关 对账补偿数据库怎么扛分库分表 冷热分离 字段精简参考资料B站 IT老齐0922个大厂100亿级超大流量红包架构方案 - 博客园电商红包雨是如何实现的 - CSDN