首页 > 数据库 >Redis实现分布式锁有哪些方案?

Redis实现分布式锁有哪些方案?

时间:2024-06-11 17:33:17浏览次数:14  
标签:方案 哪些 过期 Redis key 分布式 客户端

Redis实现分布式锁有哪些方案?

在这里分享六种Redis分布式锁的正确使用方式,由易到难。

本文已收录到Java面试网站

方案一:SETNX+EXPIRE

方案二:SETNX+value值(系统时间+过期时间)

方案三:使用Lua脚本(包含SETNX+EXPIRE两条指令)

方案四::ET的扩展命令(SETEXPXNX)

方案五:开源框架~Redisson

方案六:多机实现的分布式锁Redlock

首先什么是分布式锁?

分布式锁是一种机制,用于确保在分布式系统中,多个节点在同一时刻只能有一个节点对共享资源进行操作。它是解决分布式环境下并发控制和数据一致性问题的关键技术之一。

分布式锁的特征:

1、「互斥性」:任意时刻,只有一个客户端能持有锁。

2、「锁超时释放」:持有锁超时,可以释放,防止不必要的资源浪费,也可以防止死锁。

3、「可重入性」“一个线程如果获取了锁之后,可以再次对其请求加锁。

4、「安全性」:锁只能被持有的客户端删除,不能被其他客户端删除

5、「高性能和高可用」:加锁和解锁需要开销尽可能低,同时也要保证高可用,避免分布式锁失效。

Redis分布式锁方案一:SETNX+EXPIRE

提到Redis的分布式锁,很多朋友可能就会想到setnx+expire命令。即先用setnx来抢锁,如果抢到之后,再用expire给锁设置一个过期时间,防止锁忘记了释放。SETNX是SETIF NOT EXISTS的简写。日常命令格式是SETNXkey value,如果 key不存在,则SETNX成功返回1,如果这个key已经存在了,则返回0。假设某电商网站的某商品做秒杀活动,key可以设置为key_resource_id,value设置任意值,伪代码如下:

img

缺陷:加锁与设置过期时间是非原子操作,如果加锁后未来得及设置过期时间系统异常等,会导致其他线程永远获取不到锁。

Redis分布式锁方案二:SETNX+value值(系统时间+过期时间)

为了解决方案一,「发生异常锁得不到释放的场景」,有小伙伴认为,可以把过期时间放到setnx的value值里面。如果加锁失败,再拿出value值校验一下即可。

这个方案的优点是,避免了expire 单独设置过期时间的操作,把「过期时间放到setnx的value值」里面来。解决了方案一发生异常,锁得不到释放的问题。

但是这个方案有别的缺点:过期时间是客户端自己生成的(System.currentTimeMillis()是当前系统的时间),必须要求分布式环境下,每个客户端的时间必须同步。如果锁过期的时候,并发多个客户端同时请求过来,都执行jedis.get()和set(),最终只能有一个客户端加锁成功,但是该客户端锁的过期时间,可能被别的客户端覆盖。该锁没有保存持有者的唯一标识,可能坡别的客户端释放/解锁

分布式锁方案三:使用Lua脚本(包含SETNX+EXPIRE两条指令)

实际上,我们还可以使用Lua脚本来保证原子性(包含setnx和expire两条指令),lua脚本如下:

img

加锁代码如下:

img

Redis分布式锁方案四:SET的扩展命令(SET EX PX NX)

除了使用,使用Lua脚本,保证SETNX+EXPIRE两条指令的原子性,我们还可以巧用Redis的SET指令扩展参数。(SET key value[EX seconds]PX milliseconds][NX|XX]`),它也是原子性的

SET key value[EX seconds][PX milliseconds][NX|XX]

  1. NX:表示key不存在的时候,才能set成功,也即保证只有第一个客户端请求才能获得锁,而其他客户端请求只能等其释放锁, 才能获取。
  2. EXseconds:设定key的过期时间,时间单位是秒。
  3. PX milliseconds:设定key的过期时间,单位为毫秒。
  4. XX:仅当key存在时设置值。

伪代码如下:

img

Redis分布式锁方案五:Redisson框架

方案四还是可能存在「锁过期释放,业务没执行完」的问题。设想一下,是否可以给获得锁的线程,开启一个定时守护线程,每隔一段时间检查锁是否还存在,存在则对锁的过期时间延长,防止锁过期提前释放。当前开源框架Redisson解决了这个问题。一起来看下Redisson底层原理图:

img

只要线程一加锁成功,就会启动一个watchdog看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了「锁过期释放,业务没执行完」问题。

分布式锁方案六:多机实现的分布式锁Redlock+Redisson

前面五种方案都是基于单机版的讨论,那么集群部署该怎么处理?

答案是多机实现的分布式锁Redlock+Redisson

最后分享一份我精心整理的大厂面试手册,包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等高频面试题,非常实用,有小伙伴靠着这份手册拿过字节offer~

需要的小伙伴可以自行下载

链接:http://mp.weixin.qq.com/s?__biz=Mzg2OTY1NzY0MQ==&mid=2247485445&idx=1&sn=1c6e224b9bb3da457f5ee03894493dbc&chksm=ce98f543f9ef7c55325e3bf336607a370935a6c78dbb68cf86e59f5d68f4c51d175365a189f8#rd

标签:方案,哪些,过期,Redis,key,分布式,客户端
From: https://www.cnblogs.com/tyson03/p/18242443

相关文章

  • Redis之主从同步
    概念主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。Master以写为主,Slave以读为主。默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个......
  • 内网穿透的方式有哪些——快解析的优势
    外网穿透内网技术,即内网映射,是把目标本地内网地址和端口发布到互联网,是一种由内网开放到外网的权限操作。那么,内网穿透的方法有哪些呢?做映射外网的方法。需要结合自己本地网络环境和应用场景来实施。这里分享三种方法,只要是能上网的网络环境,都可以通过这三种方式实现内网穿透。......
  • Redis:原理、概念、用法与实例解析
    Redis:原理、概念、用法与实例解析在当今风起云涌的技术领域中,Redis犹如一颗璀璨的明星,闪耀着独特的光芒。它作为一种备受瞩目的数据存储和缓存解决方案,以其卓越的性能、丰富多样的功能以及简单易用的特性,成为了众多开发者的心头好。在这篇博客中,我们将全方位、深层次地探......
  • Redis之发布订阅
    发布订阅Redis发布订阅(pub/sub)是一种消息通信模式,发送者(pub)发送消息,订阅者(sub)接收消息。Redis客户端可以订阅任意数量的频道。消息发送者&消息接收者&频道可以想象这么一个场景。我们抖音、微博关注了哪个博主,当他发布一条文章时,系统就会给我们推送他发布的消息内......
  • 数字人贴牌哪家好?需要关注的核心优势有哪些?
    随着人工智能时代的发展,数字人蕴含着的广泛的应用场景和庞大的市场需求也逐渐展现在了人们的眼前。在此背景下,数字人成为了一众创业赛道中的大热门,数字人贴牌模式也因此走红。所谓的数字人贴牌,又称为数字人源码部署和数字人OEM定制等,简单来说,就是一种由数字人源码公司向B端客......
  • 百度面试:如何用Redis实现限流?
    高并发系统有三大特征:限流、缓存和熔断,所以限流已经成为当下系统开发中必备的功能了。那么,什么是限流?如何实现限流?使用Redis能不能实现限流?接下来我们一起来看。1.什么是限流?限流是指在各种应用场景中,通过技术和策略手段对数据流量、请求频率或资源消耗进行有计划的限制,以避......
  • redis自学(46)键值设计
    Redis键值设计优雅的key结构Redis的Key虽然可以自定义,到但是最好遵循下面的几个最佳实践约定:l 遵循基本格式:[业务名称]:[数据名]:[id]l 长度不超过44字节(长度越小,占用的内存越少)l 不包含特殊字符  优点:①可读性强②避免key冲突③方便管理④更节省内存:ke......
  • Redis面试题、知识点总结,一篇文章让Redis成为面试加分项
    Redis面试题、知识点总结,一篇文章让Redis成为面试加分项前言参与了几次中大厂的面试,你会发现一面时对于八股文的考察也具有侧重点(MySQL=Redis>网络>系统>设计模式>java集合>JVM>spring)本文的目标就是通过这一篇文章让你能在面试时将Redis相关的问题回答漂亮。......
  • Redis之持久化
    Redis持久化Redis是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以Redis提供了持久化功能!RDB(RedisDataBase)在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是Snapshot快照,它恢复时是将快照文件直接......
  • Redis在微服务架构中的角色:服务间通信与数据共享
    I.引言A.介绍微服务架构的概念和特点 微服务架构是一种设计模式,它将一个大型的单体应用分解成一组小的服务,每个服务都运行在其自身的进程中,独立地进行部署和扩展。这些服务之间通过轻量级的通信机制(如HTTPRESTfulAPI)进行交互,每个服务都围绕一个特定的业务功能进行组......