
针对微服务间用户数据操作协调,推荐使用Redis结合Redlock算法实现分布式锁,核心是通过原子操作(SETNX)结合多实例尝试与超时机制,确保高可用下的互斥,避免备份/恢复冲突。
分布式锁的本质是互斥访问共享资源(如用户数据),保证同一时间仅一个服务操作。以Redis为例:
SET key value EX seconds NX(或PX milliseconds NX)是原子操作,表示“若key不存在则设置,并设置过期时间(TTL)”。SETNX,多数成功则认定获取锁成功,部分节点故障时仍能保证正确性(需满足超时时间计算公式:timeout = 2 * (n * r + t + r),n为实例数,r为网络延迟,t为锁请求时间)。| 方案 | 定义 | 原子性 | 高可用 | 超时处理 | 适用场景 |
|---|---|---|---|---|---|
| Redis SETNX | 单实例用SET key NX PX ttl,原子设置键并过期 | 原子(Redis原子命令) | 非高可用(单点故障) | TTL自动释放 | 适用于中小规模,对高可用要求不高的场景 |
| Zookeeper | 通过临时顺序Znode(如/lock/seq-123)获取锁,比较节点序号 | 原子(创建临时节点是原子操作) | 高可用(Zookeeper集群) | 节点过期自动删除 | 适用于需要高可用,且对性能要求不高的场景 |
| Redlock | 多个Redis实例尝试SETNX,多数成功则获取锁 | 原子(多实例原子操作组合) | 高可用(多实例集群) | 超时时间计算(避免节点故障时锁失效) | 适用于高并发、对高可用要求高的场景(如备份/恢复) |
以备份服务为例,锁key设计为lock:backup:user123:service:backup(包含用户ID、服务标识、锁类型),超时5秒(备份操作可能耗时较长),重试策略用指数退避(第一次1秒,第二次2秒,指数增长)。
伪代码:
# 尝试设置锁,键为"lock:backup:user123:service:backup",过期5000毫秒,仅当不存在时设置
SET lock:backup:user123:service:backup NX PX 5000
# 如果返回OK,表示获取锁成功;否则失败,等待指数退避后重试
# 成功获取锁后,执行备份逻辑(如写入备份文件)
# 备份完成后,立即释放锁
DEL lock:backup:user123:service:backup
SET返回失败,等待1秒(第一次),2秒(第二次),指数退避,避免“饥饿问题”。面试官您好,针对分布式锁设计,我推荐使用Redis结合Redlock算法,核心是通过原子操作(SETNX)结合多实例尝试与超时机制,确保高可用下的互斥。具体来说,当备份或恢复服务需要操作用户数据时,先尝试用SET lock:backup:user123:service:backup NX PX 5000命令,如果返回OK则获取锁成功,执行备份逻辑后立即删除锁,若失败则等待指数退避(如1-2秒随机延迟)后重试。锁key包含用户ID、服务标识,确保唯一性。对于高可用,Redlock通过5个Redis实例尝试获取锁,多数成功则认定获取成功,部分节点故障时仍能正确处理(需满足超时时间计算公式)。原子性由Redis原子命令保证,超时机制防止死锁,高可用由多实例和Redlock算法保障。这样能避免备份和恢复请求冲突,适用于微服务间的数据协调。
timeout = 2 * (n * r + t + r),导致节点故障时锁失效。