百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Redis实现的分布式锁服务红锁(RedLock)

mhr18 2024-10-22 12:36 29 浏览 0 评论

我们前面文章《分布式锁服务的思考》中已经提出来为什么要加锁,以及对什么资源加锁,大家最好先过去简单看一下。今天我们继续学习一下如何结合Redis实现一个分布式锁服务。我们先实现一个简单的分布式锁服务,然后分析单节点锁存在的问题,再由问题引入Redis的分布式锁服务红锁的设计。

目录:

  1. redis简单介绍

  2. 简单的分布式锁服务

  3. 可靠的分布式锁服务

  4. 代码示例

1. Redis简单介绍

Redis本身是内存数据库,适合用来对热点数据、瞬时数据(expire)、近似统计数据做存储,不小心丢失了部分数据也不要紧。例如我们用来统计每个IP的访问频率,用来做限流或者防止爬虫,同时也记录IP和对应的登录用户ID,防止恶意接口检测。同时Redis具有一个特征:结合Lua脚本可以实现原子性操作,我们可以利用Redis的这个特点,来实现一个锁服务。

2.使用Redis实现一个不可靠的分布式锁服务

主要的指令:

SET resource random_value NX PX 3000

该指令对key = resource的资源加过期时间为3000ms的锁,如果该资源已经被加锁了,说明key存在,本次加锁失败。

需要注意的是:设置的value在本资源锁的请求中一定是不可重复的,因为在锁释放的过程中需要key和value都对应了才可以删除的,防止删除了其他客户端加的锁。例如:A获得了锁,并承诺3秒内释放锁。可结果A执行了大于3秒,此时A的锁是被Redis被动释放的,锁释放后B获得了该资源锁,A终于执行完毕,然后删除key执行锁释放,会把B的锁误删的。因此释放锁需要结合key和value才行。

释放锁的Lua脚本如下:

我们使用Java代码结合上面的Lua脚本实现一个简单的锁,如下:

头条代码没格式化,贴图吧

思考:

既然单节点存在单点故障,我们添加一个slave可以吗?不可以,因为redis的主备是异步复制。

  1. 客户端A在master上获得锁,之后master在没有同步到slave就崩溃了。

  2. slave提升为master,客户端B在新的master上获得了A已经获得的资源锁。

非分布式或集群的系统本身就没有可靠性可言,所以上面我们讨论的锁在非分布式系统中可以应用良好。下面带大家认识下Redis的分布式锁服务——红锁。

3.利用Redis实现可靠的分布式锁服务——红锁

Redis把分布式锁的算法称之为红锁,Redis + Lock = RedLock。红锁需要N个(>=3)Redis独立节点,这些节点相互之间不需要有信息交流,保持独立即可。红锁基本的思路是:客户端在每个Redis实例上获得锁(就是上面讲过的指令),只要大多数实例上成功获得锁就算加锁成功。红锁的算法已经有很多实现版本,JAVA对应的实现版本是Redisson,我们可以在业务中直接引入并使用。虽然不需要我们自己去实现算法,但是有必要了解一下红锁的算法,下面我们描述一下客户端获得锁的流程:

  1. 客户端首先记录当前时间,用于后面计算总耗时。

  2. 客户端使用相同的key和随机value,从所有的Redis节点上获得锁。客户端在每个实例上设置锁的过程中,需要设超时时间(5-50ms),不成功就换下一个实例继续设置锁,用来防止客户端阻塞在一个down掉都实例上。

  3. 客户端需要计算获得锁的总耗时。客户端从至少N/2 + 1个节点上成功获得锁,且总耗时小于锁过期时间才能成功获得锁。

  4. 客户端获得锁之后,该锁的有效期不再是最初的过期时间,因为客户端要从多个节点上获得锁,需要去掉这些过程耗时。

  5. 如果客户端最终获得锁失败,必须在所有节点上执行锁释放。

以上算法保证了:

  • 锁互斥性,同一时间只能有一个锁

  • 不会死锁,使用锁过期时间。

  • 多节点容错,只要大多数节点获取了锁就可以认为成功获取锁。

4.Redisson实现的分布式锁

Redisson是基于Netty、Redis、JDK实现的更上层的应用工具,它提供了分布式对象和服务。Redisson命令的发送可以支持同步方式,异步方式,Redisson可以支持多种Redis的实际部署方式,例如:单节点、集群、主备、热备、哨兵、云服务。可参考下面官方的架构图:

我们使用Redisson的分布式锁服务,因为Redisson支持Redis的集群部署、热备部署、哨兵部署、主备部署多种方式,而今天我们重点不在Redis的部署,所以我们就简单部署3个独立的Redis节点就可以实验了。

使用编码的方式获得Redisson实例

通过3个实例,获得红锁

加锁和释放锁

我们通过上面的代码片段,简单写一个工具类:

贴图保格式

总结

  1. Redis的应用场景简介。这里大家先思考redis开发模式和规范,强调下,仅仅使用key->value是很恐怖的事情。

  2. 我们分析了单节点Redis的锁不可靠,引入了红锁算法。

  3. 带领大家认识了功能丰富的Redisson,我们仅介绍了红锁功能。

希望本文章能带给大家一点收获,能理解到锁的重要,保证业务一致性才是锁的使命。谢谢大家阅读,不足之处评论指出。

相关推荐

Dubai's AI Boom Lures Global Tech as Emirate Reinvents Itself as Middle East's Silicon Gateway

AI-generatedimageAsianFin--Dubaiisrapidlytransformingitselffromadesertoilhubintoaglob...

OpenAI Releases o3-pro, Cuts o3 Prices by 80% as Deal with Google Cloud Reported to Make for Compute Needs

TMTPOST--OpenAIisescalatingthepricewarinlargelanguagemodel(LLM)whileseekingpartnershi...

黄仁勋说AI Agent才是未来!但究竟有些啥影响?

,抓住风口(iOS用户请用电脑端打开小程序)本期要点:详解2025年大热点你好,我是王煜全,这里是王煜全要闻评论。最近,有个词被各个科技大佬反复提及——AIAgent,智能体。黄仁勋在CES展的发布...

商城微服务项目组件搭建(五)——Kafka、Tomcat等安装部署

1、本文属于mini商城系列文档的第0章,由于篇幅原因,这篇文章拆成了6部分,本文属于第5部分2、mini商城项目详细文档及代码见CSDN:https://blog.csdn.net/Eclipse_...

Python+Appium环境搭建与自动化教程

以下是保姆级教程,手把手教你搭建Python+Appium环境并实现简单的APP自动化测试:一、环境搭建(Windows系统)1.安装Python访问Python官网下载最新版(建议...

零配置入门:用VSCode写Java代码的正确姿

一、环境准备:安装JDK,让电脑“听懂”Java目标:安装Java开发工具包(JDK),配置环境变量下载JDKJava程序需要JDK(JavaDevelopmentKit)才能运行和编译。以下是两...

Mycat的搭建以及配置与启动(mycat2)

1、首先开启服务器相关端口firewall-cmd--permanent--add-port=9066/tcpfirewall-cmd--permanent--add-port=80...

kubernetes 部署mysql应用(k8s mysql部署)

这边仅用于测试环境,一般生产环境mysql不建议使用容器部署。这里假设安装mysql版本为mysql8.0.33一、创建MySQL配置(ConfigMap)#mysql-config.yaml...

Spring Data Jpa 介绍和详细入门案例搭建

1.SpringDataJPA的概念在介绍SpringDataJPA的时候,我们首先认识下Hibernate。Hibernate是数据访问解决技术的绝对霸主,使用O/R映射(Object-Re...

量子点格棋上线!“天衍”邀您执子入局

你是否能在策略上战胜量子智能?这不仅是一场博弈更是一次量子智力的较量——量子点格棋正式上线!试试你能否赢下这场量子智局!游戏玩法详解一笔一画间的策略博弈游戏目标:封闭格子、争夺领地点格棋的基本目标是利...

美国将与阿联酋合作建立海外最大的人工智能数据中心

当地时间5月15日,美国白宫宣布与阿联酋合作建立人工智能数据中心园区,据称这是美国以外最大的人工智能园区。阿布扎比政府支持的阿联酋公司G42及多家美国公司将在阿布扎比合作建造容量为5GW的数据中心,占...

盘后股价大涨近8%!甲骨文的业绩及指引超预期?

近期,美股的AI概念股迎来了一波上升行情,微软(MSFT.US)频创新高,英伟达(NVDA.US)、台积电(TSM.US)、博通(AVGO.US)、甲骨文(ORCL.US)等多股亦出现显著上涨。而从基...

甲骨文预计新财年云基础设施营收将涨超70%,盘后一度涨8% | 财报见闻

甲骨文(Oracle)周三盘后公布财报显示,该公司第四财季业绩超预期,虽然云基建略微逊于预期,但管理层预计2026财年云基础设施营收预计将增长超过70%,同时资本支出继上年猛增三倍后,新财年将继续增至...

Springboot数据访问(整合MongoDB)

SpringBoot整合MongoDB基本概念MongoDB与我们之前熟知的关系型数据库(MySQL、Oracle)不同,MongoDB是一个文档数据库,它具有所需的可伸缩性和灵活性,以及所需的查询和...

Linux环境下,Jmeter压力测试的搭建及报错解决方法

概述  Jmeter最早是为了测试Tomcat的前身JServ的执行效率而诞生的。到目前为止,它的最新版本是5.3,其测试能力也不再仅仅只局限于对于Web服务器的测试,而是涵盖了数据库、JM...

取消回复欢迎 发表评论: