51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

设计一个分布式锁,用于在多个微服务(如备份服务、恢复服务)中协调对同一用户数据的操作,比如同时有备份和恢复请求,避免数据冲突。请说明实现方案(如Redis、Zookeeper或分布式协调器),并分析其原子性、高可用、超时等特性。

万兴科技后端开发难度:中等

答案

1) 【一句话结论】

针对微服务间用户数据操作协调,推荐使用Redis结合Redlock算法实现分布式锁,核心是通过原子操作(SETNX)结合多实例尝试与超时机制,确保高可用下的互斥,避免备份/恢复冲突。

2) 【原理/概念讲解】

分布式锁的本质是互斥访问共享资源(如用户数据),保证同一时间仅一个服务操作。以Redis为例:

  • Redis的SET key value EX seconds NX(或PX milliseconds NX)是原子操作,表示“若key不存在则设置,并设置过期时间(TTL)”。
  • 类比:锁是共享停车位,只有一人能停(获取锁),过期时间相当于停车时长(防止死锁)。
  • 锁key需包含唯一标识(如用户ID、服务标识、锁类型),确保同一用户的数据操作由对应服务持有锁。
  • 超时机制(TTL)防止服务挂了后锁不释放。
  • Redlock通过多个Redis实例尝试SETNX,多数成功则认定获取锁成功,部分节点故障时仍能保证正确性(需满足超时时间计算公式:timeout = 2 * (n * r + t + r),n为实例数,r为网络延迟,t为锁请求时间)。

3) 【对比与适用场景】

方案定义原子性高可用超时处理适用场景
Redis SETNX单实例用SET key NX PX ttl,原子设置键并过期原子(Redis原子命令)非高可用(单点故障)TTL自动释放适用于中小规模,对高可用要求不高的场景
Zookeeper通过临时顺序Znode(如/lock/seq-123)获取锁,比较节点序号原子(创建临时节点是原子操作)高可用(Zookeeper集群)节点过期自动删除适用于需要高可用,且对性能要求不高的场景
Redlock多个Redis实例尝试SETNX,多数成功则获取锁原子(多实例原子操作组合)高可用(多实例集群)超时时间计算(避免节点故障时锁失效)适用于高并发、对高可用要求高的场景(如备份/恢复)

4) 【示例】

以备份服务为例,锁key设计为lock:backup:user123:service:backup(包含用户ID、服务标识、锁类型),超时5秒(备份操作可能耗时较长),重试策略用指数退避(第一次1秒,第二次2秒,指数增长)。

伪代码:

  1. 获取锁:
    # 尝试设置锁,键为"lock:backup:user123:service:backup",过期5000毫秒,仅当不存在时设置
    SET lock:backup:user123:service:backup NX PX 5000
    # 如果返回OK,表示获取锁成功;否则失败,等待指数退避后重试
    
  2. 执行备份:
    # 成功获取锁后,执行备份逻辑(如写入备份文件)
    # 备份完成后,立即释放锁
    DEL lock:backup:user123:service:backup
    
  3. 重试逻辑:
    若SET返回失败,等待1秒(第一次),2秒(第二次),指数退避,避免“饥饿问题”。

5) 【面试口播版答案】

面试官您好,针对分布式锁设计,我推荐使用Redis结合Redlock算法,核心是通过原子操作(SETNX)结合多实例尝试与超时机制,确保高可用下的互斥。具体来说,当备份或恢复服务需要操作用户数据时,先尝试用SET lock:backup:user123:service:backup NX PX 5000命令,如果返回OK则获取锁成功,执行备份逻辑后立即删除锁,若失败则等待指数退避(如1-2秒随机延迟)后重试。锁key包含用户ID、服务标识,确保唯一性。对于高可用,Redlock通过5个Redis实例尝试获取锁,多数成功则认定获取成功,部分节点故障时仍能正确处理(需满足超时时间计算公式)。原子性由Redis原子命令保证,超时机制防止死锁,高可用由多实例和Redlock算法保障。这样能避免备份和恢复请求冲突,适用于微服务间的数据协调。

6) 【追问清单】

  • 问题:Redlock算法中,若5个实例中有3个成功,2个失败,如何判定获取锁成功?
    回答:Redlock要求多数实例成功(如5个实例中至少3个成功),若满足则认定获取锁成功,否则视为失败并重试。
  • 问题:锁key设计时,为什么需要包含服务标识?
    回答:避免不同服务(如备份与恢复)因key冲突导致锁竞争,确保同一用户的数据操作由对应服务持有锁。
  • 问题:超时时间(TTL)如何根据业务调整?
    回答:备份操作可能需要更长的TTL(如5秒),恢复操作较短(如3秒),根据操作时长和并发量设置,避免锁被误删或等待时间过长。
  • 问题:网络分区时,Redlock如何处理?
    回答:若部分节点故障,Redlock会重试其他可用节点,通过多数成功判定确保锁的正确性,避免单点故障导致锁失效。
  • 问题:重试策略中,指数退避如何避免“饥饿问题”?
    回答:重试间隔从1秒开始,每次指数增长(如2秒、4秒),避免某个服务因频繁重试占用过多资源,其他服务仍有机会获取锁。

7) 【常见坑/雷区】

  • 锁key设计不当:仅用用户ID作为key,导致不同服务竞争同一锁,如备份和恢复服务同时请求锁,冲突。
  • TTL设置不合理:备份操作TTL过短(如2秒),导致服务执行时锁已过期,需重试;或过长(如10秒),其他服务等待时间过长。
  • 未释放锁:业务逻辑中忘记删除锁,或异常时未执行删除,导致其他服务无法获取锁。
  • Redlock超时时间计算错误:未满足timeout = 2 * (n * r + t + r),导致节点故障时锁失效。
  • 网络分区下的重试策略:未考虑节点故障时的重试次数,可能导致无限重试或锁竞争加剧。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1