[Golang 修仙之路] 分布式专题:分布式锁

分析

锁的基本要求(无论是分布式锁还是单机锁):

  1. 要有锁的存储空间。
  2. 锁要被唯一标识。
  3. 锁要有2种状态。

但是这不够,还需要考虑3个问题:

  1. 判断锁状态 和 上锁 2步操作的原子性。
  2. 锁需要被及时释放。
    • (主机A获取到锁,A宕机,一直不释放锁,资源被占用)
  3. 释放锁时,需要确认这锁是自己持有的。
    • (A获取锁,A挂了,挂之前及时释放锁,B一看没锁,B获取锁成功,A重启,释放锁,B一看md自己的锁被别人释放了)

进阶:

  1. 惊群效应(Herd Effect):在分布式锁中,惊群效应指的是,在有多个请求等待获取锁的时候,一旦占有锁的线程释放之后,如果所有等待的方都同时被唤醒,尝试抢占锁。但是这样的情况会造成比较大的开销,那么在实现分布式锁的时候,应该尽量避免惊群效应的产生。

Redis 实现

过程

获取锁:

arduino 复制代码
set lock_key <setter_id> nx ex 10
  • nx 保证了获取锁和加锁2步的原子性。
  • ex 保证了锁不会被一直持有。
  • setter_id 保证了锁被释放时可以检查是不是自己的。

释放锁:

  1. 判断锁的value是不是自己的setter_id,是才释放锁。
  2. del lock_key

这两步操作的原子性通过lua脚本保证。

lua 复制代码
if (redis.call('GET', KEY[1]) == ARGV[1]) then
    return redis.call('DEL', KEY[1])
else 
    return 0

问题

Redis 主从同步是异步的,主节点set nx成功,从节点还没同步,此时其他进程想获取锁,走从节点读,仍然能获取到。

zookeeper实现

过程

ZooKeeper(以下简称"ZK")中有一种节点叫做顺序节点,假如我们在/lock/目录下创建3个节点,ZK集群会按照发起创建的顺序来创建节点,节点分别为/lock/0000000001、/lock/0000000002、/lock/0000000003。

ZK中还有一种名为临时节点的节点,临时节点由某个客户端创建,当客户端与ZK集群断开连接,则该节点自动被删除。EPHEMERAL_SEQUENTIAL为临时顺序节点。

根据ZK中节点是否存在,可以作为分布式锁的锁状态,以此来实现一个分布式锁,下面是分布式锁的基本逻辑:

  1. 客户端调用create()方法创建名为"/dlm-locks/lockname/lock-"的临时顺序节点。
  2. 客户端调用getChildren("lockname")方法来获取所有已经创建的子节点。
  3. 客户端获取到所有子节点path之后,如果发现自己在步骤1中创建的节点是所有节点中序号最小的,那么就认为这个客户端获得了锁。
  4. 如果创建的节点不是所有节点中需要最小的,那么则监视比自己创建节点的序列号小的最大的节点,进入等待。直到下次监视的子节点变更的时候,再进行子节点的获取,判断是否获取锁。

释放锁的过程相对比较简单,就是删除自己创建的那个子节点即可,不过也仍需要考虑删除节点失败等异常情况。

优势

  • zk的临时节点可以直接避免网络断开或主机宕机,锁状态无法清除的问题。
  • 顺序节点可以避免惊群效应。

这些特性都使得利用ZK实现分布式锁成为了最普遍的方案之一。

相关推荐
NAGNIP2 小时前
万字长文!回归模型最全讲解!
算法·面试
yangminlei3 小时前
Spring Boot3集成LiteFlow!轻松实现业务流程编排
java·spring boot·后端
qq_318121593 小时前
互联网大厂Java面试故事:从Spring Boot到微服务架构的技术挑战与解答
java·spring boot·redis·spring cloud·微服务·面试·内容社区
计算机毕设VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue医院设备管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
J_liaty3 小时前
Spring Boot整合Nacos:从入门到精通
java·spring boot·后端·nacos
面汤放盐3 小时前
后端系统设计文档模板
后端
2***d8854 小时前
SpringBoot 集成 Activiti 7 工作流引擎
java·spring boot·后端
五阿哥永琪4 小时前
Spring中的定时任务怎么用?
java·后端·spring
追逐时光者4 小时前
C#/.NET/.NET Core技术前沿周刊 | 第 65 期(2026年1.1-1.11)
后端·.net
计算机毕设VX:Fegn08954 小时前
计算机毕业设计|基于springboot + vue小型房屋租赁系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计