首页 > 数据库 >redis 分布式锁

redis 分布式锁

时间:2023-05-08 11:35:44浏览次数:45  
标签:释放 加锁 redis Redis master key 客户端 分布式

如何利用Redis实现锁机制
用一句话概括的说,其实Redis实现锁机制其实就是在Redis中设置一个key-value,当key存在时,即上锁,删除key即解锁。
当然要想实现一个很健壮的锁机制,这其中还有很多细节不容忽视,所以下面,我们一步一步的跟着思路去思考如何使用Redis实现一个分布式的锁:

加锁保证互斥性,同一时间只能有一个客户端加锁成功。

通过Redis的setnx命令实现,setnx即 set if not exists,当key不存在时才能设置成功

(推荐)通过set key value PX 3000 NX,PX指过期时间,NX即not exists,效果等同setnx,但是由于 setnx 不支持设置过期时间,所以需要拆分成两个两个命令setnx key value 和 expire key 3,要保证原子性还需要将两个命令合并为一个lua脚本。

SET key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL] [NX|XX] [GET]
summary: Set the string value of a key
since: 1.0.0
group: string
1
2
3
4

前面也提到,由于Redis是单线程的,所以当大量请求过来时,这些请求是串行化执行的,所以一定只有一个请求才能设置成功,从而保证了加锁的互斥性。

防止死锁
当客户端加锁之后,在释放锁之前如果Redis发生了宕机,那么Redis中的锁就无法自动释放,最终产生死锁,所以为了避免死锁,我们还需要给这个锁的key设置一个合理的过期时间,当锁占用的时间超过指定的过期时间,则自动删除该锁对应的key释放锁,让其他客户端能够有机会去争抢这个锁。

锁过期提前释放
上一步由于为了避免死锁,所以在加锁时,指定了锁的有效期,但是这个有效期也是估算出来的,如果实际业务处理时间超过了锁的有效期,锁会被提前释放,就会导致其他客户端获得了锁,从而导致锁机制的失效。
所以为了解决该问题,就需要一个机制去对锁进行续期,防止在加锁的业务还未处理完之前,被提前释放,我们可以利用一个子线程,在锁有效期到期之前,定期的去的给锁进行续期,即:增加key的过期时间。

释放锁
释放锁,只需要将对应的锁的key从redis中删除即可,但是这里需要注意的是,在释放锁之前,必须判断只有是当前线程占用的锁才可以进行释放,所以锁的key对应的value我们就可以存放当前的客户端的身份标识,在释放锁之前,比对一下当前释放锁的客户端是否是当前加锁的客户端,如果匹配成功则可以正常删除对应的key释放锁,否则就不释放锁

Redisson 单机模式下的缺点
事实上这类锁最大的缺点就是它加锁时只作用在一个Redis节点上,如果Redis挂了,那么就会产生单点故障的问题,
即使Redis通过sentinel哨兵机制保证高可用,当master节点发生故障后,可以故障转移,slaver升级为master,
但由于主从之间的数据同步是异步的, 如果在发生主从切换的时候,key 还没来得及同步到slaver上,那么就会出现锁丢失的情况:

在Redis的master节点上拿到了锁;
但是这个加锁的key还没有同步到slave节点;
 master故障,发生故障转移,slave节点升级为master节点;
 导致锁丢失

所以Redis对于这种场景提供RedLock红锁,即对主节点master的Redis进行集群,多个master实例间互相独立,需要对N个实例进行上锁,这里假设有5个Redis集群,当获取锁的时候,当且仅当大多数的节点(即 N/2 + 1)都设置锁成功,整个获取锁的过程才算成功,如果没有满足该条件,就需要在向所有的Redis实例发送释放锁命令即可,不用关心之前有没有从Redis实例成功获取到锁.

标签:释放,加锁,redis,Redis,master,key,客户端,分布式
From: https://www.cnblogs.com/xzjf/p/17381215.html

相关文章

  • Netty_Redis_Zookeeper高并发实战-读书笔记
    第1章    高并发时代的必备技能1.nettyNetty是JBOSS提供的一个Java开源框架,基于NIO的客户端/服务器编程框架,能够快速开发高并发、高可用、高可靠的网络服务器程序,也能开发高可用、高可靠的客户端程序。NIO是指:非阻塞输入输出(Non-BlockingIO)。优点:API使用简单,开发门槛......
  • 了解Redis过期策略及实现原理
    大约阅读4分钟如果你使用过redis,那你一定知道过期策略这个命令吧,如果让你设计一个过期键接口,你有什么想法?我们在使用redis时,一般会设置一个过期时间,当然也有不设置过期时间的,也就是永久不过期。当我们设置了过期时间,redis是如何判断是否过期,以及根据什么策略来进行删除的。redi......
  • [230]连接Redis后执行命令错误 MISCONF Redis is configured to save RDB snapshots
    今天在redis中执行setrangename1chun命令时报了如下错误提示:(error)MISCONFRedisisconfiguredtosaveRDBsnapshots,butiscurrentlynotabletopersistondisk.Commandsthatmaymodifythedatasetaredisabled.PleasecheckRedislogsfordetailsabout......
  • redis到底是不是单线程
     常说的Redis是单线程,主要是指Redis对外提供键值存储服务的主要流程,即从「网络模块+命令处理」是由⼀个线程来完成的。除此外Redis的其他功能,比如持久化、异步删除、集群数据同步等,是由额外的线程执⾏的。并且,从redis6.0开始,网络模块开始支持多线程,命令处理仍是单线程......
  • 【Redis】常用命令介绍
    一、Redis常用基本命令官方文档:https://redis.io/commands/参考文档:http://redisdoc.com/#可以使用help命令查看各redis命令用法[root@Client-Ubuntu-1804-250:~]#redis-cli-aredis--no-auth-warninghelpredis-cli5.0.14TogethelpaboutRediscommandstype:......
  • 知乎问题:如何说服技术老大用 Redis ?
    这个问题很微妙,可能这位同学内心深处,觉得Redis是所有应用缓存的标配。缓存的世界很广阔,对于应用系统来讲,我们经常将缓存划分为本地缓存和分布式缓存。本地缓存:应用中的缓存组件,缓存组件和应用在同一进程中,缓存的读写非常快,没有网络开销。但各应用或集群的各节点都需要维护自......
  • 分布式ID生成策略
    在分布式系统中,肯定避免不了获取全局唯一ID,用于业务主键,本节主要学习分布式ID常用的生成方法。一、UUIDUUID(UniversallyUniqueIdentifier),通用唯一识别码。UUID是基于当前时间、计数器(counter)和硬件标识(通常为无线网卡的MAC地址)等数据计算生成的。UUID是JDK提......
  • 分布式架构整体框架
    文章目录一、分布式整体框架图1.架构eg12.架构eg2二、什么是分布式系统?1.什么是分布式系统?2.分布式系统的挑战3.分布式系统特性与衡量标准4.组件、理论、协议5.概念与实现6.总结三、分布式学习最佳实践:从分布式系统的特征开始(附思维导图)1.分布式特征的思维导图2.分布式系统的一般特......
  • 第10章:10W QPS真刀实操__以及基于ZK+Netty手写分布式测试工具 177手机路人甲账号 主目
    10WQPS真刀实操__以及基于ZK+Netty手写分布式测试工具参考链接系统架构知识图谱(一张价值10w的系统架构知识图谱)https://www.processon.com/view/link/60fb9421637689719d246739秒杀系统的架构https://www.processon.com/view/link/61148c2b1e08536191d8f92f10WQPS真刀实......
  • redis分布式锁
    分布式锁是可以跨越多个实例,多个进程的锁。一个tomcat实例是一个JVM进程,单体锁(synchronized、ReentrantLock)是JVM层面的锁,只能控制单个实例上的并发访问安全,多实例下依然存在数据一致性问题。分布式锁:所有实例的所有线程都去获取同一把锁,但只有一个线程可以成功的获得锁,其他没......