分布式中间件:基于 Redis 实现分布式锁

分布式中间件:基于 Redis 实现分布式锁

一、背景引入

在当今的互联网应用中,分布式系统变得越来越常见。在分布式环境下,多个服务实例可能会同时对共享资源进行读写操作,这就很容易引发数据不一致等问题。比如电商系统中的库存扣减,如果多个订单处理服务同时对同一商品的库存进行操作,就可能导致超卖现象。为了解决这类问题,分布式锁应运而生。分布式锁能够保证在分布式系统中,同一时刻只有一个服务实例可以对共享资源进行操作,从而确保数据的一致性和完整性。

Redis 作为一款高性能的开源内存数据库,具有丰富的数据结构和原子操作特性,成为了实现分布式锁的理想选择。接下来,我们将深入探讨如何基于 Redis 实现分布式锁。

二、Redis 实现分布式锁的原理

(一)基本原理

Redis 实现分布式锁主要是利用了其原子性操作。Redis 提供了 SET 命令,该命令可以原子性地设置一个键值对,并且可以同时设置过期时间。当多个客户端同时尝试获取锁时,只有一个客户端能够成功设置该键值对,从而获得锁。

(二)具体命令

使用 SET key value NX PX timeout 命令,其中:

  • key:表示锁的名称,通常是一个具有业务含义的字符串,例如 product:1:lock 表示对商品 ID 为 1 的资源加锁。
  • value:可以是一个唯一的标识,用于区分不同的客户端,防止误解锁。例如,可以使用 UUID 作为 value。
  • NX:表示只有当键不存在时才进行设置操作,如果键已经存在,则设置失败,这保证了同一时刻只有一个客户端能获得锁。
  • PX timeout:设置键的过期时间,单位为毫秒。这是为了防止持有锁的客户端出现异常(如崩溃)而导致锁无法释放,造成死锁。

三、代码实现

(一)Java 代码示例

import redis.clients.jedis.Jedis;
import java.util.UUID;public class RedisDistributedLock {private static final String LOCK_KEY = "my_distributed_lock";private static final int LOCK_EXPIRE_TIME = 5000; // 锁的过期时间,单位:毫秒private Jedis jedis;public RedisDistributedLock() {this.jedis = new Jedis("localhost", 6379);}public String acquireLock() {String requestId = UUID.randomUUID().toString();String result = jedis.set(LOCK_KEY, requestId, "NX", "PX", LOCK_EXPIRE_TIME);if ("OK".equals(result)) {return requestId;}return null;}public boolean releaseLock(String requestId) {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, 1, LOCK_KEY, requestId);return "1".equals(result.toString());}public void close() {jedis.close();}
}

(二)代码解释

  • acquireLock 方法:生成一个唯一的 requestId,然后使用 SET 命令尝试获取锁。如果返回 OK,表示成功获取锁,返回该 requestId;否则返回 null
  • releaseLock 方法:使用 Lua 脚本确保释放锁的操作是原子性的。首先检查当前锁的 value 是否与传入的 requestId 相等,如果相等则删除该键,释放锁,并返回 1;否则返回 0。
  • close 方法:关闭 Redis 连接。

(三)使用示例

public class Main {public static void main(String[] args) {RedisDistributedLock lock = new RedisDistributedLock();String requestId = lock.acquireLock();if (requestId != null) {try {System.out.println("成功获取锁,开始执行临界区代码");// 模拟临界区代码执行Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();} finally {lock.releaseLock(requestId);System.out.println("成功释放锁");}} else {System.out.println("获取锁失败");}lock.close();}
}

四、Redis 分布式锁的优缺点

(一)优点

  1. 高性能:Redis 是基于内存的数据库,读写速度非常快,能够满足高并发场景下的锁操作需求。
  2. 原子操作:Redis 提供了原子操作,如 SET 命令和 Lua 脚本,保证了锁的获取和释放操作的原子性,避免了并发问题。
  3. 可扩展性:Redis 可以通过集群或主从复制等方式实现高可用性和可扩展性,满足大规模分布式系统的需求。

(二)缺点

  1. 单点故障:如果 Redis 节点出现故障,可能会导致锁服务不可用。虽然可以通过集群或主从复制来解决,但仍然存在一定的风险。
  2. 时钟漂移:Redis 的锁超时机制依赖于系统时钟,如果不同节点的时钟存在漂移,可能会导致锁提前或延迟释放。
  3. 锁释放问题:如果客户端在持有锁期间崩溃,锁可能无法正常释放,需要依赖锁超时机制来解决。

五、应用场景

  1. 分布式系统中的数据一致性:在多个服务同时访问和修改共享数据时,使用分布式锁可以保证数据的一致性。例如,多个订单处理服务对同一商品的库存进行操作时,使用分布式锁可以避免超卖现象。
  2. 任务调度:在分布式任务调度系统中,使用分布式锁可以保证同一个任务在同一时间只被一个节点执行。例如,定时清理缓存的任务,避免多个节点同时执行导致数据不一致。
  3. 资源限流:在多个客户端同时访问有限资源时,使用分布式锁可以限制同一时间的访问数量。例如,限制同一时间对某个接口的并发访问数量。

六、总结

基于 Redis 实现分布式锁是一种简单、高效的解决方案,能够满足大多数分布式系统的需求。通过合理设置锁的过期时间和使用原子操作,可以保证锁的正确性和可靠性。但同时也需要注意 Redis 的单点故障、时钟漂移等问题,在实际应用中需要根据具体场景进行优化和改进。希望本文能帮助你更好地理解和应用基于 Redis 的分布式锁。

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

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

相关文章

【C#】WinForm自定义控件及窗体

前言 WinForm(Windows Forms)是Microsoft.NET框架中的技术,用于开发Windows桌面应用程序。它提供了一套丰富的控件和组件。通过拖放控件、编写事件处理程序等方式快速构建用户界面。 通过属性窗口定制这些控件的外观和行为。 通过数据绑定&am…

Live555+Windows+MSys2 编译Androidso库和运行使用

下载 wget http://www.live555.com/liveMedia/public/live555-latest.tar.gz tar -xzvf live555-latest.tar.gz加入版本控制 git init git add . git commit -a -m "first init" git log修改config.android-arm64 cd live vim config.android-arm64 ./genMakefile…

大模型-提示词工程与架构

什么是提示工程 提示工程(Prompt Engineering)是一门新兴的技术领域,专注于研究如何设计、构建和优化提示词,以充分发挥大模型的潜力 。它涉及到对语言结构、任务需求、模型特性等多方面因素的综合考量。提示工程的目标是通过精心…

Agent Team 多智能体系统解析

引言 在人工智能技术高速发展的今天,"多智能体协作系统"(Agent Team)正成为突破效率瓶颈的关键技术。与传统的单体AI不同,这种由多个专业化智能体组成的协同网络,通过分工协作和动态调整,展现出…

【蓝桥杯—单片机】IAP15F2K61S2专项 | 真题整理、解析与拓展 | 省赛题(更新ing...)

IAP15F2K61S2 专项 前言IAP15F2K61S2 介绍(基于手册)I/O口结构复位管脚RST中断第十四届省赛 外设通过PWM控制第十五届省赛题 性能与工作参数在线调试第十四届省赛题拓展与小结:单片机在线调试常用的接口 功耗第十五届省赛题 前言 在本文中我…

生物化学笔记:医学免疫学原理02 抗原概念+免疫应答+抗原的分类

抗原基本概念 影响抗原刺激机体产生免疫应答的因素 抗原的分类 CG 【北京大学】1080p 王月丹教授 《医学免疫学原理》2022春 全81p

(UI自动化测试)第二篇:元素定位的方法_name定位

二、name定位 ⽅法: driver.find_element_by_name(“name属性值”) 前置: 标签必须name属性 特点: 当前⻚⾯可以重复 提示: 由于name属性值可以重复,所以使⽤时需要查看是否为唯⼀。 # 导包selenium from selenium i…

软考中级-软件设计师 准备

软考中级-软件设计师 准备 一、软考相关1.1、考试时间1.2、考试时长1.3、题型和分值: 二、软考备考2.1、相关书籍2.2、推荐课程:B站up主zst_20012.3、学习路线 一、软考相关 1.1、考试时间 一年有两次软考,一般是五月末和十一月的中旬 以下…

记忆力训练day24

一 数字锁链串联法 数字两位 两位的连

田间机器人幼苗视觉检测与护苗施肥装置研究(大纲)

田间机器人幼苗视觉检测与护苗施肥装置研究 基于多光谱视觉与精准施肥的农业机器人系统设计 第一章 绪论 1.1 研究背景与意义 农业智能化需求: 传统幼苗检测依赖人工,效率低且易遗漏弱苗/病苗施肥不精准导致资源浪费和环境污染 技术挑战:…

Debian12生产环境配置笔记

在 Debian 12 上进行生产环境配置的详细步骤,涵盖软件更新、基础软件安装、Docker 及 Redis 部署,以及 Nginx 配置多个虚拟主机等内容。所有命令均以 root 用户身份执行,无需添加 sudo 1. 更新软件 首先,确保系统上的所有软件包…

HAL库编程知识点---Can.c和Driver_can.c分层开发

在一个工程中,通常会把对CAN外设的操作分成底层和上层两个部分,从而提高代码的模块化和可维护性。一般来说: can.c 通常由硬件抽象层(HAL)或者自动生成工具(如 CubeMX)提供或生成。主要负责CAN硬…

7. 【Vue实战--孢子记账--Web 版开发】-- 收支分类设置

本篇文章我们一起来实现收支分类功能。收支分类和前篇文章的主币种设置界面大体类似。我们将详细介绍如何创建和管理不同的收支分类,以便用户可以更好地组织和跟踪他们的财务状况。 一、功能 先来看一下原型界面,界面很简单,这里就不多讲解…

人工智能 - DeepSeek 和 Manus 的区别和应用场景

DeepSeek 与 Manus 是人工智能领域两种不同技术路线的代表,其核心区别在于功能定位和技术实现,应用场景也因此存在显著差异。以下是两者的对比分析: 一、核心区别 技术定位 DeepSeek:定位为“超级大脑”,专注于底层大模型的研发,擅长处理数学题、代码生成、知识问答等需要…

基于yolov11的防震锤缺陷检测系统python源码+pytorch模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv11的防震锤缺陷检测系统是一种利用深度学习技术进行自动化检测的系统。防震锤是电力线路中用于防止导线因风力等因素引起振动的关键部件,其性能状态直接影响到电力线路的安全运行。然而,防震锤在使用过程中可能会因各种因素导致缺…

MySQL数据库精研之旅第二期:库操作的深度探索

专栏:MySQL数据库成长记 个人主页:手握风云 目录 一、查看数据库 二、创建数据库 2.1. 语法 2.2. 示例 三、字符集编码和校验(排序)规则 3.1. 查看数据库支持的字符集编码 3.2. 查看数据库支持的排序规则 3.3. 不同的字串集与排序规则对数据库的…

ubuntu系统/run目录不能执行脚本问题解决

目录 前言 一、问题现象 二、原因分析 三、解决办法 总结 前言 在使用 Ubuntu 系统的过程中,我们有时会遇到在 /run 目录下无法执行脚本的情况。这篇博客将详细探讨该问题的原因,并提供有效的解决方案。。 一、问题现象 当尝试在 /run 目录下执行一个…

万用表测MOS好坏

测N MOS好坏 1,首先用万用表表笔把G D S全部短接放电。 2,万用表打到二极管档位 3,红笔接S(源极),黑笔接D(漏极),万用表会显示0.5V左右的电压(内部二极管压降…

clamav服务器杀毒(Linux服务器断网状态下如何进行clamav安装、查杀)

ClamAV服务器杀毒(服务器断网状态也可以使用该方法) 服务器因为挖矿病毒入侵导致断网,进行离线的clamav安装并查杀 安装包下载网址:https://www.clamav.net/downloads 安装.deb,如果服务器处于断网状态,可以…

Linux:基础IO---文件描述符

文章目录 1. 前言1.1 C语言文件知识回顾 2. 文件2.1 文件基础知识 3. 被打开的文件3.1 以C语言为主,先回忆一下C文件接口3.2 过渡到系统,认识文件系统调用3.3 访问文件的本质3.4 重定向&&缓冲区 序:在深入了解了进程的内容后&#xf…