Redis 如何实现分布式锁

课程地址

单机 Redis

naive 版

加锁:

SETNX ${lockName} ${value}	# set if not exist

如果不存在则插入成功,返回 1,加锁成功;否则返回 0,加锁失败

解锁:

DEL ${lockName}

问题1

2 个线程 A、B,线程 A 拿到了锁后,宕机了怎么办?谁来释放锁?

解决:使用自动过期机制:

加锁:

SET ${lockName} ${value} EX 10 NX	# atomic opreation

解锁:

DEL ${lockName}

问题2

在这里插入图片描述

t0 时刻实例1获取到锁,t3 时刻被自动释放(国企),同时实例2获取到锁,t4 时刻实例1再次释放(实例2的锁),实例3又获取到了锁,造成了数据混乱

解决:设置 value 为当前实例线程 id,在解锁时做判断

加锁:

SET ${localName} ${threadId} EX 10 NX

解锁(使用 lua 脚本实现原子性):

current_value = get ${lockName}
if ${threadId} == current_value thenDEL ${lockName}

问题3

在这里插入图片描述

锁被自动释放的问题仍然存在

启动一个异步线程(WatchDog),获取到锁成功后启动异步线程,每隔 x 秒对当前锁续期 y 秒,直到锁被释放停止

至此,单机版的 Redis 分布式锁就得到了成功实现

集群 Redis

主节点加锁成功后崩溃,从节点上位后没有锁的信息

在这里插入图片描述

加锁:

  • 向所有节点发送加锁请求
  • 获取到锁的数量达到节点个数半数以上认为加锁成功

解锁:

删除所有实例上的锁

在这里插入图片描述

问题4

网络延迟超过了锁的过期时间

在这里插入图片描述
加锁:

一、获取当前时间
二、按顺序依次向N个Redis实例执行加锁操作

这里的加锁操作和在单实例上执行的加锁操作一样,使用SET命令,带上NX、EX/PX选项,以及带上客户端的唯一标识。当然,如果某个Redis实例发生故障了,为了保证在这种情况下,Redlock算法能够继续运行,我们需要给加锁操作设置一个超时时间。如果客户端在和一个Redis实例请求加锁时,一直到超时都没有成功,那么此时,客户端会和下一个Redis实例继续请求加锁。加锁操作的超时时间需要远远地小于锁的有效时间,一般也就是设置为几十毫秒

三、一旦客户端完成了和所有Redis实例的加锁操作,客户端就要计算整个加锁过程的总耗时

客户端只有在满足两个条件时,才能认为是加锁成功:

  • 客户端从超过半数(大于等于 N/2+1)的Redis实例上成功获取到了锁
  • 客户端获取锁的总耗时没有超过锁的有效时间

在满足了这两个条件后,我们需要重新计算这把锁的有效时间,计算的结果是锁的最初有效时间减去客户端为获取锁的总耗时。如果锁的有效时间已经来不及完成共享数据的操作了,我们可以释放锁,以免出现还没完成共享资源操作,锁就过期了的情况。

当然,如果客户端在和所有实例执行完加锁操作后,没能同时满足这两个条件,那么,客户端就要向所有Redis节点发起释放锁的操作

在这里插入图片描述

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

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

相关文章

前后端交互概念

前后端交互概念 1前后端分离开发概念2搭建后端环境2.1配置文件commomcommon-utilservice-utilmodelservice gitee使用 1前后端分离开发概念 前段:运用html、css、js和现成库,对数据作展示。 后端:运用Java和Java框架,提供数据或操…

立创·实战派ESP32-C3开发板 with lv_micropython

一、lv_micropython对驱动芯片的支持 ESP32-C3开发板的Display drivers:ST7789,Input drivers:FT6336,从LVGL的官方文档了解到lv_micropython包含了这两颗IC的驱动。 参考文档: lv_micropython already contains these drivers: 链接:Micro…

智慧化转型赋能园区创新:科技创新引领产业智慧化,打造高效发展新格局

在全球化和信息化浪潮的推动下,园区作为区域经济发展的重要引擎,正面临着前所未有的机遇与挑战。为应对这些挑战并把握机遇,园区需积极拥抱智慧化转型,通过科技创新引领产业智慧化,打造高效发展的新格局。本文将深入探…

贝叶斯分类 python

贝叶斯分类 python 贝叶斯分类器是一种基于贝叶斯定理的分类方法,常用于文本分类、垃圾邮件过滤等领域。 在Python中,我们可以使用scikit-learn库来实现贝叶斯分类器。 下面是一个使用Gaussian Naive Bayes(高斯朴素贝叶斯)分类器的简单示例&#xff1…

go | defer、panic、recover

刷一道题, 将当函数触发panic 之后,函数是怎么执行的 然后我去找相关博客,发现这篇讲的蛮好的 接下来我直接上demo ,然后通过demo 来逐个分析 package mainimport ("fmt" )func f() {defer func() {if r : recover();…

毕业设计——基于ESP32的智能家居系统(语音识别、APP控制)

ESP32嵌入式单片机实战项目 一、功能演示二、项目介绍1、功能演示2、外设介绍 三、资料获取 一、功能演示 多种控制方式 ① 语音控制 ②APP控制 ③本地按键控制 ESP32嵌入式单片机实战项目演示 二、项目介绍 1、功能演示 这一个基于esp32c3的智能家居控制系统,能实…

websocket 请求头报错 Provisional headers are shown 的解决方法

今日简单总结 websocket 使用过程中遇到的问题&#xff0c;主要从以下三个方面来分享&#xff1a; 1、前端部分 websocket 代码 2、使用 koa.js 实现后端 websocket 服务搭建 3、和后端 java Netty 库对接时遇到连接失败问题 一、前端部分 websocket 代码 <template>…

Spark和Hadoop的安装

实验内容和要求 1&#xff0e;安装Hadoop和Spark 进入Linux系统&#xff0c;完成Hadoop伪分布式模式的安装。完成Hadoop的安装以后&#xff0c;再安装Spark&#xff08;Local模式&#xff09;。 2&#xff0e;HDFS常用操作 使用hadoop用户名登录进入Linux系统&#xff0c;启动…

Flink基础概念及算子

Flink基础概念-算子 一、Flink概述二、Flink集群角色和核心概念1.Flink运行时架构&#xff08;Standealone会话模式&#xff09;2.并行度&#xff08;Parallelism&#xff09;3.算子链&#xff08;Operator Chain&#xff09;4. 任务槽&#xff08;Task Slots&#xff09; 三、…

GO环境及入门案例

文章目录 简介一、win GO开发环境安装二、Linux go运行环境二、GO代码入门2.1 导包案例2.2 赋值2.3 变量、函数2.4 三方库使用 简介 go不是面向对象语言&#xff0c; 其指针、结构体等比较像C&#xff0c;知名的go 开源项目有docker k8s prometheus node-exporter等 一、win …

C语言语法进阶

条件运算符 条件运算符是 C 语言中唯一的一种三目运算符。三目运算符代表有三个操作数&#xff1b;双目 运算符代表有两个操作数&#xff0c;如逻辑与运算符就是双目运算符&#xff1b;单目运算符代表有一个操作数&#xff0c; 如逻辑非运算符就是单目运算符。运算符也称操作符…

arping命令详解

arping – send ARP REQUEST to a neighbour host. arping 是一个在网络中发送 ARP 请求以查找特定 IP 地址对应的 MAC 地址的命令行工具。它的功能类似于 ping 命令&#xff0c;基于ARP协议报文的交互机制&#xff0c;只能测试同一网段或子网的网络主机的连通性。 ARP 是 Add…

软件杯 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的行人重识别算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c…

如何使用JSONB类型在PostgreSQL中存储和查询复杂的数据结构?

文章目录 解决方案1. 创建包含JSONB列的表2. 插入JSONB数据3. 查询JSONB数据4. 创建索引以优化查询性能 示例代码结论 在PostgreSQL中&#xff0c;JSONB是一种二进制格式的JSON数据类型&#xff0c;它允许你在数据库中存储和查询复杂的JSON数据结构。与普通的JSON类型相比&…

《操作系统导论》第27章读书笔记:插叙:线程API

《操作系统导论》第27章读书笔记&#xff1a;插叙&#xff1a;线程API —— 2024-04-21 杭州 上午 本章讲得比较啰嗦&#xff0c;问题是本章的二级标题后面都会作为一个章节来讲&#xff0c;所以本章属于概况介绍类章节&#xff0c;另外这几个并发的章节使用的都是是POSIX线程…

【python】启动一个公司级项目的完整报错和解决方案

启动一个项目对于新手都是不容易的事情 操作 打开项目 使用pyCharm打开python项目以后&#xff0c;先找main方法&#xff0c;一般在根目录有一个.py的文件 点进去以后会让你配置Python解释器 每个项目都有自己的一个虚拟环境&#xff0c;配置自己的解释器&#xff0c;可能…

windows驱动开发-设备栈

设备栈是windows内核中非常重要的部分&#xff0c;这部分理解可以让我们在调试中节省大量的时间&#xff0c; 在windows NT体系中&#xff0c;内核所有的设备被按照连接次序加载到设备树上&#xff0c;这棵树的根节点是ROOT节点&#xff0c;每一个设备可以从当前路径一直遍历到…

QMT和Ptrade有什么区别?该如何选择?

QMT&#xff08;Quantitative Model Trading&#xff09;和Ptrade&#xff08;Professional Trading&#xff09;是两种不同的交易策略和方法&#xff0c;它们在金融市场中被广泛应用。了解它们的区别有助于投资者根据自己的需求和目标做出选择&#xff1a; QMT&#xff08;量…

将记录从excel当中导出为.sql文件,再新增到数据库

一、背景 临时遇到了一个需求&#xff0c;比如根据人员的名字查询对应记录&#xff0c;看起来还是很简单的&#xff0c;直接用select查询就可以&#xff0c;然而如果此时存在以下情况&#xff1a; 数据库根本就没有人员信息表&#xff1b;------这个倒是好操作&#xff1b;现…

AlDente Pro for mac最新激活版:电池长续航软件

AlDente Pro是一款专为Mac用户设计的电池管理工具&#xff0c;旨在提供电池安全和健康管理的一站式解决方案。它具备实时监控电池状态的功能&#xff0c;让用户随时了解电池的电量、充电次数、健康状态等信息。 AlDente Pro for mac最新激活版下载 同时&#xff0c;AlDente Pro…