1. 分布式锁的业务场景与核心挑战
在电商秒杀、库存扣减、订单处理等高并发场景中,多个服务实例同时操作共享资源时,会出现超卖、数据不一致等典型问题。去年双十一大促期间,我们系统就曾因库存竞争导致超卖200多件商品。分布式锁正是为解决这类跨进程、跨服务器的互斥访问问题而生的关键技术方案。
传统单机锁(如Java的synchronized)在分布式环境下完全失效,因为:
- 锁状态无法跨JVM共享
- 网络延迟和分区故障会导致锁状态不一致
- 没有自动释放机制可能导致死锁
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Redis实现分布式锁的三大核心要素
2.1 原子性加锁操作
使用SETNX命令已逐渐被淘汰,现在推荐用Redis 2.6.12+的SET扩展参数:
bash复制SET lock_key unique_value NX PX 30000
这个命令的原子性体现在:
- NX:只有key不存在时才设置成功(争抢锁)
- PX:自动过期时间(毫秒),避免死锁
- unique_value:客户端唯一标识,防止误删
关键细节:过期时间要大于业务操作耗时,我们一般设置为平均耗时的2-3倍。曾经因为设得太短(5s),导致批量导出任务频繁锁失效。
2.2 安全的锁释放机制
错误示范(会导致删除其他客户端的锁):
lua复制if redis.get("lock_key") == "my_value" then
redis.del("lock_key")
end
正确姿势是用Lua脚本保证原子性:
lua复制if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
2.3 锁续期机制(WatchDog)
对于执行时间不确定的长任务,需要后台线程定期续期:
java复制private void renewExpiration() {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('pexpi
