Redis 分布式锁实现深度解析

Redis 分布式锁是分布式系统中协调多进程/服务对共享资源访问的核心机制。以下从基础概念到高级实现进行全面剖析。

一、基础实现原理

1. 最简实现(SETNX 命令)

# 加锁
SET resource_name my_random_value NX PX 30000# 解锁(Lua脚本保证原子性)
if redis.call("get",KEYS[1]) == ARGV[1] thenreturn redis.call("del",KEYS[1])
elsereturn 0
end

关键要素

  • NX:仅当key不存在时设置(原子性保证)
  • PX 30000:30秒自动过期(防死锁)
  • my_random_value:唯一客户端标识(防误删)

2. 实现演进对比

版本

方案

问题

v1.0

SETNX + EXPIRE

非原子操作可能死锁

v2.0

SET NX PX

无法解决误删锁问题

v3.0

唯一值 + Lua解锁

基本满足需求

v4.0

Redlock算法

解决单点问题

二、Redis 单实例实现详解

1. 完整加锁流程

sequenceDiagramparticipant Clientparticipant RedisClient->>Redis: SET lock:order UUID123 NX PX 30000alt 锁空闲Redis-->>Client: OKClient->>Client: 启动看门狗线程else 锁占用Redis-->>Client: nilClient->>Redis: BLPOP lock:order:notify 30Redis--xClient: 等待通知或超时end

2. 看门狗机制(续期)

def watchdog(lock_key, client_id, ttl):while True:time.sleep(ttl / 3)  # 每10秒续期一次if not redis.call("EVAL", "if redis.call('get', KEYS[1]) == ARGV[1] then " +"return redis.call('pexpire', KEYS[1], ARGV[2]) " +"else return 0 end",1, lock_key, client_id, ttl):break  # 续期失败退出

3. 解锁通知优化

lua

-- 解锁时发布通知
redis.publish("lock:order:notify", "released")-- 客户端订阅
SUBSCRIBE lock:order:notify

三、Redlock 集群算法

1. 算法流程

  1. 获取当前毫秒级时间戳 T1
  2. 依次向 N 个 Redis 节点请求加锁(相同TTL)
  3. 计算获取锁耗时 = 当前时间 T2 - T1
  4. 当且仅当满足:
    • 获得多数节点(N/2 + 1)认可
    • 总耗时 < 锁TTL
  1. 锁有效时间 = 初始TTL - 获取锁耗时

2. 节点故障处理

graph TDA[客户端] --> B[Redis Master1]A --> C[Redis Master2]A --> D[Redis Master3]B -->|响应超时| E[标记节点不可用]C -->|成功获取| F[锁计数+1]D -->|成功获取| F

3. 关键参数配置

参数

建议值

说明

节点数

5

允许2个节点故障

重试延迟

50-200ms

随机化避免冲突

锁TTL

10-30s

业务完成时间+缓冲

四、生产级问题解决方案

1. 时钟漂移问题

场景

  • 节点间时钟不同步导致TTL计算错误

解决方案

python

# 使用单调时钟而非系统时钟
start_time = get_monotonic_time()
elapsed = get_monotonic_time() - start_time
remaining_ttl = initial_ttl - elapsed

2. GC停顿导致锁失效

应对策略

  • 设置保守TTL(业务最大耗时×2)
  • 添加JVM监控告警
  • 关键业务禁用GC(如ZGC)

3. 客户端长时间阻塞

优化方案

java

// 非阻塞尝试
boolean locked = tryLock(5, TimeUnit.SECONDS);// 异步获取
RFuture<Boolean> future = lock.tryLockAsync();

五、各语言实现对比

语言

推荐库

特性

Java

Redisson

支持看门狗、多种锁类型

Go

redsync

实现Redlock算法

Python

redis-py

基础锁实现

Node.js

node-redlock

TypeScript支持

六、性能优化方案

1. 锁分段技术

python

def get_segment_lock(resource_id):segment = resource_id % 16  # 分为16段return f"lock:{resource_type}:{segment}"# 使用示例
lock = get_segment_lock(order_id)

2. 读写锁分离

redis

# 写锁
SET rwlock:order WRITE <client_id> NX PX 10000# 读锁计数器
INCR rwlock:order:read_count

3. 热点锁优化

策略

实施方法

适用场景

本地缓存

先获取本地锁再尝试分布式锁

极高并发

令牌桶

控制获取锁的速率

突发流量

乐观锁

CAS机制更新资源

冲突较少

七、监控与告警指标

1. 关键监控项

bash

# Redis监控
redis-cli info stats | grep lock
redis-cli slowlog get  # 查看锁命令耗时# 客户端监控
lock_acquire_time_seconds_bucket{le="0.1"} 0.95  # 99%锁获取<100ms
lock_hold_time_seconds_sum / lock_hold_time_seconds_count  # 平均持有时间

2. 告警规则示例

yaml

# Prometheus规则
- alert: HighLockContentionexpr: rate(redis_commands_total{cmd="SET",arg0~="lock:*"}[1m]) > 100for: 5mlabels:severity: warningannotations:summary: "High lock contention detected"

八、选型决策指南

mermaid

graph TDA[需要强一致性?] -->|是| B[Redlock+5节点]A -->|否| C[单Redis+看门狗]B --> D[业务容忍延迟?]D -->|是| E[同步确认]D -->|否| F[异步确认]C --> G[需要自动续期?]G -->|是| H[Redisson]G -->|否| I[基础SETNX]

通过深入理解这些原理和实现细节,可以构建出既安全又高效的Redis分布式锁方案。建议根据实际业务场景的CAP需求进行技术选型和参数调优。

Redisson分布式锁深度解析:原理与实现机制 参见上一篇

Redisson分布式锁深度解析:原理与实现机制-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Rust基础】使用LanceDB构建高性能以图搜图服务

简介 最近使用LanceDB构建了一个以图搜图服务&#xff0c;用于相似图片检索&#xff0c;支持以下功能&#xff1a; 搜索 支持向量搜索&#xff0c;查找相似图片支持通过item_id搜索精确搜索 数据管理 支持添加数据、批量导入CSV或JSON数据支持已有数据修改、删除 API 提供HTT…

蓝桥杯备考:模拟算法之排队接水

简单的模拟就行了&#xff0c;把他们的时间排序&#xff0c;时间最少的先上&#xff0c;然后算出每个人的等待时间的平均值 #include <iostream> #include <algorithm> using namespace std; const int N 1e310; int n; double sum; double ret; struct node{int…

zynq7000 + ucos3 + lwip202_v1_2调试过程

1 现在裸机应用上验证lwip 跑起来可能会报错&#xff0c;看下面的链接解决 zynq 网卡Phy setup error问题 zynq 网卡Phy setup error问题-CSDN博客 2 ping同以后&#xff0c;在zynq上添加ucos系统 链接如下&#xff1a; ZYNQ移植uCOSIII_zynq ucos-CSDN博客 3 移植lwip协议…

如何用 Postman 正确传递 Date 类型参数,避免服务器解析错误?

如何在 Postman 中传递 Date 类型参数。调试工具如何模拟发送用户端的当前时间呢&#xff1f; Postman 传递 Date 类型参数教程

卷积神经网络在图像分割中的应用:原理、方法与进展介绍

摘要 图像分割是计算机视觉领域的核心任务之一&#xff0c;旨在将图像划分为具有语义意义的区域。卷积神经网络&#xff08;CNN&#xff09;因其强大的特征提取能力&#xff0c;已成为图像分割的主流方法。本文系统介绍了CNN在图像分割中的关键技术&#xff0c;包括全卷积网络…

VMware Windows Tools 存在认证绕过漏洞(CVE-2025-22230)

漏洞概述 博通公司&#xff08;Broadcom&#xff09;近日修复了 VMware Windows Tools 中存在的一个高危认证绕过漏洞&#xff0c;该漏洞编号为 CVE-2025-22230&#xff08;CVSS 评分为 9.8&#xff09;。VMware Windows Tools 是一套实用程序套件&#xff0c;可提升运行在 VM…

DeepSeek-V3-0324对比OpenAI GPT-4o和Gemini 2.5 Pro

以下是DeepSeek-V3-0324、OpenAI GPT-4o与谷歌Gemini 2.5 Pro模型的更新点及优化对比总结&#xff1a; 1. DeepSeek-V3-0324 开源地址&#xff1a;https://huggingface.co/deepseek-ai/DeepSeek-V3-0324 核心更新与优化 性能提升&#xff1a; 采用6850亿参数MoE架构&#xff…

视频编码器的抉择:x264、x265、libaom、vvenc 对比测试实验

264、x265、libaom、vvenc 对比测试实验 测试机器配置&#xff1a;Apple M1 Pro -16G编码器版本&#xff08;选择自己编译&#xff09;&#xff1a;所有源码都是当前最新更新的状态&#xff0c;此外各类编码具体的编译过程可参考我的相关系列博客。 编码器GitHubx264git clon…

【极速版 -- 大模型入门到进阶】LORA:大模型轻量级微调

文章目录 &#x1f30a; 有没有低成本的方法微调大模型&#xff1f;&#x1f30a; LoRA 的核心思想&#x1f30a; LoRA 的初始化和 r r r 的值设定&#x1f30a; LoRA 实战&#xff1a;LoraConfig参数详解 论文指路&#xff1a;LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE M…

初识MySQl · 内置函数

目录 前言&#xff1a; 日期类函数 字符串函数 数学类函数 其他函数 前言&#xff1a; 在前文的学习我们已经简单了解了部分函数&#xff0c;比如count()函数什么的&#xff0c;今天我们主要是笼统的学习一下MySQL中的函数&#xff0c;仅仅从使用的角度来学习&#xff0c…

Python每日一题(7)

Python每日一题 2025.3.27 一、题目二、分析三、自己源代码四、deepseek答案五、源代码与ai分析 一、题目 question["""编写程序,生成包含20个随机数的列表,然后将前十个元素升序排列,后10个元素降序排列,并输出结果""" ]二、分析 今天本来写了…

一些需要学习的C++库:CGAL和Eysshot

写在前面&#xff1a; 从开始工作到现在&#xff0c;去过多家公司&#xff0c;多个行业&#xff0c; 虽然大部分时间在通信业&#xff0c;但也有其它的行业的工作没有做完&#xff0c;但也很感兴趣。每次想要研究一下时&#xff0c;总是想不起来。 这里写一些信息&#xff0c;…

嵌入式linux系统中对应的文件锁详细实现方法

//文件锁:flock用于对文件加锁或者解锁但是只能产生建议性锁,并且同一个文件不会同时 具有共享锁和互斥锁。 第一:flock函数对应的要素 头文件: #include <sys/file.h> 函数原型:int flock(int fd,int operation) 参数: fd:表示需要加锁文件的文件描述符 operati…

WEB或移动端常用交互元素及组件 | Axure / 元件类型介绍(表单元件、菜单和表格 、流程元件、标记元件)

文章目录 引言I Axure / 元件类型介绍基本元件表单元件菜单和表格流程元件标记元件II Axure 基础Axure / 常用功能介绍Axure / 常用元素实例Axure / 动态交互实例Axure / 常用设计分辨率推荐III Axure / 创建自己的元件库元件库作用元件库的创建及使用引言 I Axure / 元件类型介…

如何排查C++程序的CPU占用过高的问题

文章目录 可能的原因程序设计的BUG系统资源问题恶意软件硬件问题 通常步骤一个简单的问题代码在windows平台上如何排查Windows Process ExplorerWinDBG 在Linux平台如何排查使用TOP GDBPerf 可能的原因 程序设计的BUG 有死循环低效算法与数据结构滥用自旋锁频繁的系统调用&a…

19726 星际旅行

19726 星际旅行 ⭐️难度&#xff1a;困难 &#x1f31f;考点&#xff1a;Dijkstra、省赛、最短路问题、期望、2024 &#x1f4d6; &#x1f4da; import java.util.*;public class Main {static int N 1005;static ArrayList<Integer>[] g new ArrayList[N]; // …

vue3 + ant-design-vue4实现Select既可以当输入框也可以实现下拉选择

近日工作中&#xff0c;遇到一个需求&#xff0c;就是select的有一个前置切换条件&#xff0c;有些条件需要时输入&#xff0c;有些条件需要时下拉选择&#xff0c;但是在切换的时候&#xff0c;后面的这个输入或者选择组件不能闪烁&#xff0c;于是也就只能采用select去实现&a…

Unity UGUI - 六大基础组件

目录 一、Canvas上 1. Canvas&#xff1a;复制渲染子UI控件 2. ✨Canvas Scaler✨&#xff1a;画布分辨率自适应 3. Graphics Raycaster&#xff1a;射线事件响应 4. ✨Rect Transform✨&#xff1a;UI位置锚点对齐 二、Event System上 5. Event System 6. Standalone …

VSCode中使用Markdown以及Mermaid实现流程图和甘特图等效果

前言 Markdown&#xff08;简称md&#xff09;这种文件格式&#xff0c;渐渐盛行起来。有点类似html格式的意思。特别是内嵌的对Marmaid的支持&#xff0c;对流程图、甘特图等的绘制&#xff0c;都非常的方便。 一、安装Markdown的插件 二、创建.md文件 新建一个Markdown文件&…

如何让 history 记录命令执行时间?Linux/macOS 终端时间戳设置指南

引言:你真的会用 history 吗? 有没有遇到过这样的情况:你想回顾某个重要命令的执行记录,却发现 history 只列出了命令序号和内容,根本没有时间戳?这在运维排查、故障分析、甚至审计时都会带来极大的不便。 想象一下,你在服务器上误删了某个文件,但不知道具体是几点执…