MST

星途 面试题库

面试题:分布式系统中基于分布式锁实现资源竞争控制的常见方案有哪些

请阐述在分布式系统里,基于分布式锁来处理资源竞争控制,你所知道的常见实现方案,并简要说明每种方案的优缺点。
32.3万 热度难度
后端开发分布式系统

知识考点

AI 面试

面试题答案

一键面试

基于数据库实现分布式锁

  1. 实现方式
    • 利用数据库的唯一约束来实现。例如,在数据库中创建一张锁表,表中包含一个唯一索引字段。当需要获取锁时,向该表插入一条记录,利用唯一索引的特性,如果插入成功则获取到锁,否则获取锁失败。当释放锁时,删除该记录。
  2. 优点
    • 实现简单,对于熟悉数据库操作的开发人员容易上手。
    • 可靠性较高,基于成熟的数据库系统,数据持久化,即使系统重启,锁的状态也能保持。
  3. 缺点
    • 性能问题,数据库的读写操作性能相对较低,在高并发场景下,频繁的插入和删除操作可能成为性能瓶颈。
    • 锁的粒度较粗,无法满足更细粒度的锁控制需求。
    • 可能存在死锁问题,如果某个事务在获取锁后未正常释放锁就发生故障,可能导致其他事务一直无法获取锁。

基于Redis实现分布式锁

  1. 实现方式
    • 利用Redis的SETNX(SET if Not eXists)命令来实现。当一个客户端执行SETNX key value命令,如果key不存在,则设置成功并返回1,即获取到锁;如果key已存在,则返回0,获取锁失败。释放锁时,通过DEL命令删除该key。为了防止死锁,通常还会给锁设置一个过期时间。
  2. 优点
    • 性能高,Redis是基于内存的高性能键值存储系统,能快速处理锁的获取和释放操作,适合高并发场景。
    • 灵活性好,可以方便地设置锁的过期时间,有效避免死锁。
    • 支持多种数据结构,可基于不同数据结构实现更复杂的锁逻辑。
  3. 缺点
    • 可靠性依赖Redis集群,若Redis集群出现故障,可能导致锁服务不可用。
    • 锁的过期时间设置较难,设置过短可能导致业务未完成锁就过期,设置过长则可能在故障时长时间占用锁资源。
    • 存在锁误删风险,比如客户端A获取锁后,由于业务执行时间较长,锁过期被Redis自动删除,此时客户端B获取到锁,而客户端A执行完业务后去释放锁,就会误删客户端B的锁。

基于Zookeeper实现分布式锁

  1. 实现方式
    • 在Zookeeper中创建一个持久化节点作为锁的根节点,每个客户端尝试获取锁时,在根节点下创建一个临时顺序节点。客户端获取根节点下所有子节点并排序,判断自己创建的节点序号是否最小,如果是则获取到锁,否则监听比自己序号小的前一个节点的删除事件。当持有锁的客户端释放锁(即删除自己创建的临时节点)时,下一个等待的客户端会收到通知并尝试获取锁。
  2. 优点
    • 可靠性高,Zookeeper采用了 Zab 协议保证数据的一致性和可靠性,即使部分节点故障,也能保证锁服务的正常运行。
    • 支持公平锁,通过临时顺序节点的机制,天然支持公平锁,能避免某些客户端长时间等待锁的情况。
    • 自动释放锁,由于创建的是临时节点,客户端与Zookeeper断开连接后,节点会自动删除,即锁自动释放,避免死锁。
  3. 缺点
    • 性能相对较低,Zookeeper的写操作性能不如Redis,因为Zookeeper为了保证数据一致性,写操作需要过半节点确认。
    • 实现相对复杂,涉及到节点的创建、监听等操作,代码实现比基于数据库或Redis的锁复杂。
    • 网络开销较大,客户端需要频繁与Zookeeper集群进行通信,获取节点状态和监听事件。