实现分布式锁方法
一、首先了解zk中锁的种类
1、读锁(共享锁):大家都可以读,要想上锁的前提是:之前没有写锁
2、写锁:只有得到写锁才能写数据。要想上写锁的前提是,之前没有任何的锁
二、zk如何上读锁
1、创建一个临时序号节点,节点的数据是read,表示读锁
2、获取当前zk中序号比自己小的所有节点
3、判断最小节点是否是读锁:(如果最小节点是写锁,那么后面的节点都不可能上读锁的)
(1)如果不是读锁的话(写锁时),则上锁失败,为最小节点设置监听。阻塞等待,zk的watch机制会当最小节点发生变化时通知当前节点,于是再执行第二步的流程
(2)如果是读锁的话,则上锁成功
三、zk如何上写锁
1、创建一个临时序号节点,节点的数据是write,表示写锁
2、获取zk中所有的子节点
3、判断自己是否是最小的节点:
(1)如果是,则上写锁成功;
(2)如果不是,则说明前面还有锁,则上锁失败,监听最小的节点,如果最小的节点有变化,则回到第二步
羊群效应
在Zookeeper中,"羊群效应"是指所有的客户端都尝试对一个临时节点去加锁,当一个锁被占有的时候,其他的客户端都会监听这个临时节点。一旦锁被释放,Zookeeper反向通知添加监听的客户端,然后大量的客户端都尝试去对同一个临时节点创建锁,最后也只有一个客户端能获得锁,但是大量的请求造成了很大的网络开销,加重了网络的负载,影响Zookeeper的性能。这种现象就像羊群一样,盲目地跟随,从众心理很容易导致盲从,而盲从往往会陷入骗局或遭到失败。因此,"羊群效应"在Zookeeper中是一种不良现象。
解决羊群效应
要避免Zookeeper中的羊群效应,可以采取以下措施:
- 客户端不直接连接Zookeeper,而是通过一个中间代理进行连接。这样,客户端的请求都被中间代理缓存起来,避免同时向Zookeeper发起大量请求,减少Zookeeper的负载。
- 使用分布式锁。当一个客户端获取到锁之后,其他客户端就不需要再尝试获取锁,等待锁的释放即可。这样可以减少对Zookeeper的请求数量,提高性能。
- 客户端在尝试获取锁之前进行预判。在客户端尝试获取锁之前,先检查是否已经有一个客户端获取了锁。如果已经有一个客户端获取了锁,那么其他客户端就不需要再尝试获取锁,避免浪费资源。
- 限制客户端的请求频率。在客户端请求获取锁的过程中,可以设置一个等待时间,避免过快地发送请求。这样可以减少Zookeeper的负载,提高性能。
- 优化网络结构。通过优化网络结构,使得客户端之间的通信更加高效,减少不必要的请求和响应,从而降低Zookeeper的负载。
至此,对于Zookeeper实现分布式锁的相关概念和技术点介绍完毕,后续还会持续更新,敬请期待~~~