iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Redis分布式锁详细介绍
  • 162
分享到

Redis分布式锁详细介绍

2024-04-02 19:04:59 162人浏览 八月长安
摘要

目录分布式锁Redis实现分布式锁的原理死锁问题超时问题锁误放问题可重入性Redlock分布式锁 在单进程应用中,当一段代码同一时间内只能由一个线程执行时, 多线程下可能会出错,例如

分布式锁

在单进程应用中,当一段代码同一时间内只能由一个线程执行时,

多线程下可能会出错,例如两个线程同时对一个数字做累加,两个线程同时拿到了该数字,例如40,一个线程加了10,一个线程加了20,正确结果应该是70,

但由于两个线程在自己的内存中一个算出的是50,一个算出的是60,此时二者都将自己的结果往该数字原本的地方写(保存),

这时候,肯定会有一个线程的值会被覆盖,因为读取->计算->保存 并不是原子操作(原子操作是指不会被线程调度机制打断的操作,这种操作一旦开始,就会一直运行结束,中间不会有任何线程切换),

也就是说最终的结果要么是50,要么是60,而不可能是70(出现并发或并行的情况下,这种情况大概率会发生),

image.png

单进程应用发生这种情况时,可以由程序提供的锁语义直接上锁(例如java中的sychornized)保证该段代码只会被一个线程执行,按照顺序来进行,结果将是正确的。

在分布式应用中,由于一台机器上可能跑着相同的应用进程,或者在不同的机器上跑着,原本程序自带的语义锁已经无法起到作用,

因为相同的代码可能是在不同的机器、进程中执行,所以此时需要一个能够让不同机器、进程中,相同的应用代码执行到同一段代码时,也能够按照顺序执行(或者同一时间内只有一个线程能够执行),

这就需要用到中间件来协调,可以实现分布式锁的中间件有很多,redis就是其中一个。

redis实现分布式锁的原理

redis中分布式锁的原理其实就是在redis当中设置一个值(当然要保证分布式应用连的都是同一个redis,以这个redis作为中间点,否则当然是没用的),这个值只能由一个线程来存放,当其他线程(或者不同机器上的进程)也来存放时,发现这个值已经存在了,就说明此时已经有人在用这把锁了,这时候要么进行重试等待,要么进行放弃。

设置一般使用 SETNX (set if not exists) 指令,如果该值没有,则进行设置,有了则不设置,这就是拿锁的关键了,当拿到锁的人执行处理完毕后,再调用 DEL 执行进行锁的释放。

死锁问题

使用 SETNX 和 DEL 实现了分布式锁,但是有一种情况,如果一个线程进行了 SETNX 拿到锁成功后,突然这个线程因为某种原因崩溃了,导致没有进行 DEL 释放锁,

那么此时,将会导致其他所有的应用都再也没办法拿到这把锁,也就是 死锁 ,这个问题的解决方式是将锁设置一个有效期,到了有效期之后该锁将被自动释放,

使用 EXPIRE 可以给锁设置一个有效期,如下


SETNX LOCK-KEY-NAME true
EXPIRE LOCK-KEY-NAME 5

但是还有一个问题,因为 SETNX 和 EXPIRE 是分为两个指令执行的,这中间依然有可能出现 SETNX 执行完毕后,由于认为或者机器、程序发生的故障 导致 EXPIRE 没有执行成功,此时还是有可能会发生死锁,

image.png

事务能不能解决这个问题?

NO,因为 EXPIRE 是依赖 SETNX 的执行结果执行的,只有 SETNX 成功后,才能进行 EXPIRE,否则是不可以执行的,事务里并没有 if else 的分支逻辑,要么全部执行,要么一个都不执行。

在 redis2.8 的版本中,引入了set指令的拓展参数,可以让 SETNX 和 EXPIRE 同时执行(原子),解决了超时问题,


SET LOCK-KEY-NAME true ex 5 nx

超时问题

上面虽然说到利用给锁设置过期时间解决可能会发生的死锁问题,但是万一我的程序代码执行时间超过了设置的过期时间,这时候锁自动释放了,但是我的代码还没执行完毕,其他人又进行执行了,导致结果出错怎么办?

在一般的开发场景中,我们会尽量将锁的时间设置的长一些,例如60s,一般应用程序在60s内都能执行完毕,但是怕就怕的是较真,如果60s内也执行不完怎么办?

此时可以使用一种续期的方案,就是当程序在执行过程中,不断的判断锁是否快要过期,代码是否执行完毕,如果快过期了没有执行完毕,就将这把锁进行续期,保证锁不会被自动释放,直到我们的代码执行完毕为止,这种方案在java中由一个叫做 redisson 的框架实现了,可以直接引入使用。

锁误放问题

在锁的使用过程中,很有可能出现其他应用没有拿到锁,但是也执行了 DEL 指令,将我们正在执行中的程序的锁释放了,导致其他地方拿到锁,进入代码段开始执行,

这里的解决方式是,在SETNX的时候,可以将value设置成一个随机生成并全局唯一的一串数字或字符,该线程一直持有字符,在释放锁的时候,将字符与锁中的字符进行比对,如果匹配,则可以进行释放锁,如果不匹配,说明是其他人误放,此时拒绝释放,

但是判断字符是否相同与释放锁并不是原子操作,redis也并不提供这么一种命令,所以我们考虑使用lua脚本执行这几步操作(redisson也实现了),

最重要的一点是,程序中使用释放锁的入口一定要统一,万一有的应用程序不使用上面所述的方法释放,直接使用 DEL ,那么上面说的方案就没用了(笔者为了测试,直接用DEL释放过)。

可重入性

可重入性是指线程在持有锁的情况下,再次请求加锁,如果一个锁支持同一个线程的多次加锁,那么这个锁就是可重入的,Java中的 ReentrantLock 就是可重入锁,大致的原理就是每次获取到锁后对一个数字进行 +1,每次释放的时候进行 -1,当数字为0时,分布式锁被释放,

redis锁如果要支持可重入性,也需要用上面的方式进行支持,不过该逻辑加重了复杂性,一般推荐将需要锁的代码段进行逻辑调整,避免重复获取分布式锁来处理。(当然redisson也支持了可重入锁)

Redlock

上面的方式看起来没有太多的问题了,但是由于redis本身可能也会发生问题,例如在Sentinel集群中,主节点挂掉,从节点变成主节点,但是客户端这时候是不知道的,

如果客户端在刚刚挂掉的主节点上SETNX成功了,但是这把锁还没有同步到从节点中,从节点这时候变成了主节点,这时候新主节点中没有这把锁的信息,

此时另一个客户端来请求这把锁,直接 SETNX 成功,又导致了两个客户端同时在执行相同的代码,又出现了不安全性,

image.png

为此业界提供了叫做 Redlock 的解决方案,原理大致是,提供多台redis实例,这些实例之间相互独立,没有主从关系(没有任何关系),同其他分布式算法一样,使用了大多数机制,

加锁时,它会向过半节点发出 set(key, value, nx = True, ex = xxx)指令,只要过半节点设置成功,这把锁就算拿到了,释放锁时向所有节点发出 DEL 指令,

Redlock算法(Redisson已支持)需要考虑出错重试,时钟漂移等等细节问题,同时Redlock需要向多个节点进行读写,性能将要比单例redis下降,

如果业务场景对错误的发生容忍度很低,又可以接受性能稍微有点下降,可以考虑采用Redlock算法。

到此这篇关于Redis分布式锁详细介绍的文章就介绍到这了,更多相关Redis分布式锁内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Redis分布式锁详细介绍

本文链接: https://www.lsjlt.com/news/159228.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Redis分布式锁详细介绍
    目录分布式锁redis实现分布式锁的原理死锁问题超时问题锁误放问题可重入性Redlock分布式锁 在单进程应用中,当一段代码同一时间内只能由一个线程执行时, 多线程下可能会出错,例如...
    99+
    2022-11-12
  • 巧用Redis实现分布式锁详细介绍
    目录前言手写Redis分布式锁Redissonlock()lock(long leaseTime, TimeUnit unit)tryLock(long waitTime, long...
    99+
    2022-11-12
  • Golang分布式锁详细介绍
    目录进程内加锁trylock基于redis的setnx基于zk基于etcdredlock如何选择在单机程序并发或并行修改全局变量时,需要对修改行为加锁以创造临界区。为什么需要加锁呢?...
    99+
    2022-11-11
  • Redis分布式锁介绍与使用
    目录分布式锁业务逻辑分析Redis命令代码实现分布式锁误删问题问题原因分析代码实现Lua脚本首先,使用idea模拟搭建一个tomcat服务器集群,并使用Nginx对集群中的服务器实现...
    99+
    2022-11-13
  • Redis超详细分析分布式锁
    目录分布式锁应用场景使用Redis 实现分布式锁单机版Redis实现分布式锁使用原生Jedis实现使用Springboot实现分布式锁 为了保证一个方法在高并发情况下的同一时间只能被同一个线程执行,在传统单体应用单机部署...
    99+
    2022-07-27
    Redis 分布式锁 Redis 分布式锁实现
  • Redis分布式锁的实现原理介绍
    这篇文章主要讲解了“Redis分布式锁的实现原理介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis分布式锁的实现原理介绍”吧!一、写在前面现在面试,一般都会聊聊分布式系统这块的东西...
    99+
    2023-06-02
  • Redis实现分布式锁方法详细
    目录1. 单机数据一致性2. 分布式数据一致性3. Redis实现分布式锁3.1 方式一3.2 方式二(改进方式一)3.3 方式三(改进方式二)3.4 方式四(改进方式三)3.5 方...
    99+
    2022-11-12
  • etcd与分布式锁的介绍
    本篇内容主要讲解“etcd与分布式锁的介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“etcd与分布式锁的介绍”吧!1. 实现分布式锁的组件们在分布式系统中,...
    99+
    2022-10-19
  • 【分布式任务调度】二、Elastic-Job详细介绍
    Elastic-Job 一、What is elastic-job?Elastic-Job-LiteElastic-Job-CloudElastic-job开发环境要求Elastic-Job配置开发1、 使用Java配置方式启动2、...
    99+
    2023-08-30
    java 开发语言
  • html5响应式布局的详细介绍
    本篇内容主要讲解“html5响应式布局的详细介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“html5响应式布局的详细介绍”吧!一、什么是响应式布局 ...
    99+
    2022-10-19
  • Redis实现分布式锁详解
    目录一、前言为什么需要分布式锁?二、基于Redis实现分布式锁为什么redis可以实现分布式锁?如何实现?锁的获取锁的释放三、如何避免死锁?锁的过期时间如何设置?避免死锁锁过期处理释放其他服务的锁如何处理呢?那么redi...
    99+
    2023-04-09
    Redis实现分布式锁 Redis分布式锁
  • 详细介绍redis info命令
    redis info命令以一种易于解释(parse)且易于阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。通过给定可选的参数 section ,可以让命令只返回某一部分的信息:1、server...
    99+
    2022-10-18
  • Java操作Redis详细介绍
    1. 简介Redis 是一个开源(BSD许可)的,内存中的key-value存储系统,它可以用作数据库、缓存和消息中间件。2. 对key的操作首先要建立连接Jedis jedis = new Jedis("127.0.0.1", 6379)...
    99+
    2023-05-30
    java redis使用
  • 详解redis分布式锁(优化redis分布式锁的过程及Redisson使用)
    目录1. redis在实际的应用中2.如何使用redis的功能进行实现分布式锁2.1 redis分布式锁思想2.1.1设计思想:2.1.2 根据上面的设计思想进行代码实现2.2 使用...
    99+
    2022-11-12
  • go语言分布式id生成器及分布式锁介绍
    目录分布式 id 生成器worker_id 如何分配开源示例:标准雪花算法分布式锁进程内加锁尝试加锁 tryLock基于 Redis 的 setnx 分布式锁基于 ZooKeeper...
    99+
    2023-05-14
    go 分布式id生成器 锁 go 分布式锁
  • Redis List列表的详细介绍
    Redis List列表的详细介绍 Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (42949...
    99+
    2022-06-04
    详细介绍 列表 Redis
  • Java中的各种锁详细介绍
    这篇文章主要讲解了“Java中的各种锁详细介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中的各种锁详细介绍”吧!锁有什么作用呢说了这么多还是不清楚锁到底有什么用处这一点就要深思我...
    99+
    2023-06-16
  • 详细介绍Java中的各种锁
    一、一张图了解21种锁 二、乐观锁 应用 CAS 思想 一种乐观思想,假定当前环境是读多写少,遇到并发写的概率比较低,读数据时认为别的线程不会正在进行修改 实现 写数据...
    99+
    2022-11-12
  • redis实现分布式锁实例详解
    目录1、业务场景引入2、基础环境准备2.1.准备库存数据库2.2.创建SpringBoot工程,pom.xml中导入依赖,请注意版本。2.3.application.properti...
    99+
    2022-11-13
  • 详解redis如何实现分布式锁
    小编这次要给大家分享的是详解redis如何实现分布式锁,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。前言系统的不断扩大,分布式锁是最基本的保障。与单机的多线程不一样的...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作