当前位置: 首页 > news >正文

基于 Redis 的分布式锁实现原理及步骤

实现分布式锁的目的是在分布式系统中,保证多个节点之间对共享资源的并发访问是互斥的。常用的分布式锁实现方式有以下几种:基于数据库、基于 Redis、基于 Zookeeper。下面详细介绍基于 Redis 的分布式锁实现原理及步骤。

一、Redis 分布式锁原理

  1. 唯一性:通过 Redis 的 SET 命令加锁时,使用了 NX(仅当键不存在时才设置键)选项来确保只有一个客户端能成功获取锁。

  2. 超时释放:使用 SET 命令的 EX 参数(设置键的过期时间)来避免死锁问题,即客户端在获取锁后如果出现故障,没有主动释放锁,锁会在一定时间后自动释放。

  3. 原子操作:Redis 的 SET 命令结合 NX 和 EX 参数,保证加锁的原子性,即检查键是否存在和设置键是一个原子操作。

  4. 锁释放:客户端执行完任务后,需要主动释放锁。释放锁时需要检查当前锁是否是自己持有的,以防止释放他人的锁。

二、实现步骤

1. 获取锁

使用 Redis 的 SET 命令获取锁,结合 NX 和 EX 参数。

public boolean tryLock(String key, String value, int expireTime) {// 使用 Redis 客户端进行操作String result = jedis.set(key, value, "NX", "EX", expireTime);return "OK".equals(result);}
  • key: 锁的标识(通常是共享资源的唯一标识)。

  • value: 锁的拥有者标识,可以使用 UUID 确保唯一性。

  • NX: 表示仅在 key 不存在时才进行设置。

  • EX: 设置过期时间,避免死锁。

  • expireTime: 锁的自动过期时间,单位为秒。

2. 释放锁

释放锁时,先检查锁是否是当前客户端持有的,避免误删他人的锁。

 public boolean releaseLock(String key, String value) {String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +"return redis.call('del', KEYS[1]) " +"else return 0 end";Object result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(value));return "1".equals(result.toString());}
  • 使用 Lua 脚本确保获取锁值与删除操作的原子性。这样可以避免在锁到期前发生意外,导致锁的值被修改而释放了其他客户端的锁。

3. 锁过期时间和自动续期

如果业务逻辑执行时间超过了锁的有效期,则可能出现锁过期后被其他客户端抢占的问题。为了解决这个问题,可以使用锁自动续期机制,例如:

  • 定时任务:定期检测锁是否接近过期,如果即将过期且仍然需要占用锁,则重新设置锁的过期时间。

  • 专用线程:开辟一个独立的线程,在锁持有期间定时续期。

4. 锁竞争

Redis 通过单线程处理命令,因此多个客户端尝试获取同一个锁时,Redis 会通过队列顺序处理每个客户端的请求,确保只有一个客户端能获取到锁。那些未获取到锁的客户端可以选择以下方式:

  • 重试:可以使用退避策略(比如指数退避)进行重试,避免频繁请求 Redis。

  • 超时退出:如果重试一段时间后仍然没有获取到锁,可以选择放弃并抛出超时异常。

三、Redis 分布式锁的优缺点

优点:
  1. Redis 的性能非常高,分布式锁的获取和释放效率较高。

  2. 实现简单,基于 Redis 可以快速构建分布式锁机制。

缺点:
  1. 锁的安全性依赖于 Redis 的稳定性。如果 Redis 宕机,锁的状态会丢失。

  2. 在网络延迟较大或 Redis 出现主从切换时,锁可能会丢失,导致多个客户端同时持有锁。

四、Redlock 算法

为了进一步提高锁的可靠性,Redis 作者提出了 Redlock 算法,该算法通过多个 Redis 实例共同维护锁的状态,避免单点故障导致的锁丢失。Redlock 的原理如下:

  1. 部署多个 Redis 实例,通常是 5 个。

  2. 客户端依次向多个 Redis 实例请求锁,只有当超过半数的实例(比如 3 个)成功获得锁后,才认为获取锁成功。

  3. 如果获取锁失败,需要主动释放已经获取的部分锁,确保没有锁残留。


Redis 分布式锁是一种简单高效的实现方式,适用于大多数分布式场景。通过合理设置锁的超时时间、自动续期机制,以及结合 Lua 脚本进行锁释放,可以有效避免死锁和误释放问题。不过,在高可用性要求较高的场景下,推荐使用 Redlock 算法来提高锁的可靠性。

  更多精彩请关注我的Github:Utopia007 (Qiao Guanhao) · GitHub

相关文章:

基于 Redis 的分布式锁实现原理及步骤

实现分布式锁的目的是在分布式系统中,保证多个节点之间对共享资源的并发访问是互斥的。常用的分布式锁实现方式有以下几种:基于数据库、基于 Redis、基于 Zookeeper。下面详细介绍基于 Redis 的分布式锁实现原理及步骤。 一、Redis 分布式锁原理 唯一性…...

21_动态规划与数据结构结合

菜鸟:老鸟,我最近在处理一个数据操作时遇到了性能问题。我需要计算一个数组中某些子数组的和,但直接计算太慢了,有没有什么更高效的方法? 老鸟:你提到的这个问题其实可以通过动态规划结合数据结构来解决。…...

React与Vue的对比

异同总结 相同点: 都有组件化思想 都支持服务器端渲染 都有Virtual DOM(虚拟dom) 数据驱动视图 都有支持native的方案:Vue的weex、React的React native 都有自己的构建工具:Vue的vue-cli、React的Create React A…...

精密量测软件(仿KLA免费浏览器程序ProfilmOnline)

KLA在线软件分析图 软件仿KLA公司免费浏览器软件ProfilmOnline,软件地址ProfilmOnline - 用于3D轮廓仪和AFM的表面成像、分析和测量软件 可以直接从profilmonline上下载3D图加载对比分析,当前已完成的内容有 1、调平 2、尖峰去噪 3、能量密度图&…...

Java项目: 基于SpringBoot+mybatis+maven实现的IT技术交流和分享平台(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven实现的IT技术交流和分享平台 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美…...

STL02——手写简单版本的list

手写一个简单版本的list 设计一个名为 List 的 List 类,该类具有以下功能和特性: 1、基础成员函数 构造函数:初始化 List 实例析构函数:清理资源,确保无内存泄露 2、核心功能 在 List 末尾添加元素在 List 开头添…...

基于SpringBoot的校园自助洗衣服务管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的校园自助洗衣服务…...

音视频入门基础:AAC专题(2)——使用FFmpeg命令生成AAC裸流文件

在文章《音视频入门基础:PCM专题(1)——使用FFmpeg命令生成PCM音频文件并播放》中讲述了生成PCM文件的方法。通过FFmpeg命令可以把该PCM文件转为AAC裸流文件: ./ffmpeg -f s16le -ar 44100 -ac 2 -i audio1.pcm audio1.aac 由于…...

第 6 篇 自定义 Helm Chart

文章目录 第 1 步:创建 chartChart.yamlvalues.yamltemplates 模板文件_helpers.tpl 模板辅助文件serviceaccount.yamlservice.yamldeployment.yamlhpa.yamlingress.yamlNOTES.txttests/test-connection.yaml 第 2 步:检查 chart 格式第 3 步&#xff1a…...

Jenkis部署vue前端项目提示:sh: vue-cli-service: command not found

解决方法: 1. 进入到/var/lib/jenkins/workspace/项目名下,查看是否有node_modules,如果没有执行 npm install 2. 如果执行npm intall的过程中提示:npm ERR! 407 Proxy Authentication Required - GET http://registry.npm.taob…...

中介者模式mediator

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/mediator 减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。...

GO语言性能分析

Go语言基准测试与pprof工具性能分析详解 在现代软件开发中,性能优化是一个重要的环节。Go语言提供了强大的工具来进行基准测试和性能分析,其中 testing 包用于基准测试,而 pprof 工具用于性能分析。本文将详细讲解如何使用这些工具来进行性能…...

关于 PreparedStatement

Mysql 层面的语法也支持 prepare 这个确实第一次见 PREPARE prepares a statement for execution (see Section 13.5.1, “PREPARE Statement”).EXECUTE executes a prepared statement (see Section 13.5.2, “EXECUTE Statement”).DEALLOCATE PREPARE releases a prepared…...

漫谈设计模式 [9]:外观模式

引导性开场 菜鸟:老鸟,我最近在做一个项目,感觉代码越来越复杂,我都快看不懂了。尤其是有好几个子系统,它们之间的调用关系让我头疼。 老鸟:复杂的代码确实让人头疼。你有没有考虑过使用设计模式来简化你…...

多进程编程

基本概念 进程是一个具有单独功能的程序对某个数据集在处理机上的执行过程,进程也是作为资源分配的一个单位。 进程和程序是相辅相成的,进程是一个动态概念。 进程具有并行性特征。进程具有独立性和异步性。 进程的描述 进程分为三部分:…...

7-Zip压缩包如何添加密码,加密后如何取消

压缩包文件大家经常使用,最熟悉的肯定是RAR、ZIP格式压缩文件,但是7z压缩文件格式也很好用,它是三种压缩文件格式中压缩率最大的。想要将文件压缩到最小,使用7z格式可以达到最大化。那么在使用7z压缩格式的时候,我们可…...

HarmonyOS---应用测试概述

一、应用质量要求 应用质量要求分为应用体验质量建议和应用内容合规要求两大部分。 1、应用体验质量建议 功能数据完备、基础体验要求、HarmonyOS特征增强体验要求。 (1)功能数据完备 (2)基础体验要求 (3)增…...

密码学---真题演练

✨Base加密:题目-base? 靶场网址:https://polarctf.com/ Base100加密!!! 得到的新的一串密码是 rot47 密码,属于凯撒密码的一种变体. ✨斐波那契:题目-FB 从第三项开始,每一项都等…...

时间日期工具类

时间日期工具类 import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit;public class DateTimeUtils {private static final String DEFAULT_DATE_FORMAT "yyyy-MM-dd";private static final String DEFAULT_TIME_…...

linux中vim常用命令大全

前言 Linux有大量的配置文件,所以 Linux的文本处理工具也是比较多的,其中编辑一些配置文件时,常用的工具就是 vim。在Linux中,Vim编辑器是一个非常强大的文本编辑工具,它提供了多种模式和命令来满足不同的编辑需求。以…...

XCTF-web-easyupload

试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

【HTTP三个基础问题】

面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)&#xff…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

Vue ③-生命周期 || 脚手架

生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...