秒杀场景下的 Redis 分布式锁优化与业务设计
秒杀是高并发场景的典型代表,核心挑战在于库存扣减的准确性与订单生成的原子性。面对海量请求,如何保证数据一致性与系统可用性,是架构设计的重点。
全局唯一 ID 生成策略
商品秒杀本质仍是订单购买,需要一张订单表记录流水。直接使用数据库自增 ID 在高并发下存在明显缺陷:
- ID 规律暴露信息:用户可通过 ID 推算出下单时间间隔,甚至推测其他用户的下单情况,存在安全隐患。
- 单表性能瓶颈:高并发下订单量巨大,MySQL 单表难以承载,分库分表后自增 ID 容易重复。
因此,我们需要一个全局唯一且无规律的 ID 生成器。虽然 Redis 的 INCR 命令能保证递增性和高性能,但纯数字序列依然有规律可循。通常采用 Redis 计数器配合时间戳拼接的方式,或者使用 Snowflake 算法。
以 Redis 自增 ID 策略为例,每天重置 Key 方便统计,ID 结构包含时间戳与秒内计数器:
public class RedisIdWorker {
/** 开始时间戳 */
private static final long BEGIN_TIMESTAMP = 1640995200L;
/** 序列号的位数 */
private static final int COUNT_BITS = 32;
private StringRedisTemplate stringRedisTemplate;
public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
public long nextId(String keyPrefix) {
// 1. 生成时间戳(偏移量)
LocalDateTime now = LocalDateTime.now();
long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
long nowSecond - BEGIN_TIMESTAMP;
now.format(DateTimeFormatter.ofPattern());
stringRedisTemplate.opsForValue()
.increment( + keyPrefix + + date);
timestamp << COUNT_BITS | count;
}
}


