分布式锁
Zookeeper (分布式服务注册与发现、分布式协调技术,分布式锁),分布式协调技术用来解决分布式环境当中多个进程之间的同步控制,让其有序访问某种临界资源,防止造成“脏数据”。
分布式锁:防止分布式系统中的多个进程间互相干扰,需要用到分布式协调技术来对进程进行调度。分布式协调技术的核心就是实现分布式锁。
分布式锁需求:
- 保证一个方法或属性在高并发下同一时间只能被同一个线程执行.
- 单机环境中 java 提供了并发处理相关的 API
- 分布式系统多线程,多进程并且分布在不同机器上,原单机部署情况并发控制锁策略失效
- 跨 JVM 的互斥机制来控制共享资源的访问
分布式锁的具备条件:
- 分布式环境下,一个方法或变量只能被一个机器的一条线程执行
- 高可用的获取锁与释放锁
- 高性能的获取锁与释放锁
- 具备锁失效机制,防止死锁
- 具备非阻塞锁特性,没有获取到锁直接返回获取锁失败(超时熔断,非阻塞)
- 具备可重入特性(多个任务并发使用,不担心数据错误)
Zookeeper
Zookeeper 的设计初衷就是实现分布式锁服务 ,Zookeeper 是为分布式应用提供一致性服务的开源组件,内部是一个分层的文件系统树结构目录,同一个目录下文件名必须唯一.
Zookeeper 使用场景之一:集群 Master 选举,解决分布式系统单点故障。
传统主从模式,主节点都有一个备用节点,备用节点不断发心跳确认主节点是否存活,如果主节点宕机备用节点立即接替主节点 。这样还会有个问题就是,网络问题导致请求或者响应信息丢失(丢包),备用节点启动了 Master 实例,分布式系统当中就有了两个节点 双Master, 从节点分别将数据部分发送给两个主节点,出现服务数据错乱。
Zookeeper 解决方案
zookeeper 能保证每时每刻只有一个 Master,但是不能避免网络故障。
主节点向 zookeeper 注册节点,例如:主节点A为 master-00001 ,主节点B为 master-00002,编号最小的节点将在选举中获胜取得锁成为主节点,其他节点将被阻塞成为备用节点。
Master 故障
如果 主节点A 宕机,自动删除 主节点A 注册的节点,Zookeeper 会自动感知节点变化, 重新发起选举,此时主节点B 的编号最小,B 将会替代 A 成为主节点。
Master 恢复
如果 主节点A 恢复,它会再次向向 zookeeper 注册节点,此时注册节点为 master-00003,Zookeeper 会感知节点变化再次选举,此时仍是 主节点B 获胜继续担任主节点。
问题: Zookeeper 必须高可用. Keepalived (健康检查,虚拟IP)实现高可用, HAProxy 负载均衡.
(待填坑!代码实现 demo)
Zookeeper 分布式锁方案
实现步骤:
- 创建目录 MyZookeeperLock
- 线程 A 向获取锁就在 MyZookeeperLock 目录下创建临时顺序节点.
- 获取 MyZookeeperLock 目录下所有子节点,然后获取比自己小兄弟节点,如果不存在,则表示当前线程顺序号最小 ,从而获得锁
- 线程 B 获取所有节点,判断自己不是最小节点,则设置监听比自己小的节点
- 线程 A 处理完,删除自己的节点,线程 B 监听到变更事件,判断自己是不是最小的节点,如果是则获得锁.
1 | 线程A |
Memcached 分布式锁方案
利用 Memcached 的 add 命令(原子操作)。只有 key 不存在的情况下 add 才能成功,也就意味着线程得到了锁。
Redis 分布式锁方案
类似 Memcached 的方式获取锁,利用 Redis 的 setnx 命令(原子操作)。只有 key 不存在的情况下,才能 set 成功。
Chubby 分布式锁方案
Google 公司实现的粗粒度分布式锁服务,底层利用 Paxos 一致性算法。
- 本文作者: MISAKIGA
- 本文链接: https://misakiga.github.io/2021/06/22/microservice/distribute_lock/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!
