redis分布式锁

简介

为什么需要分布式锁

一个进程中当多线程的去竞争某一资源的时候,我们通常会用一把锁来保证只有一个线程获取到资源,在单体项目也就是部署在一台服务器上的时候,加锁只需要加synchronize关键字或ReentrantLock锁就行
那么在微服务中加synchronize关键字或ReentrantLock锁不管用了,因为每个服务都用自己的实例,锁的对象不是同一个对象。
那么这时候为了防止多个服务器同时访问一个共享变量,就需要分布式锁,例如redis分布式锁

示例

保证全局唯一性:
示例: 一个系统需要为每个新订单生成一个唯一的订单号。在分布式环境下,如果多个节点同时生成订单号,可能会导致生成重复的订单号,这会影响业务的正确性。
防止重复消费消息
示例: 在某个任务处理系统中,多个应用实例订阅同一个消息队列。如果没有锁机制,当一个任务被多个实例同时处理时,会导致任务的重复执行,影响系统性能和一致性。

总而言之,多个实例操作一个共享变量,也就是说多个请求通过不同的服务器同时访问接口中的共享变量导致最终数据不一致就需要分布式锁来控制同一时间只能有一个实例执行操作

redis实现分布式锁

redis的操作具有原子性(在 Redis 中,所有的命令执行是串行的,不会发生多个命令同时执行的情况,因此在执行某个命令时不会受到其他命令的干扰。),多个实例或者多个客户端访问redis设置同一个值的时候能保证同一时刻只有一个实例或者一个客户端能写入成功

下面依次从非安全-》安全锁的演变

简单锁(SETNX 锁)

使用 Redis 的 SETNX(Set if Not Exists)命令来实现简单的互斥锁。
实现原理:SETNX 命令会在键不存在时设置值,返回 1;如果键已经存在,则返回 0。通过这个特性,多个客户端尝试设置相同的键时,只有第一个设置成功的客户端能获得锁。

SETNX lock_key "unique_lock_identifier"

lock_key:表示锁的名字,通常是共享资源的标识符。
unique_lock_identifier:是一个唯一标识符,通常可以是当前客户端的 ID 或 UUID,用来标记当前锁的拥有者。

使用场景:适用于一些不需要过期时间、仅仅进行简单加锁和解锁的场景。

问题:
SETNX是可以加锁,但是需要手动释放锁,如果服务加锁后还没来得及释放锁就宕机了,那么这个锁就会一直存在redis中,其他服务就一直获取不到锁了

因此出现了SET NX PX

Redis 自带的锁(SET 命令的 NX 和 PX 选项)

Redis 3.0 引入了 SET 命令,可以通过 NX 和 PX 选项来实现更加简洁的分布式锁。
实现原理:通过 SET 命令的 NX(仅当键不存在时设置)和 PX(设置超时时间)选项,可以在一次命令中实现加锁和超时设置。

SET lock_key "client_id" NX EX 30

使用场景:适用于需要简单分布式锁的场景。

问题:虽然SET NX PX可以加锁并设置过期事件,但是依旧会出现问题,如果咱们设置过期时间为10s,但是业务执行时间是20s,那么在业务还没执行完成的时候锁就释放了,那么其他服务就可以获取到锁来执行这个方法中的业务,这样就会出现锁过期释放其他服务锁这两个问题

Redisson

对于锁过期问题,我们是也可以手动处理的,例如我们可以写一个定时任务,来询问这个方法执行完没有,没有就为这个锁续时间,这样比较麻烦

为了克服 SET NX PX实现分布式锁的缺点,Redisson(一个基于 Redis 的客户端)提供了一种更为强大和灵活的分布式锁实现,支持更复杂的锁机制和更高的可靠性。

Redisson其实就是内置了一个守护线程(看门狗),他会自动检查方法是否结束,以及锁释是否过期,并自动续时这样一个功能

特点如下:

自动解锁
Redisson 提供了自动解锁的功能,避免了死锁的问题。如果持有锁的客户端在持有锁时发生崩溃或超时,Redisson 会自动释放锁。

锁的过期时间
Redisson 会为每个锁设置一个合理的过期时间(TTL),以防止死锁。通过这种方式,即使客户端在没有释放锁的情况下崩溃,其他客户端仍然可以在超时后获取锁。

可重入锁
Redisson 提供了可重入锁(ReentrantLock)的实现,即同一个客户端可以多次获得锁,并且在每次获得锁时计数,只有在锁计数归零时才会释放锁。

公平锁
Redisson 支持公平锁,它确保锁的获取顺序是按照请求锁的顺序来分配的。公平锁避免了某些客户端可能一直得不到锁的问题。

锁的监控与可扩展性
Redisson 提供了对锁的监控,可以检测锁的持有者和锁的状态,允许开发者更好地控制和优化锁的使用。

问题:虽然reddisson能很好的解决锁过期问题,但是依旧有缺陷,当我们redis为了高可用,分布式需要部署集群模式,这时候就有主节点和从节点,而redisson存锁的位置其实就是主节点,如果当主节点挂掉了,从节点还没同步主节点数据的时候,其他服务来加锁了,这时候第一个服务器也加了锁,导致2个服务都开始执行加锁的业务代码,这时候就是不安全的。

Red lock

Redlock 是由 Redis 创始人 Salvatore Sanfilippo(Antirez)提出的一种分布式锁算法,旨在解决 Redis 分布式锁的可靠性问题,尤其是在多个 Redis 实例之间提供一致性和容错性。简单来说,Redlock 通过多个 Redis 实例来增强分布式锁的可靠性,从而避免了单点故障的问题。

Redlock 的基本思路是通过多个独立的 Redis 实例来实现分布式锁,减少单点故障的风险,并且通过一定的机制确保锁的可靠性。具体步骤如下:

1.准备多个 Redis 实例:
Redlock 要求至少有 5 个 Redis 实例(奇数个实例)来保证锁的一致性和可用性。
这些 Redis 实例最好分布在不同的机器或数据中心中,以避免单点故障。

2.客户端获取锁:
客户端向多个 Redis 实例请求获取锁。它依次向每个 Redis 实例发送加锁请求,直到获取到一定数量的锁(比如多数节点上获取锁)。
获取锁的过程中,会设置一个合理的过期时间(TTL),确保锁不会被永久占用。
锁的唯一性是通过在每个 Redis 实例上设置一个唯一的标识符(通常是 UUID)来实现的。

3.确保锁的有效性:
客户端在所有 Redis 实例中获取锁后,会检查是否有至少大多数实例上成功加锁。如果是,则认为获取锁成功。
如果无法在大多数 Redis 实例上获得锁,则认为加锁失败,并释放已经获得的锁。

4.释放锁:
客户端释放锁时,向每个 Redis 实例发送解锁请求,确保锁能够被正确释放。

Redlock 的优点

容错性:Redlock 的设计允许部分 Redis 实例不可用时仍然能够工作,保证了锁的高可用性。
保证一致性:通过设置多个 Redis 实例,Redlock 能够减少单点故障带来的影响,保证分布式锁的一致性。

Redlock 的缺点和问题

尽管 Redlock 相比传统单节点 Redis 分布式锁具有更高的容错性和一致性,但它也有一些缺点:

时钟偏差问题:Redlock 的一个关键问题是时钟同步。Redis 实例的时钟如果不同步,可能导致锁的过期时间不一致,进而导致锁争用问题。
延迟问题:Redlock 要求访问多个 Redis 实例,这可能会引入额外的网络延迟,尤其在跨数据中心部署时,延迟可能影响锁的效率。
实现复杂性:相比单个 Redis 实例的分布式锁,Redlock 的实现和维护更加复杂,需要处理多个 Redis 实例之间的协同和故障恢复。

总结

因此一般项目中不建议使用RedLock,因占用太多服务器了!一般还是使用Redisson,因此主从不一致情况很少,而且切换都是很快的,在此期间如果高并发确实用到这个锁了也可以使用兜底方案,
例如实现 Redis 主从切换监控和通知机制,可以利用 Redis SentinelRedis Cluster 提供的事件通知机制。这些机制能够检测主节点宕机、切换以及其他状态变化,并通过发布/订阅机制(Pub/Sub)将事件通知给客户端应用。

实现步骤

  1. 依赖添加
  2. 连接到 Redis Sentinel
  3. 订阅 Sentinel 事件
  4. 处理主节点切换事件

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

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

相关文章

将Deepseek接入本地Vscode

第一步:获取Deepseek APIKEY 1.1 登录Deepseek官网 https://www.deepseek.com/ 1.2 选择API开放平台 1.3 注册账号并登录 1.4 登录成功后的就界面 1.5 点击左侧菜单栏“API keys”,并创建API key 名称自定义输入 生成API key 复制保存,丢失…

docker使用笔记

文章目录 1.Docker 与容器2.核心概念与安装配置2.1 核心概念2.2 docker 安装ubuntu使用官方的脚本自动安装准备条件准备安装安装Docker安装Docker 命令补全工具允许非Root用户执行docker 命令最后一步 更新.bashrc文件 [修改docker 默认的存储路径](https://www.cnblogs.com/du…

vim如何设置制表符表示的空格数量

:set tabstop4 设置制表符表示的空格数量 制表符就是tab键,一般默认是四个空格的数量 示例: (vim如何使设置制表符表示的空格数量永久生效:vim如何使相关设置永久生效-CSDN博客)

PPT添加与管理批注的操作指南

​​​ 批注是PPT中一个非常实用的功能,它不仅能帮助我们在演讲和设计过程中记录想法,还能与他人协作时提供有价值的反馈。无论是团队讨论、审稿,还是个人思考,批注的运用都能让我们的PPT更加完善和高效。我会详细介绍如何在PPT中…

CASAIM与友达光电达成深度合作,CASAIM IS自动化蓝光测量技术为创新显示技术发展注入新的活力

近期,CASAIM与友达光电股份有限公司在液晶显示面板智能自动三维检测技术上达成深度合作,联合打造CASAIM IS全自动化智能检测系统,助力光电产品显示面板制造全自动化3d测量,实现高精度、高效率测量和检测,进一步提升产品质量和生产…

【已解决】OSS配置问题

OSS SDK快速入门_对象存储(OSS)-阿里云帮助中心 阿里官方的SDK使用方法还得配置环境变量access Key、access Secret ,我没有配置,仅把access Key和access Secret写到了yml文件读取,结果上传图片时还是出现下面的问题。 [ ERROR ] [ com.s…

STM32 硬件I2C读写

单片机学习! 目录 前言 一、步骤 二、配置I2C外设 2.1 开启I2C外设和GPIO口时钟 2.2 GPIO口初始化为复用开漏模式 2.3 结构体配置I2C 2.4 使能I2C 2.5 配置I2C外设总代码 三、指定地址写时序 3.1 生产起始条件S 3.2 监测EV5事件 3.3 发送从机地址 3.4 …

C语言程序设计十大排序—冒泡排序

文章目录 1.概念✅2.冒泡排序🎈3.代码实现✅3.1 直接写✨3.2 函数✨ 4.总结✅ 1.概念✅ 排序是数据处理的基本操作之一,每次算法竞赛都很多题目用到排序。排序算法是计算机科学中基础且常用的算法,排序后的数据更易于处理和查找。在计算机发展…

Python网络自动化运维---用户交互模块

文章目录 目录 文章目录 前言 实验环境准备 一.input函数 代码分段解析 二.getpass模块 前言 在前面的SSH模块章节中,我们都是将提供SSH服务的设备的账户/密码直接写入到python代码中,这样很容易导致账户/密码泄露,而使用Python中的用户交…

【后端开发】字节跳动青训营之性能分析工具pprof

性能分析工具pprof 一、测试程序介绍二、pprof工具安装与使用2.1 pprof工具安装2.2 pprof工具使用 资料链接: 项目代码链接实验指南pprof使用指南 一、测试程序介绍 package mainimport ("log""net/http"_ "net/http/pprof" // 自…

【Ubuntu】安装SSH启用远程连接

【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端: sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端: sudo systemctl start ssh贰、配置SSH(可跳过) 配置文件 …

【模拟集成电路】锁相环(phase-locked loops,PLL)设计_环形振荡器相关(简)

0. 前言 未来将会不定时更新PLL相关的文章,主要目的是作为个人的学习笔记,关于锁相环的基础,可以参考《模拟CMOS集成电路设计_Behzad Razavi》后面几章的内容,下面的文章主要参考书籍是的英文书籍《DESIGN OF CMOS PHASE‑LOCKED …

【python】四帧差法实现运动目标检测

四帧差法是一种运动目标检测技术,它通过比较连续四帧图像之间的差异来检测运动物体。这种方法可以在一定的程度上提高检测的准确性。 目录 1 方案 2 实践 ① 代码 ② 效果图 1 方案 具体的步骤如下: ① 读取视频流:使用cv2.VideoCapture…

Spring--SpringMVC使用(接收和响应数据、RESTFul风格设计、其他扩展)

SpringMVC使用 二.SpringMVC接收数据2.1访问路径设置2.2接收参数1.param和json2.param接收数据3 路径 参数接收4.json参数接收 2.3接收cookie数据2.4接收请求头数据2.5原生api获取2.6共享域对象 三.SringMVC响应数据3.1返回json数据ResponseBodyRestController 3.2返回静态资源…

又是一年啊

又是一年 回顾2024一、2024的愿望二、愿望实现了吗?三、总结 展望2025几个愿望~~(终于快写完了)~~ 华丽结尾 回顾2024 一、2024的愿望 1.CSP-J上岸; 2.小升初上岸; 3.数学进入联赛班; 4.初一期末年级前五…

直线拟合例子 ,岭回归拟合直线

目录 直线拟合,算出离群点 岭回归拟合直线: 直线拟合,算出离群点 import cv2 import numpy as np# 输入的点 points np.array([[51, 149],[122, 374],[225, 376],[340, 382],[463, 391],[535, 298],[596, 400],[689, 406],[821, 407] ], dtypenp.float32)# 使用…

如何解压rar格式文件?8种方法(Win/Mac/手机/网页端)

RAR 文件是一种常见的压缩文件格式,由尤金・罗谢尔(Eugene Roshal)开发,因其扩展名 “rar” 而得名。它通过特定算法将一个或多个文件、文件夹进行压缩,大幅减小存储空间,方便数据传输与备份。然而&#xf…

【软件测试项目实战 】淘宝网:商品购买功能测试

一、用例设计方法分析 在对淘宝网商品下单功能进行测试时,不同的测试角度和场景适合运用不同的用例设计方法,以下是针对该功能各方面测试所适用方法及其原因的分析: 商品数量相关测试:对于商品数量的测试,主要采用等…

失业ing

零零碎碎记一下unity相关的东西备忘 渲染: https://github.com/festivities/PrimoToon 仿原神的卡通渲染, 参照这种文档: Unity Built-in Shader转URP Shader 接口查询对照表之类的 自己强行改api到urp可用,改了三四天&…

Centos类型服务器等保测评整/etc/pam.d/system-auth

修改服务器配置文件/etc/pam.d/system-auth,但是,把一下配置放在password的配置第一行才会生效 执行命令:配置口令要求:大小写字母、数字、特殊字符组合、至少8位,包括强制设置root口令! sed -i 14a pas…