羊群是一种很散乱的组织,平时在一起也是盲目地左冲右撞,但一旦有一只头羊动起来,其他的羊也会不假思索地一哄而上,全然不顾前面可能有狼或者不远处有更好的草。因此,“羊群效应”就是比喻人都有一种从众心理,从众心理很容易导致盲从,而盲从往往会陷入骗局或遭到失败。
Zookeeper分布式锁场景中的羊群效应指的是所有的客户端都尝试对一个临时节点去加锁,当一个锁被占有的时候,其他的客户端都会监听这个临时节点。一旦锁被释放,Zookeeper反向通知添加监听的客户端,然后大量的客户端都尝试去对同一个临时节点创建锁,最后也只有一个客户端能获得锁,但是大量的请求造成了很大的网络开销,加重了网络的负载,影响Zookeeper的性能。
解决方案可以参考curator框架创建Zookeeper分布式锁的机制。原理图如下:
步骤为:
- 所有客户端都尝试去创建临时有序节点以获取锁
- 序号最小的临时有序节点获得锁
- 未获取到锁的客户端给自己的上一个临时有序节点添加监听
- 获得锁的客户端进行自己的操作,操作完成之后删除自己的临时有序节点
- 当监听到自己的上一个临时有序节点释放了锁,尝试自己去加锁
- 操作完成之后释放锁
- 之后剩下的客户端重复加锁和解锁的操作
其中最核心的思路就是获取锁时创建一个临时顺序节点,顺序最小的那个才能获取到锁,之后尝试加锁的客户端就监听自己的上一个顺序节点,当上一个顺序节点释放锁之后,自己尝试加锁,其余的客户端都对上一个临时顺序节点监听,不会一窝蜂的去尝试给同一个节点加锁导致羊群效应。