面试题答案
一键面试设计思路
- 节点类型选择:
- 使用临时顺序节点。当客户端尝试获取锁时,在Zookeeper的锁节点下创建一个临时顺序节点。例如,锁节点为
/lock
,客户端创建的节点可能形如/lock/lock-0000000001
。临时节点保证了客户端与Zookeeper断开连接时,节点自动删除,避免死锁。顺序节点则提供了一种天然的排队机制,序号最小的节点代表获得锁。
- 使用临时顺序节点。当客户端尝试获取锁时,在Zookeeper的锁节点下创建一个临时顺序节点。例如,锁节点为
- 监听器机制:
- 每个客户端创建完临时顺序节点后,并不直接去判断自己是否获得锁,而是监听比自己序号小的前一个节点。比如客户端C1创建的节点序号为
lock-0000000003
,它就监听lock-0000000002
节点。当前一个节点被删除(意味着持有锁的客户端释放了锁)时,Zookeeper会通知监听它的客户端。
- 每个客户端创建完临时顺序节点后,并不直接去判断自己是否获得锁,而是监听比自己序号小的前一个节点。比如客户端C1创建的节点序号为
实现要点
- 获取锁:
- 客户端连接Zookeeper,在锁节点下创建临时顺序节点。
- 获取锁节点下所有子节点,并对其按序号排序。
- 判断自己创建的节点序号是否最小,如果是,则获得锁;否则,监听前一个序号的节点。
- 释放锁:
- 持有锁的客户端在业务完成后,删除自己创建的临时顺序节点。这会触发对下一个序号节点监听的客户端的通知。
- 异常处理:
- 客户端在监听过程中可能出现网络抖动等异常情况。需要在客户端重新连接Zookeeper后,重新确认自己的锁状态。例如,如果之前监听的节点已不存在,且自己的节点序号变为最小,那么重新获得锁;如果监听的节点仍存在,则继续监听。
- 防止惊群效应:
- 由于多个客户端可能同时监听同一个节点,当该节点被删除时,会通知所有监听它的客户端。为避免所有客户端同时竞争锁,可以在客户端收到通知后,设置一个短暂的随机延迟,然后再去竞争锁,降低并发冲突的概率。