
1) 【一句话结论】
核心采用“分层解耦+异步解耦+缓存加速+分布式保障+限流熔断”架构,通过滑动窗口限流控制流量、Redis缓存提升查询效率、分布式锁保障并发安全、Kafka异步处理请求,结合主从复制、持久化存储保障故障恢复,确保百万级高并发下的低延迟高吞吐与数据一致性。
2) 【原理/概念讲解】
老师:高并发抢红包的核心挑战是流量突发、并发安全、数据一致性。类比超市抢购,系统需像“智能收银台(限流)+分拣中心(消息队列)+库存管理(缓存+分布式锁)+库存同步(数据库)”运作。
3) 【对比与适用场景】
| 算法/组件 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 滑动窗口限流 | 统计当前窗口内请求数,超过阈值拒绝 | 动态调整,抗突发能力强 | 高频请求(如抢红包) | 需精确计算窗口边界,避免超卖 |
| Redis分布式锁 | SETNX实现单机锁,设置过期时间 | 单机锁,分布式需主从 | 保障并发安全(如抢红包) | 过期时间≥最慢操作时间+缓冲,防死锁 |
| Kafka消息队列 | 持久化消息,支持消费组 | 解耦、异步、高吞吐 | 处理高并发请求 | 需持久化存储,避免消息丢失 |
| 布隆过滤器 | 基于位图的哈希集合 | 空间高效,误判率低 | 缓存穿透过滤无效请求 | 误判率约1%,需结合互斥锁 |
4) 【示例】(伪代码):
# 用户抢红包流程(含重试、死信队列、缓存回滚)
def抢红包(user_id,红包id):
# 1. 滑动窗口限流(QPS=1000)
if not 检查限流(user_id):
return "限流中"
# 2. 缓存穿透处理(布隆过滤器+互斥锁)
if not 布隆过滤器过滤(红包id):
return "已抢完"
lock_key = f"抢红包_互斥锁_{红包id}"
if not redis.setnx(lock_key, "1", ex=1): # 1秒互斥锁
return "抢夺失败(互斥锁占用)"
# 3. 分布式锁(SETNX)
lock_key = f"抢红包_分布式锁_{红包id}"
if not redis.setnx(lock_key, "1", ex=3): # 3秒过期
return "抢夺失败(锁被占用)"
# 4. 扣减缓存数量
剩余数量 = redis.decr(f"红包{红包id}_数量")
if 剩余数量 < 0: # 超卖,回滚
redis.incr(f"红包{红包id}_数量") # 回滚
redis.delete(lock_key)
return "超卖,重试"
# 5. 异步写入数据库(Kafka)
kafka_producer.send("抢红包日志", value={"user_id": user_id, "红包id": 红包id, "剩余数量": 剩余数量})
# 6. 释放锁
redis.delete(lock_key)
redis.delete(lock_key) # 互斥锁
return "抢到红包!"
(注:Kafka消费者处理消息时,若数据库写入失败,则将消息投递至死信队列,后续重试或记录日志。)
5) 【面试口播版答案】
面试官您好,针对微信红包系统百万级高并发场景,我的方案核心是构建“分层解耦+异步处理+缓存加速+分布式保障”的架构,确保低延迟和高吞吐。
首先,架构上采用微服务拆分(如红包生成、抢红包、统计模块独立部署),通过API网关统一入口实现水平扩展。然后,核心组件选型:限流用滑动窗口算法(每秒QPS阈值1000次,动态调整窗口大小),缓存用Redis集群(高可用+高并发),分布式锁用RedisSETNX(设置3秒过期时间,防止死锁),消息队列用Kafka(持久化+消费组)。数据一致性方面,采用最终一致性——用户抢到后,先更新缓存(Redis),再异步写入数据库(MySQL),通过消息队列保证顺序。若数据库写入失败,缓存回滚到原值(如扣减失败则恢复剩余数量)。故障恢复方面,Redis主从复制+哨兵实现高可用,Kafka持久化+消费组保证消息不丢失,数据库主从读写分离保障读写性能。这样在峰值时,限流控制流量,缓存加速查询,分布式锁保障并发安全,消息队列异步处理请求,整体保障低延迟和高吞吐,同时具备故障恢复能力。
6) 【追问清单】
7) 【常见坑/雷区】