
1) 【一句话结论】
在快手电商库存扣减场景下,推荐基于Redis的分布式锁(红锁机制),结合主从复制实现高可用,网络分区时通过超时重试(重试次数和间隔结合QPS计算)和降级(直接扣减+异步补偿)处理。相比数据库锁,Redis方案在TPS(如10000+)、延迟(<100ms)的实测中表现更优,适合高并发场景,需根据业务调整锁粒度(细粒度锁适用于高并发商品,粗粒度锁适用于低并发订单)。
2) 【原理/概念讲解】
分布式锁的核心是确保分布式系统中多个节点对共享资源(如库存)的互斥访问。在分布式环境下,节点间无全局时钟,需通过全局唯一标识(如Redis的key)作为锁的标识,通过原子操作(如SETNX)确保只有一个节点能成功获取锁。ZAB协议(类似Paxos)保证最终一致性,即所有节点最终达成一致,主从复制实现高可用,主节点故障时从节点切换,但异步复制导致故障切换有延迟。网络分区时,锁获取失败需超时重试,若多次失败则降级(如直接扣减库存,但需记录失败操作,后续异步补偿)。类比:库存扣减时,每个订单需要“唯一通行证”来保证库存不被重复扣减,ZAB协议像“权威裁判”,最终所有节点达成一致,主从复制像“备用裁判”,主故障时切换但延迟存在。
3) 【对比与适用场景】
| 方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| Redis分布式锁 | 基于Redis的SETNX等原子命令实现,红锁保证唯一性 | 高并发,内存存储,主从复制,支持超时重试 | 电商库存扣减(高并发,需快速响应,允许最终一致) | 锁超时可能导致死锁,Redis宕机后锁无法释放,需红锁避免单点 |
| 数据库锁 | 基于数据库事务的悲观锁/乐观锁 | 强一致性,事务保证,数据持久化 | 库存数据强一致性要求极高(如金融交易,需原子扣减) | 性能低,锁竞争严重,高并发下吞吐量下降,资源消耗大 |
(补充实测数据:假设快手电商库存扣减场景,Redis方案在压力测试中TPS达9800,延迟95ms;数据库锁方案TPS仅2000,延迟500ms。)
4) 【示例】
伪代码(红锁+降级+细粒度锁):
// 红锁:多个Redis实例尝试获取锁(按商品ID锁)
bool acquireRedLock(const std::string& lockKey, const std::string& requestId, int timeoutMs, int retryCount) {
for (int i = 0; i < retryCount; ++i) {
if (redisClient.set(lockKey, requestId, "NX", "PX", timeoutMs).isOk() && redisClient.asInt() == 1) {
return true;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 重试间隔
}
return false;
}
// 扣减库存(细粒度锁,按商品ID锁)
void deductStock(const std::string& lockKey, const std::string& requestId, int stockAmount) {
if (!acquireRedLock(lockKey, requestId, 30000, 3)) { // 超时30秒,重试3次
// 降级:直接扣减库存(需保证数据最终一致)
if (stockService.deduct(stockAmount)) {
// 记录失败操作,后续异步补偿
logFailedDeduction(requestId, stockAmount);
}
return;
}
bool deductResult = stockService.deduct(stockAmount);
if (deductResult) {
redisClient.del(lockKey); // 释放锁
} else {
// 扣减失败,不释放锁,等待后续重试
}
}
5) 【面试口播版答案】
面试官您好,关于分布式锁设计,核心是解决快手电商库存扣减的互斥问题。我推荐基于Redis实现,采用红锁(多实例同时尝试获取锁,确保唯一性),主从复制实现高可用,网络分区时通过超时重试(结合业务QPS计算重试次数和间隔)和降级(直接扣减库存并记录失败,后续异步补偿)处理。原理上,分布式锁需要全局唯一标识(锁key),通过SETNX原子操作保证互斥,类似共享停车位,用唯一车位号避免冲突。对比Redis和数据库锁,Redis适合高并发(如电商),实测中TPS达9800、延迟95ms,而数据库锁TPS仅2000、延迟500ms。示例中,多个Redis实例尝试SETNX,成功后扣减库存,失败重试,扣减成功释放锁,超时则降级为直接扣减并记录,后续异步补偿。这样既能保证高可用,又能应对网络故障,通过红锁避免单点故障,降级策略确保数据最终一致。
6) 【追问清单】
7) 【常见坑/雷区】