分布式锁的主流实现方案
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
分布式锁是分布式系统中解决共享资源并发竞争、防止数据错乱、重复执行的核心组件,核心目标是保证同一时刻仅有一个客户端持有锁、操作共享资源。根据底层依赖的中间件和实现机制,主流分布式锁可分为五大类,每类适配不同的业务场景、性能要求和一致性诉求,具体方案拆解如下:
一、基于数据库的分布式锁(入门简易版)
依托关系型数据库(MySQL、PostgreSQL)的事务、索引、锁机制实现,无需额外引入中间件,适合简单低并发场景,分为三种经典实现:
1. 悲观锁(SELECT ... FOR UPDATE)
核心原理:通过数据库行级排他锁锁定资源记录,事务提交前其他客户端无法修改/锁定该记录,实现互斥。执行语句为SELECT * FROM distributed_lock WHERE resource_key = 'xxx' FOR UPDATE,只有当前事务释放锁(提交/回滚)后,其他请求才能获取锁。
优缺点:实现简单、强一致性;但性能差、锁超时依赖事务、数据库压力大,不适合高并发。
2. 乐观锁(版本号/时间戳机制)
核心原理:不锁定数据库记录,而是通过版本号字段控制并发。更新资源时携带版本号,只有版本号匹配才执行更新,否则判定并发冲突,需重试。语句示例:UPDATE distributed_lock SET version = version + 1 WHERE resource_key = 'xxx' AND version = 旧版本号。
优缺点:无锁阻塞、性能高;仅适合并发冲突低的场景,冲突频繁时重试成本高。
3. 唯一键约束锁
核心原理:利用数据库唯一索引的唯一性约束,加锁时执行INSERT语句,唯一键重复则插入失败,代表锁已被持有;释放锁时执行DELETE语句删除记录。
优缺点:实现极简;无锁超时机制、宕机易导致死锁,需配合定时任务清理失效锁。
数据库锁总结:适合单体微服务、低并发、无中间件的简易场景,核心短板是性能瓶颈、锁超时难管控,不适合核心高并发业务。
二、基于Redis的分布式锁(高并发首选)
依托Redis的高性能、单线程特性实现,是互联网公司高并发场景的主流方案,分为单机锁和进阶红锁,解决性能与可靠性平衡问题。
1. 单机Redis锁(SETNX + EXPIRE)
核心原理:利用Redis的SETNX(SET IF NOT EXISTS)命令实现互斥,配合EXPIRE设置锁超时时间,防止宕机死锁;标准原子命令:SET lock_key random_value NX EX 30(NX代表仅不存在时设置,EX代表过期时间)。释放锁时需通过Lua脚本校验锁归属,避免误删他人锁。
优缺点:性能极致、延迟极低、实现简单;仅支持单机Redis,主从切换时存在锁丢失风险(主节点宕机、锁未同步到从节点)。
2. Redlock红锁(Redis多节点集群版)
核心原理:针对单机Redis锁的单点故障问题,Redis官方提出的进阶方案。部署多个独立Redis主节点(无主从、无集群),客户端依次向所有节点申请锁,超过半数节点加锁成功且耗时小于锁超时时间,才算加锁成功;释放锁时向所有节点发送解锁指令。
优缺点:解决单点故障、可靠性提升;部署成本高、性能下降、时钟漂移存在争议,适合对锁可靠性要求极高的场景。
3. Lua脚本原子锁
将加锁、续期、解锁逻辑封装为Lua脚本,利用Redis单线程执行Lua的原子性,避免网络延迟导致的命令拆分问题,是Redis锁的标准落地方式,配合Redisson框架可实现自动续期(看门狗机制)。
Redis锁落地建议:普通高并发业务用Redisson+单机/哨兵Redis即可;极致可靠性场景再考虑Redlock,优先复用成熟框架避免手写锁漏洞。
三、基于ZooKeeper的分布式锁(强一致性首选)
依托ZooKeeper的临时有序节点+Watcher监听机制实现,基于ZAB协议保证强一致性,适合对锁可靠性、顺序性要求极高的场景。
核心实现逻辑
- 客户端在ZooKeeper的锁节点下创建临时有序子节点,临时节点特性:客户端宕机则节点自动删除,避免死锁;
- 客户端判断自己创建的节点是否为当前最小序号节点,若是则获取锁;若不是则监听前一个节点的删除事件;
- 前序节点释放锁(删除)后,Watcher触发,当前客户端重新判断是否获取锁,实现公平锁机制。
实际落地可直接使用Curator框架封装的InterProcessMutex,屏蔽底层细节,支持可重入锁。
优缺点
强一致性、无锁丢失风险、自动释放锁、支持公平锁;性能低于Redis、依赖ZooKeeper集群、运维成本高,适合并发量低但一致性要求高的场景。
四、基于etcd的分布式锁(云原生主流)
依托etcd的Raft一致性协议、lease租约、Revision版本号实现,是云原生、K8s生态的首选分布式锁,兼顾一致性与性能。
核心原理
- 基于etcd的事务机制创建锁key,配合lease租约实现锁超时,客户端定时续期;
- 利用Revision全局单调递增特性,实现公平锁,最小Revision的客户端持有锁;
- 客户端通过watch机制监听锁释放,避免轮询,提升效率。
优缺点
强一致性、云原生友好、性能优于ZooKeeper、集群易运维;适合微服务、云原生架构,是替代ZooKeeper锁的主流方案。
五、其他小众分布式锁方案
- Consul分布式锁:依托Consul的session和KV存储实现,支持锁超时、健康检查,适合Service Mesh架构;
- 基于MQ的分布式锁:利用消息队列的单消费特性,将并发请求转为串行消费,实现伪锁,适合异步场景;
- 自研锁服务:大厂针对自身业务定制的锁服务,整合多中间件优势,适配超大规模分布式集群。
分布式锁选型核心总结
数据库锁 | 低 | 强 | 低 | 简易低并发、无中间件场景 |
Redis锁 | 极高 | 最终一致 | 中 | 高并发、性能优先的核心业务 |
ZooKeeper锁 | 中低 | 强 | 高 | 一致性优先、并发量低的场景 |
etcd锁 | 中高 | 强 | 中 | 云原生、微服务、K8s架构 |
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
本专栏聚焦 Redis 分布式锁从原理到生产落地全流程,拆解SET 原子加锁、Lua 解锁、锁续期、Redlock等核心技术,直击锁超时、误释放、主从一致性等高频痛点。结合 Redisson 实战与微服务场景案例,输出可直接复用的代码方案与避坑指南,助力后端工程师攻克分布式并发难题,构建高可靠锁服务。