Redis04-分布式锁

目录

Redis实现分布式锁

分布式锁的工作流程

Redis实现分布式锁

Redission的watch dog

Redis分布式锁的合理应用


Redis实现分布式锁

在单节点的服务器中,java中的synchronized机制是处于JVM层面的,只能保证线程之间的同步。而实际的服务部署中,我们通常会使用多节点的集群部署方式,而要保证多个节点中的不同进程对数据的同步操作,就需要使用分布式锁。

使用分布式锁的主要目的是在分布式环境中确保多个节点之间的协同操作,避免由于并发访问而导致的数据不一致、竞态条件等问题。以下是使用分布式锁的一些常见原因:

  1. 避免并发问题: 在分布式系统中,多个节点可能同时对共享资源进行访问。使用分布式锁可以确保对关键资源的访问在同一时刻只有一个节点拥有,避免并发问题,如数据不一致、丢失更新等。

  2. 保护共享资源: 分布式系统中的共享资源,例如数据库、缓存、文件等,可能同时被多个节点访问。通过使用分布式锁,可以保护这些共享资源,确保在任何时刻只有一个节点能够修改它们。

  3. 防止死锁: 在分布式系统中,由于网络分区、节点故障等原因,可能发生死锁。通过使用分布式锁,可以避免因为多节点间的协同操作导致的死锁问题。

  4. 控制访问顺序: 在某些场景下,需要对共享资源的访问进行有序控制,确保一些操作的执行顺序。分布式锁可以用于实现对资源的顺序访问。

  5. 实现分布式协调: 分布式锁是实现分布式协调和同步的一种重要机制。例如,在分布式任务调度、分布式事务等场景中,分布式锁可以用于协调不同节点的操作。

  6. 防止重复执行: 在一些需要幂等性操作的场景下,分布式锁可以用于防止同一操作被重复执行。

  7. 避免“多写”问题: 当多个节点同时写入同一数据时,可能导致“多写”问题,即最后写入的值覆盖了之前的写入。分布式锁可以用于保护写入操作,确保只有一个节点能够写入。

分布式锁的工作流程

Redis实现分布式锁

Redis实现分布式锁主要利用的是Redis的setnx命令。setnx是Set if no exists的简写。

CenOs7:0>setnx lock 1 # 首次设置lock值1
"1"  # 设置成功返回1
CenOs7:0>setnx lock 1 # lock已存在,给lock赋值
"0"  # 设置失败返回0,不做任何操作
CenOs7:0>get lock # 获取lock的值
"1"  # lock值为1
CenOs7:0>del lock # 删除lock,释放锁
"1"  # 删除成功,返回1
CenOs7:0>get lock # 获取lock的值
null # lock为空
CenOs7:0>setnx lock 1 # 设置lock值为1
"1"  # 设置成功

需要注意的是,setnx的方式是不支持重入锁的。而且锁的持有时间很难控制。单纯地依赖expire设置过期时间是不现实的。

Redission的watch dog

Redission引入了“看门狗”的机制,目的是处理锁的续期问题。

代码示例:

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
​
import java.util.concurrent.TimeUnit;
​
public class RedissonWatchdogExample {
​public static void main(String[] args) throws InterruptedException {// 创建 Redisson 客户端Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");RedissonClient redisson = Redisson.create(config);
​// 获取分布式锁RLock lock = redisson.getLock("myLock");
​try {// 尝试获取锁并设置锁的过期时间为10秒// boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);// 如果设置了第二个参数[锁的持续时间]就默认不使用watchdog// redission中的lock是依赖了底层lua脚本的原子性实现的boolean isLocked = lock.tryLock(10, TimeUnit.SECONDS);
​if (isLocked) {// 获取锁成功,执行业务逻辑System.out.println("Lock acquired. Executing business logic...");
​// 模拟业务逻辑执行时间Thread.sleep(5000);
​// 业务逻辑执行完毕,不需要手动释放锁,Watchdog会自动续期或者释放锁
​} else {System.out.println("Failed to acquire the lock within the specified time");}
​} finally {// 关闭 Redisson 客户端redisson.shutdown();}}
}

创建了一个名为"myLock"的分布式锁,并使用tryLock方法尝试获取锁,设置锁的过期时间为10秒。在获取锁成功后,执行了一段模拟的业务逻辑,并且无需手动释放锁,因为Watchdog会在锁过期时自动续期或释放锁。

Redission实现可重入锁

Redission通过Hash结构实现重入锁的,key对应的是lock,value存放的是线程信息。

需要注意的是,Redisson Watchdog是默认开启的,你不需要额外的配置。在正式的生产环境中,建议你根据实际需求进行更详细的配置,比如设置Watchdog的检查间隔、锁的失效时间等参数。

红锁(RedLock)

Redis集群是主从复制结构,Master负责写,Slave负责读。setnx是在Master实例上进行加锁。

  • Java应用通过setnx在Master节点获取锁。

  • Master节点异常,Redis通过哨兵机制选举出新的Master。

  • Java应用通过setnx在新的Master节点获取锁。

  • 此时集群中存在两把锁,违背了锁的互斥性。

针对这种情况,Redis提供了RedLock,它的主要机制是在(n/2+1)个节点实例上同时创建锁。

RedLock解决了锁的互斥性问题,同时缺点也很明显:实现复杂,性能差,同时运维繁琐。针对分布式中的CAP现象,不同的业务应该选择对应的方案:

  • AP思想(高可用性+分区容错):使用Redis实现分布式锁

  • CP思想(强一致性+分区容错):使用Zookeeper实现分布式锁

需要注意的是,Redisson Watchdog是默认开启的,你不需要额外的配置。在正式的生产环境中,建议你根据实际需求进行更详细的配置,比如设置Watchdog的检查间隔、锁的失效时间等参数。

Redis分布式锁的合理应用

Redis分布式锁是在多个节点之间实现互斥访问共享资源的一种机制。它可以应用于各种场景,以下是一些合理的应用场景:

  1. 分布式任务调度: 当有多个节点需要执行定时任务或者周期性任务时,可以使用分布式锁确保同一时刻只有一个节点在执行任务,避免重复执行或者竞态条件。

  2. 分布式缓存更新: 当多个节点需要同时更新某个缓存或者共享的数据时,可以使用分布式锁确保只有一个节点能够进行更新操作,防止并发问题。

  3. 分布式事务: 在分布式事务场景下,可能需要对一些关键资源进行加锁,以确保在事务执行期间,其他事务不会修改这些资源,从而保证事务的隔离性。

  4. 防止重复操作: 在一些场景下,可能需要防止某个操作被重复执行。通过使用分布式锁,可以确保同一时刻只有一个节点能够执行这个操作,防止重复操作。

  5. 分布式限流: 在某些情况下,需要对请求进行限流,确保系统不被过度请求。通过使用分布式锁,可以控制某个时间窗口内只有一个节点能够处理请求,实现简单的限流效果。

  6. 分布式协同: 当多个节点需要协同工作时,可以使用分布式锁确保各个节点之间的操作按照规定的顺序进行,防止不一致或混乱的情况发生。

  7. 分布式任务队列: 在分布式环境中,多个节点可能需要消费同一个任务队列。通过使用分布式锁,可以确保只有一个节点能够成功获取并消费队列中的任务,避免重复消费。

  8. 资源竞争: 当多个节点需要竞争某个资源时,可以使用分布式锁来进行竞争,确保只有一个节点能够成功占用资源,如分布式锁用于实现分布式秒杀场景。

需要注意的是,在使用分布式锁时,要注意锁的超时策略、锁的释放等问题,以确保系统的稳定性和性能。此外,选择成熟的分布式锁实现库,如Redisson、Curator等,可以减少潜在的问题,提高开发效率。

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

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

相关文章

李开复再度回应争议;10 月中国游戏厂商及应用出海收入 30 强出炉丨 RTE 开发者日报 Vol.86

开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE (Real Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有…

Java排序算法之堆排序

图解 堆排序是一种常见的排序算法,它借助了堆这种数据结构。堆是一种完全二叉树,它可以分为两种类型:最大堆和最小堆。在最大堆中,每个结点的值都大于等于它的子结点的值,而在最小堆中,每个结点的值都小于等…

mac homebrew.mxcl.php@5.6.plist

今天启动php5.6时 遇到了一个问题 servers % brew services start php5.6 Bootstrap failed: 5: Input/output error Try re-running the command as root for richer errors. Error: Failure while executing; /bin/launchctl bootstrap gui/501 /Users/ssh/Library/LaunchAge…

深兰科技轮腿家用AI机器人荣获“2023年度城市更新科创大奖”

近日,“2023金砖论坛第五季金立方城市更新科创大会”在上海举行,会上发布了《第12届金砖价值榜》,深兰科技研发出品的轮腿式家用AI机器人(兰宝),因其AI技术的创新性应用,荣获了“2023年度城市更新科创大奖”。 在10月2…

word批量图片导出wps office word 图片批量导出

word批量导出图片教程 背景 今天遇到了一个场景,因为word里的图片打开看太模糊了,如果一个一个导出来太麻烦。想批量将word中的图片全部导出 但是,wps导出的时候需要会员 教程开始: 将word保存为 .docx 格式,可以按F1…

2023版Idea创建JavaWeb时,右键new没有Servlet快捷键选项

问题:右键时,没有创建servlet的快捷键,如下图: 解决方法: 1.打开idea,点击File>settings(设置),进入settings页面,如下 从上图中的Files选项中没看到有servlet选项,…

2023.11.17 -hivesql调优,数据压缩,数据存储

目录 1.hive命令和参数配置 2.hive数据压缩 3.hive数据存储 0.原文件大小 18.1MB 1.textfile行存储格式, 压缩后size:18MB 2.行存储格式:squencefile ,压缩后大小8.89MB​ 3. 列存储格式 orc - ZILIB ,压缩后大小2.78MB 4.列存储格式 orc-snappy ,压缩后大小3.75MB 5…

懒人福利:6款Sketch插件合集,提升设计效率爆款推荐!

Sketch作为一种在线设计工具,一直是许多设计师的最爱。它不仅能快速建立原型,还能提供丰富的插件,以满足不同的需求。 今天,我想和大家分享六款流行的Sketch插件供参考。这些插件都是精心挑选的,它们支持Windows、Mac…

python的re正则表达式

华子目录 什么是正则表达式元字符字符集字符集与元字符的综合使用 数量规则指定匹配次数边界处理分组匹配贪婪匹配非贪婪匹配re.S转义字符re.search()re.sub()实例常见的匹配模式 什么是正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串…

如何检查 Docker 和 Kubernetes 是否可以访问外部网络,特别是用于拉取镜像的仓库?

要检查 Docker 和 Kubernetes 是否可以访问外部网络,尤其是用于拉取容器镜像的仓库,您可以按照以下步骤进行: 1. 检查节点的网络连接 首先,您需要确保 Kubernetes 节点能够访问外部网络。这可以通过在节点上执行 ping 命令来测试…

照亮夜晚的台灯:户外空间的闪亮之选

户外台灯是家庭和社交空间的重要元素,它们不仅提供照明,还可以为您的户外区域增添美感,以及创造一个温馨的社交氛围。以下是一些关于户外台灯的信息,以帮助您更好地了解它们的多功能性和用途。 1、照明的重要性:户外台…

使用ResponseSelector实现校园招聘FAQ机器人

本文主要介绍使用ResponseSelector实现校园招聘FAQ机器人,回答面试流程和面试结果查询的FAQ问题。FAQ机器人功能分为业务无关的功能和业务相关的功能2类。 一.data/nlu.yml文件   与普通意图相比,ResponseSelector训练数据中的意图采用group/intent格…

消息通讯——MQTT WebHookSpringBoot案例

目录 EMQX WebHook介绍EMQX WebHook是什么EMQX WebHook配置项如何使用EMQX WebHook配置WebHook配置事件推送参数详解 SpringBoot集成Webhook实现客户端断连监控1. 实现前提2. 代码实现接口3. 监听结果 总结 EMQX WebHook介绍 EMQX WebHook是什么 EMQX WebHook 是由 emqx_web_…

使用Postman进行压力测试

1.打开Postman新建测试接口 2.点击右边保存,选择一个文件集合,如果没有就创建,然后保存 就是这个东西,这里不便展示出来,压力测试需要在文件夹里面进行 3.选择要测试的接口,iterations 表示请求发起次数&a…

一个22届被裁前端思想上得转变

距离上篇文章已经过去了三个多月,这个三个月,经历了技术攻坚,然后裁员,退房,回老家,找工作。短短的几个月,就经历社会的一次次毒打,特别是找工作,虽然算上实习我也有两年…

将按键放到输入框内:

如何将将Button放到输入框内&#xff1f; 效果图&#xff1a; 步骤如下&#xff1a; button 外围用template 包裹一层 <template #suffix v-if"row.WorkerRole TPM"> <el-inputtype"text"v-model"row.JobNumber"placeholder"…

电路综合-基于简化实频的集总参数电路匹配1

电路综合-基于简化实频的集总参数电路匹配1 对于分布式参数的匹配方法&#xff0c;我们已经深入探讨并给出了解决方案&#xff1a; 10、电路综合-基于简化实频的宽带匹配电路设计方法 {阻抗匹配其实就是S11电路的匹配&#xff0c;给定需要匹配的阻抗数值去设计微带电路&#…

【数据结构 | 链表】leetcode 2. 两数相加

个人主页&#xff1a;兜里游客棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里游客棉花糖 原创 收录于专栏【LeetCode】 原题链接&#xff1a;点击直接跳转到该题目 目录 题目描述解题代码 题目描述 给你两个 非空 的链表&#xff0c;表示两个非…

第十九章绘图

Java绘图类 Graphics 类 Grapics 类是所有图形上下文的抽象基类&#xff0c;它允许应用程序在组件以及闭屏图像上进行绘制。Graphics 类封装了Java 支持的基本绘图操作所需的状态信息&#xff0c;主要包括颜色、字体、画笔、文本、图像等。 Graphics 类提供了绘图常用的…

京东联盟flutter插件使用方法

目录 1.京东联盟官网注册申请步骤略~2.安卓端插件配置&#xff1a;3.IOS端插件配置4.其它配置5.京东OAuth授权 文档地址&#xff1a;https://baiyuliang.blog.csdn.net/article/details/134444104 京东联盟flutter插件地址&#xff1a;https://pub.dev/packages/jdkit 1.京东联…