参考 分布式锁之Zk(zookeeper)实现
Zookeeper分布式锁
问题
正常线程进程同步的机制有哪些?
互斥:互斥的机制,保证同一时间只有一个线程可以操作共享资源 synchronized,Lock等
临界值:让多线程串行话去访问资源
事件通知:通过事件的通知去保证大家都有序访问共享资源
信号量:多个任务同时访问,同时限制数量,比如发令枪CDL,Semaphore等
分布式锁实现
Zookeeper
Redis
MySQL
zk的使用场景
服务注册与订阅(共用节点)
分布式通知(监听znode)
服务命名(znode特性)
数据订阅、发布(watcher)
分布式锁(临时节点)
zk是啥?
他是个数据库,文件存储系统,并且有监听通知机制(观察者模式)
存文件系统,
他存了什么?
节点
- 持久化节点(zk断开节点还在)
- 持久化顺序编号目录节点
- 临时目录节点(客户端断开后节点就删除了)
- 临时目录编号目录节点
节点名称都是唯一的
节点怎么创建?
- create /test laogong // 创建永久节点
- create -e /test laogong // 创建临时节点
- create -s /test // 创建顺序节点
- 创建时给节点名称进行顺序编号
- create -e -s /test // 创建临时顺序节点
分布式锁
zk就是基于节点去实现各种分布式锁的。
k节点有个唯一的特性
- 就是我们创建过这个节点了,你再创建zk是会报错的
使用永久节点
- 加锁
- 全部去创建一个节点
- 创建成功的第一个返回true
- 释放锁
- 删除节点,删了再通知其他的人过来加锁,依次类推
- 问题
- 如果第一个节点出现异常,没有删除节点,导致其他客户端都在等待
使用临时顺序节点
- 加锁
- 创建临时顺序节点
- 获取所有创建的临时顺序节点
- 如果自己的编号是最小的
- 加锁成功
- 释放锁
- 把事情完成,端客户端断开,节点删除
与redis缓存实现分布式锁区别
Zk性能上可能并没有缓存服务那么高。
因为每次在创建锁和释放锁的过程中,都要动态创建、销毁瞬时节点来实现锁功能。
ZK中创建和删除节点只能通过Leader服务器来执行,然后将数据同步到所有的Follower机器上。
Zookeeper也有可能带来并发问题
- 网络抖动
- session连接断了
- 就会删除临时节点
- 其他客户端就可以获取到分布式锁了
总结
zk通过临时节点,解决掉了死锁的问题
- 一旦客户端获取到锁之后突然挂掉(Session连接断开)
- 那么这个临时节点就会自动删除掉,其他客户端自动获取锁。
zk通过节点排队监听的机制,也实现了阻塞的原理
- 实就是个递归在那无限等待最小节点释放的过程。
XMind - Trial Version