分布式锁: Redisson红锁(RedLock)原理与实现细节

news2025/5/18 0:52:26

分布式锁是分布式系统的核心基础设施,但 单节点 Redis 锁在高可用场景下存在致命缺陷:当 Redis 主节点宕机时,从节点可能因异步复制未完成而丢失锁信息,导致多个客户端同时持有锁。为此,Redis 作者 Antirez 提出了 RedLock 算法,旨在通过多节点协作提升分布式锁的可靠性。本文将深入剖析 Redisson 中 RedLock 的实现原理、技术争议与最佳实践。


一、单节点 Redis 锁的局限性

1. 主从架构下的锁丢失问题

假设以下场景:

  1. 客户端 A 在 Redis 主节点成功获取锁。
  2. 主节点宕机,锁尚未同步到从节点。
  3. 从节点晋升为新主节点,此时客户端 B 也能获取同一把锁。
  4. 结果:客户端 A 和 B 同时持有锁,违反互斥性。

2. 异步复制的风险

Redis 主从复制默认异步,锁的写入可能在故障切换后丢失。


二、RedLock 算法核心思想

RedLock 的核心是通过 多个独立的 Redis 节点(至少 5 个)协作实现分布式锁。算法步骤如下:

1. 加锁流程

  1. 向所有节点发起加锁请求
    客户端依次向 N 个独立 Redis 节点发送加锁命令:

    SET lock_key <unique_value> NX PX <expire_time>
    
    • 使用相同的 Key 和唯一值(如 UUID + 线程ID)。
    • 设置合理的过期时间(通常为 10-30 秒)。
  2. 计算有效锁数量
    客户端统计成功获得锁的节点数。若 多数节点(≥ N/2 +1) 返回成功,则认为加锁成功。
    示例:N=5 时,至少需要 3 个节点成功。

  3. 计算锁的实际持有时间
    锁的最终有效时间 = 初始过期时间 - 加锁过程耗时。

    • 若实际持有时间过短(如剩余时间 < 业务执行时间),需立即释放锁。

2. 释放锁流程

向所有节点发送释放锁的 Lua 脚本(无论是否加锁成功):

if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

三、Redisson 中 RedLock 的实现

1. 配置多节点 Redisson 客户端

需为每个独立 Redis 节点创建 RedissonClient 实例:

Config config1 = new Config();
config1.useSingleServer().setAddress("redis://node1:6379");
RedissonClient client1 = Redisson.create(config1);

Config config2 = new Config();
config2.useSingleServer().setAddress("redis://node2:6379");
RedissonClient client2 = Redisson.create(config2);

// ... 创建其他节点客户端

RLock lock1 = client1.getLock("myLock");
RLock lock2 = client2.getLock("myLock");
RLock lock3 = client3.getLock("myLock");

RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);

2. 加锁的底层逻辑

调用 redLock.lock() 时,Redisson 内部执行以下步骤:

  1. 向所有节点并行发起加锁请求
    使用异步线程池同时向 N 个节点发送加锁命令。

  2. 统计成功加锁的节点数

    • 若成功节点数 ≥ 多数(如 5 节点需 ≥3),则加锁成功。
    • 否则,向所有节点发送解锁命令,并抛出 LockException
  3. 启动看门狗续期(可选)
    若未指定 leaseTime,Redisson 会为所有成功节点启动看门狗线程,定期续期锁。

3. 解锁流程

调用 redLock.unlock() 时:

  1. 向所有节点发送解锁命令
    即使某些节点加锁失败,也需尝试解锁。

  2. 处理部分节点失败
    若某些节点解锁失败(如网络问题),Redisson 会记录日志,但不会重试(需业务层处理)。


四、RedLock 的技术争议与应对策略

1. 争议点

1.1 时钟跳跃问题
  • 场景:若某 Redis 节点发生时钟跳跃(如 NTP 同步导致时间回拨),可能导致锁提前过期。
  • Redisson 的应对
    默认依赖 Redis 服务器的系统时间,建议禁用自动时钟同步(或在物理机环境运行)。
1.2 网络延迟与 GC 停顿
  • 场景:客户端因 GC 停顿或网络延迟,误判锁已释放。
  • 解决思路
    • 锁过期时间应远大于业务最大执行时间(如设置 30 秒,业务执行时间 ≤10 秒)。
    • 使用唯一 Token(unique_value)确保只有锁持有者能释放锁。
1.3 算法安全性争议

Martin Kleppmann 在 How to do distributed locking 中指出:

  • RedLock 依赖「系统模型假设」(如无时钟跳跃、无长时间 GC),在异步模型下无法保证绝对安全。
  • 推荐使用基于 ZooKeeper/etcd 的 CAS 操作 替代。

Antirez 的回应 Is Redlock safe?:

  • RedLock 在 实践中的大多数场景 下足够安全,但需权衡场景需求。

2. 使用建议

  • 适用场景:对锁的可靠性要求高,可容忍极低概率的锁失效(如非金融场景)。
  • 规避方案
    • 结合业务幂等性 + 状态机,即使锁失效也能保证最终一致性。
    • 使用 Fencing Token(递增令牌)防止过期锁操作资源(需存储层支持)。

五、RedLock 性能优化

1. 节点数量选择

  • 建议节点数:5 或 7(容错能力与性能的平衡)。
  • 容错能力公式:允许宕机节点数 = (N-1)/2。

2. 超时时间设置

  • 加锁超时:建议 50-200ms(避免长时间阻塞)。
  • 锁过期时间:业务最大执行时间的 2-3 倍。

3. 异步加锁优化

使用 tryLockAsync() 实现非阻塞加锁:

RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
RFuture<Boolean> future = redLock.tryLockAsync(100, 10, TimeUnit.SECONDS);
future.whenComplete((res, ex) -> {
    if (res) {
        // 加锁成功
    }
});

六、对比其他方案

方案优点缺点适用场景
Redis 单节点锁高性能、简单主从切换可能丢锁非关键业务、低并发
RedLock高可靠性(多节点容错)性能较低、实现复杂高可靠性要求
ZooKeeper 锁CP 模型、强一致性性能差、依赖 ZK 集群金融、政务系统
etcd 锁高并发、强一致性(Raft 协议)功能较简单Kubernetes 生态、高并发

七、总结

Redisson 的 RedLock 实现通过多节点协作,显著提升了分布式锁的可靠性,但其复杂性、性能损耗和潜在风险(如时钟问题)需谨慎评估。技术选型建议

  • 常规场景:优先使用单节点 Redis 锁(结合业务幂等性)。
  • 高可靠场景:评估 RedLock 或转向 ZooKeeper/etcd。
  • 混合方案:对关键资源使用 RedLock,非关键资源使用单节点锁。

最终,分布式锁的可靠性不仅依赖中间件,还需结合业务层的容错设计(如事务补偿、异步校对),才能构建健壮的分布式系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2378111.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 3.13.3 安装教程

原文来自&#xff1a;Python 3.13.3 安装教程 | w3cschool笔记 &#xff08;请勿标记为付费&#xff01;&#xff01;&#xff01;&#xff09; Python 是一种广泛使用的编程语言&#xff0c;广泛应用于 Web 开发、科学计算、数据处理、人工智能等领域。Python 3.13.3 作为 P…

现代化水库运行管理矩阵平台如何建设?

政策背景 2023年8月24日&#xff0c;水利部发布的水利部关于加快构建现代化水库运行管理矩阵的指导意见中指出&#xff0c;在全面推进水库工程标准化管理的基础上&#xff0c;强化数字赋能&#xff0c;加快构建以推进全覆盖、全要素、全天候、全周期“四全”管理&#xff0c;完…

2025程序设计天梯赛补题报告

2025程序设计天梯赛补题报告 仅包含L1 L2 L1-6 这不是字符串题 题目描述 因为每年天梯赛字符串题的解答率都不尽如人意&#xff0c;因此出题组从几年前开始决定&#xff1a;每年的天梯赛的 15 分一定会有一道字符串题&#xff0c;另外一道则一定不是字符串题。 小特现在有…

SpringBoot3.4.5下Lombok的@Data注解不生效,解决方案

程序员Feri一名12年的程序员,做过开发带过团队创过业,擅长Java、嵌入式、鸿蒙、人工智能等,专注于程序员成长那点儿事,希望在成长的路上有你相伴&#xff01;君志所向,一往无前&#xff01; 1.问题 最近的项目是Python、Java、鸿蒙的来回交叉&#xff0c;再做的一个Java的项目…

如何在 Windows 上安装类似 Synaptic 的 Chocolatey GUI 包管理器

如果你正在寻找类似 Linux 中 APT 的 Windows 包管理器&#xff0c;那么没有什么比 Chocolatey 更好的了。它是 Windows 10 上可用的最佳包管理器之一&#xff0c;可以通过命令行界面安装所有流行的软件和工具。然而&#xff0c;这并不意味着如果你不喜欢命令行&#xff0c;你就…

Guided Filtering相关记录

一、背景介绍 以前折腾保边滤波时候&#xff0c;刷了一些Guided Filtering相关资料。这里主要是对它们做个算法效果复现和资料简单整理。 二、Guided Filtering 1、基本原理 原版Guided Filtering的提出&#xff0c;主要是为了改善双边滤波做保边平滑滤波器时候的梯度翻转伪影…

智能AI构建工地安全网:跌倒、抽搐、区域入侵多场景覆盖

智能AI在工地安全中的应用&#xff1a;从监测到救援的全流程实践 一、背景&#xff1a;高温作业下的工地安全挑战 随着夏季高温持续&#xff0c;工地户外作业环境面临严峻考验。工人因高温疲劳、脱水或突发疾病引发的行为异常&#xff08;如晕厥、抽搐、跌倒&#xff09;频发…

Spring+LangChain4j小智医疗项目

这里写目录标题 LangChain4j入门配置测试Ollama阿里云百炼平台AIService聊天记忆隔离聊天 MongoDB持久化存储Prompt*创建小智医疗助手Function Calling&#xff08;Tools&#xff09;实战小智医疗智能体 RAGToken分词器向量存储流式输出总结 LangChain4j入门 LangChain4j 是一…

解决“VMware另一个程序已锁定文件的一部分,进程无法访问“

问题描述 打开VMware里的虚拟机时&#xff0c;弹出"另一个程序已锁定文件的一部分&#xff0c;进程无法访问"如图所示&#xff1a; 这是VM虚拟机的保护机制。虚拟机运行时&#xff0c;为防止数据被篡改&#xff0c;会将所运行的文件保护起来。当虚拟机崩溃或者强制…

buuctf Crypto-鸡藕椒盐味1

1.题目&#xff1a; 公司食堂最新出了一种小吃&#xff0c;叫鸡藕椒盐味汉堡&#xff0c;售价八块钱&#xff0c;为了促销&#xff0c;上面有一个验证码&#xff0c;输入后可以再换取一个汉堡。但是问题是每个验证码几乎都有错误,而且打印的时候倒了一下。小明买到了一个汉堡&a…

FreeRTOS的学习记录(基础知识)

FreeRTOS 简介 FreeRTOS 是一个开源的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;专为嵌入式系统设计。它提供了任务管理、时间管理、信号量、消息队列、内存管理等功能&#xff0c;适用于资源受限的微控制器。 FreeRTOS 是一个开源的实时操作系统内核&#xff0c…

会议分享|高超声速流动测量技术研讨会精彩探析

由中国空气动力学会测控专业委员会主办&#xff0c;中国科学技术大学工程科学学院承办的第八届三次委员会暨高超声速流动测量技术研讨会&#xff0c;5月16日在合肥盛大开幕。 会议专家报告分享了高超声速流动测量的最新研究成果、挑战与突破&#xff0c;展示了PIV高速摄像机、粒…

1-10 目录树

在ZIP归档文件中&#xff0c;保留着所有压缩文件和目录的相对路径和名称。当使用WinZIP等GUI软件打开ZIP归档文件时&#xff0c;可以从这些信息中重建目录的树状结构。请编写程序实现目录的树状结构的重建工作。 输入格式: 输入首先给出正整数N&#xff08;≤104&#xff09;…

Unix/Linux | A Programming Guide

注&#xff1a;本文为 “UNIX / Linux 教程” 相关文章合辑。 略作重排&#xff0c;如有内容异常&#xff0c;请看原文。 UNIX / Linux Tutorial for Beginners: Learn Online in 7 days By : Emily Carter UpdatedFebruary 5, 2025 UNIX / Linux Tutorial Summary Linux …

前端——布局方式

普通流&#xff08;标准流&#xff09; 所谓的标准流: 就是标签按照规定好默认方式排列. 1. 块级元素会独占一行&#xff0c;从上向下顺序排列。 常用元素&#xff1a;div、hr、p、h1~h6、ul、ol、dl、form、table 2. 行内元素会按照顺序&#xff0c;从左到右顺序排列&am…

Multimodal models —— CLIP,LLava,QWen

目录 CLIP CLIP训练 CLIP图像分类 CLIP框架 Text Enocder Image Encoder LLava系列 LLava LLava贡献 LLava模型结构 总结 LLava两阶段训练 LLava 1.5 LLava 1.6 QWen CLIP CLIP是OpenAI 在 2021 年发布的&#xff0c;最初用于匹配图像和文本的预训练神经网络模型…

LabVIEW与PLC通讯程序S7.Net.dll

下图中展示的是 LabVIEW 环境下通过调用S7.Net.dll 组件与西门子 PLC 进行通讯的程序。LabVIEW 作为一种图形化编程语言&#xff0c;结合S7.Net.dll 的.NET 组件优势&#xff0c;在工业自动化领域中可高效实现与 PLC 的数据交互&#xff0c;快速构建工业监控与控制应用。相较于…

使用GpuGeek高效完成LLaMA大模型微调:实践与心得分享

使用GpuGeek高效完成LLaMA大模型微调&#xff1a;实践与心得分享 &#x1f31f;嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 随着大模型的发展&#xff0…

华为IP(6)

VLAN聚合 VLAN聚合产生的技术背景 在一般是三层交换机中&#xff0c;通常采用一个VLAN接口的方式实现广播域之间的互通&#xff0c;这在某些情况下导致了IP地址的浪费 因为一个VLAN对应的子网中&#xff0c;子网号、子网广播地址、子网网关地址不能用作VLAN内的主机IP地址&a…

1:OpenCV—图像基础

OpenCV教程 头文件 您只需要在程序中包含 opencv2/opencv.hpp 头文件。该头文件将包含应用程序的所有其他必需头文件。因此&#xff0c;您不再需要费心考虑程序应包含哪些头文件。 例如 - #include <opencv2/opencv.hpp>命名空间 所有 OpenCV 类和函数都在 cv 命名空…