分布式环境下利用Redis实现分布式锁

Redis——Redis分布式锁原理与实战 分布式应用进行逻辑处理时经常会遇到并发问题。比如一个操作要修改用户的状态,修改状态需要先读出用户的状态,在内存里进行修改,改完了再存回去。如果这样的操作同时进行了,就会出现并发问题,因为读取和保存状态这两个操作不是原子的。( Wiki 解释:所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch 线程切换。)这个时候就要使用到分布式锁来限制程序并发的执行。 阅读详情

    在某些高并发的业务场景下,例如秒杀、选课等系统,为了避免出现商品超卖、选课人数超出课程规定人数的问题发生,读写数据库时需要进行加锁操作,保证某时刻已有一个用户在操作。在Java单机应用中,直接使用synchronized关键字没有任何毛病,但在分布式系统中就不行了,这时就需要引入分布式锁来解决问题。分布式锁可以用Zookeeper或Redis来实现,本文重点讲解使用Redis实现分布式锁。

    在Redis中有一个SETNX命令,如果key在Redis中存在,返回0,否则返回1,执行成功。下面是一种错误的实现分布式锁的思路,最后我会写一个正确的实现分布式锁的代码,请大家参考

错误的分布式锁思路

    假如客户1需要加锁时执行SETNX("key","value")返回1加锁成功,其余客户执行SETNX返回0没有获取锁,加锁失败会一直监听key并循环执行SETNX("key","value"),直到返回1。当客户1需要释放锁时需要执行DEL("key")释放锁。但这里有一个问题,如果客户1所在的进程挂掉后,key永远不会被删除,其余客户执行SETNX("key" ,"value")永远返回0,产生死锁,这样的分布式锁思路是错误的。

正确的思路

    如果客户进程获得锁后,设置一个超时移除的动作,如expire命令,客户进程挂掉后超时锁自动释放,其他客户任然可以获得锁。下面我用多线程来模拟高并发下的分布式锁的获取、释放。

    客户端获得锁:

        将k v通过SETNX命令存入Redis,如果返回1则表明Redis没有这条数据,操作成功获得锁,如果返回0则表明Redis中有这条   数据,其他客户端占有锁,获得锁失败,进入等待状态。

    RedisThread.java

/**
	 * 获得锁
	 */
	public boolean getLock(){
		Jedis jedis = pool.getResource();
		Long ret = jedis.setnx("k", "v");
		//ret==1,获得锁
		if(ret == 1){
			System.out.println(Thread.currentThread().getName()+":lock");
			//如果某个客户端挂掉没有执行del操作,则设置超时时间释放锁,否则会死锁。
			jedis.expire("k",10);
			jedis.close();
			return true;
		}
		//没有获得锁
		jedis.close();
		return false;
	}

        模拟一个客户端

            如果getLock()方法返回true,则表明获得锁,执行后面的业务逻辑,最后通过DEL(k)命令释放锁。

            如果getLock()方法返回false,循环持续监听(当然也可以通过Thread.sleep()控制监听频率),直到获得锁后执行业务逻辑最后释放锁。

    RedisThread.java

/**
	 * 模拟客户端
	 * @throws Exception
	 */
	public void client() throws Exception{
		boolean b = getLock();
		//如果没有获得锁,持续监听
		while(!b){
			b = getLock();
		}
		System.out.println(Thread.currentThread().getName()+"执行业务开始");
		Long startTime = System.currentTimeMillis();
		Thread.sleep(new Random().nextInt(1000));
		System.out.println(Thread.currentThread().getName()+"执行业务结束,共用时"+(System.currentTimeMillis()-startTime)+"ms");
		Jedis jedis = pool.getResource();
		jedis.del("k");	//unlock
		jedis.close();
	}

        开启多个线程模拟高并发

    RedisThread.java

@Override
	public void run() {
		try {
			//调用客户端
			client();
		} catch (Exception e) {
			e.printStackTrace();
		}		
	}

RedisLock.java 测试

开启50个线程模拟50个客户(50个服务组成的集群)

public class RedisLock {
	public static void main(String[] args) {
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxIdle(50);
		config.setMaxTotal(50);
		JedisPool pool = new JedisPool(config, "192.168.1.104", IpService.REDIS_PORT);
		
		Thread[] t = new Thread[50];
		for(int i = 0;i<t.length;i++){
			t[i] = new Thread(new RedisThread(pool));
		}
		for(int i = 0;i<t.length;i++){
			t[i].start();
		}
	}
}

输出结果如下:

lock-->业务开始-->业务结束-->unlock--lock-->.......

Thread-52:lock
Thread-52执行业务开始
Thread-52执行业务结束,共用时802ms
Thread-52unlock
Thread-13:lock
Thread-13执行业务开始
Thread-13执行业务结束,共用时65ms
Thread-13unlock
Thread-45:lock
Thread-45执行业务开始
Thread-45执行业务结束,共用时773ms
Thread-45unlock
Thread-4:lock
Thread-4执行业务开始
Thread-4执行业务结束,共用时860ms
Thread-4unlock
Thread-33:lock
Thread-33执行业务开始
Thread-33执行业务结束,共用时127ms
Thread-33unlock
Thread-20:lock
Thread-20执行业务开始
Thread-20执行业务结束,共用时510ms
Thread-20unlock
Thread-40:lock
Thread-40执行业务开始
Thread-40执行业务结束,共用时450ms
Thread-40unlock


    


ESXI 8.0虚拟机安装OpenWRT软路由详细教程 OpenWrt 是嵌入式的 Linux 路由器固件,OpenWrt在稳定运行的同时提供了强大的扩展能力,用户可以完全的定制属于自己的路由系统,满足不一样的个性化需求,本文讲解如何使用ESXI安装OpenWRT,打造属于自己的软路由。本次安装使用的是版本。默认登录信息:用户:root密码:password下载固件:https://github.com/haiibo/OpenWrt/releases/tag/X86_64【CPU配置】:4核心。 阅读详情

相关推荐

【AMD显卡在WIndow10/11部署带GPU支持的深度学习环境(Pytorch-DirectML篇)】

这篇是之前Tensorflow-DirectML的姊妹篇,如果对TF感兴趣的可以搜索我的博文。 首先我们丢一个官网地址,但是官网那个会误导新人如果你按那个操作的话。 https://docs.microsoft.com/en-us/windows/ai/directml/gpu-pytorch-windows 这里用我的方法操作: 首先声明一下,因为我的显卡是AMD RX6600,不带XT(性能和RTX3060 12G版本半斤八两),所以目前没有最新的WSL2驱动,如果有了的话欢迎告知我,所以我这里就.

weixin_44029053的博客 2万+

jedispool redis哨兵_阿里架构师分析:分布式锁之剖析Redis实现

分布式锁这部分主要对分布式锁再次做一次较为完整的回顾与总结。什么是分布式锁引用度娘的词条,对于分布式锁的解释如下:这段话概括的还是不错的,根据概述以及对单机锁的了解,我们能够提炼并类比得出分布式锁的几个主要约束条件:分布式锁的约束条件特点描述互斥性即:在任意时刻,只有一个客户端能持有锁安全性即:不会出现死锁的情况,当一个客户端在持有锁期间内,由于意外崩溃而导致锁未能主动解锁,其持有的锁也能够被正确...

weixin_39883256的博客 224

西门子 S7-200 SMART 系列六:手把手教你配置S7-200 SMART Modbus RTU

最新发表:https://www.ics-pedia.com/%e8%a5%bf%e9%97%a8%e5%ad%90-s7-200-smart-%e7%b3%bb%e5%88%97%e5%85%ad%ef%bc%9a%e6%89%8b%e6%8a%8a%e6%89%8b%e6%95%99%e4%bd%a0%e9%85%8d%e7%bd%aes7-200-smart-modbus-rtu%e5%ae%9e%e4%be%8b/

John_09040211的博客 3281

jedis实现分布式锁(悲观锁)

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34018202的博客 182

手眼标定搞定了,手眼矩阵不知道怎么用?快戳!!

手眼标定得到手眼矩阵到底该咋用? 大家好,我是小鱼。上几期给大家分享了关于手眼标定的方法,如果还有不清楚如何让进行手眼标定的同学可以参考下面的文章: 机器人手眼标定都能搞不定?快戳,最好用的手眼标定库!!! 很多同学做完了手眼标定之后得到了手眼矩阵,但是不知道怎么用于程序当中去,还有很多同学搞不清楚各个坐标系之间的关系,今天小智就给大家讲讲手眼矩阵的使用问题。 一、手眼矩阵为什么会长的不一样? 做完手眼标定,得到的手眼矩阵,有可能会长的不一样,这是因为旋转变换是有很多种表示方法的。 1.旋转的表

生活不止眼前的苟且 5343

密码学系列3-Elgamal加密及其IND-CPA安全性证明

但这没有任何影响,敌手本身就只能知道公钥,他并没有能力知道挑战者是否知道对应的私钥。所以上述整个游戏就是一个模拟实验,敌手无法区分挑战者运行的是这个模拟实验,还是真正的按照第一节的算法构造的实验(挑战者知道私钥…为什么合起来的时候有1/2:因为T既可能是随机的也可能是g^{ab},这两种情况概率为1/2。能够攻破Elgamal加密方案,那么挑战者利用敌手的能力构建下面游戏,来求解困难性问题DDH。就是挑战者选的随机数,虽然挑战者自己也不知道。),否则挑战者输出0,作为DDH的回答。

qq_41359358的博客 1250

分布式锁专题-Jedis实现分布式锁

1.业务场景引入 在进行代码实现之前,我们先来看一个业务场景: 系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单。 由于系统有一定的并发,所以会预先将商品的库存保存在redis中,用户下单的时候会更新redis的库存。 此时系统架构如下: 但是这样一来会产生一个问题: 假如某个时刻,redis里面的某个...

专业的计算机毕业设计指南 782

大数据分析案例-基于决策树算法构建世界杯比赛预测模型

本项目旨在分析往届世界杯比赛数据,找出规律,最后使用决策树算法构建世界杯比赛预测模型,给出两个球队即可预测胜率,可以给爱看球的小伙伴提供一个参考。本次实验我们使用了2018年及其之前的世界杯比赛数据,通过建立决策树模型,模型准确率为82%,接着我们使用该模型预测了2022年世界杯的5场半决赛及决赛,模型准确率也是接近80%的,说明模型效果还是很不错的。心得与体会:通过这次Python项目实战,我学到了许多新的知识,这是一个让我把书本上的理论知识运用于实践中的好机会。

m0_64336780的博客 1万+

Jedis无法连接Redis的解决办法

文章目录解决步骤:1.注释掉绑定的信息:2.关闭保护模式:3.关闭redis防火墙关闭防火墙命令:4.需要启动redis服务5.端口号是否一致成功 解决步骤: 1.注释掉绑定的信息: 在redis.conf的配置文件中: 在redis.conf的配置文件中bind配置的信息表示的是redis服务可以接收外部访问的地址,这个主要还是为了提高安全性,我们在学习阶段可以将这个信息直接注释掉,这样的话...

Tang 3249

【FISCO-BCOS】 八、ubuntu配置Java环境

ubuntu配置Java环境需根据自己的java版本号进行细节修改,本文以jdk11.0.18版本为例。ps:通过此法还可以查看java安装路径,但必须是环境配置成功的情况下才能使用。二、添加Java环境路径。四、检查java环境设置。

naihe_fish的博客 4310

C# ScottPlot 5.0 WinForms 十字光标示例:轻松实现动态数值显示,你学会了吗?

ScottPlot是一个免费、开源的.NET交互式绘图库,能够轻松地实现大型数据集的交互式显示。它支持多种图表类型,如折线图、柱状图、饼图、散点图等。ScottPlot的性能非常出色,即使是处理千万级别的数据也游刃有余。

java专栏 2218

实现Redis分布式锁

实现Redis分布式锁 前言 在面试中经常会被面试官问到Redis分布式锁,随着用户量和业务的增加,传统的单体架构已经无法满足我们的业务需求,这时候单体架构项目的必须升级为分布式、集群、微服务。分布式项目能带来性能上的提升,但分布式环境和集群环境下,存在数据一致性的问题。在分布式项目中,因为分布式和集群是部署到不同的服务器,线程资源不能共享,传统的锁已经无法满足我们的需求了,这时候就需要分布式...

weixin_42962663的博客 2407

基于Python的新闻聚合与推荐系统:抓取多新闻网站内容并根据用户兴趣进行个性化推荐

本文介绍了如何使用Python构建一个新闻聚合与推荐系统,涵盖了从新闻数据抓取、用户兴趣建模到推荐算法实现的全过程。通过爬虫技术抓取新闻网站内容,使用TF-IDF、Word2Vec等算法进行内容分析,并通过推荐算法向用户推送个性化的新闻,最终帮助用户快速获取自己感兴趣的信息。你可以根据具体需求,进一步扩展和优化系统。例如,加入更多的推荐算法、优化爬虫的抓取效率、增强前端展示的互动性等。通过本文的指导,您应该能够构建一个完整的新闻聚合与推荐系统,并为用户提供个性化的新闻推荐服务。

2201_76125261的博客 1514

SpringBoot之使用Redisson实现分布式锁(含完整例子)

SpringBoot之使用Redisson实现分布式锁(含完整例子)   前面讲完了Redis的分布式锁的实现,接下来讲Redisson的分布式锁的实现,一般提及到Redis的分布式锁我们更多的使用的是Redisson的分布式锁,Redis的官方也是建议我们这样去做的。Redisson点我可以直接跳转到Redisson的官方文档   1.引入Maven依赖 <dependency> <groupId>org.redisson</groupId> <a

atu1111的博客 2万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

redis分布式锁实现原理_分布式锁Redis实现详细流程,看完值得收藏

分布式锁为什么需要有分布式锁呢,在单点的时候synchronized 就能解决,但是服务拆分之后,每个服务都是单独的机器,无法解决,所以出现了分布式锁,其实也就是用各种手段,实现获取唯一锁,别人无法得到。其实在做分布式锁的前提,需要先明白,synchronized 为啥不能使用了,啥原理让他在一个机器上可以使用。synchronized 的原理众所周知 Synchronize 关键字是解决并发问题...

weixin_39609457的博客 453

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

基于 Redis 实现分布式锁思考

推荐大家关注一个公众号点击上方 "编程技术圈"关注,星标或置顶一起成长后台回复“大礼包”有惊喜礼包!每日英文Two things always to be remembe...

程序员小乐 327

分布式锁用 Redis 还是 Zookeeper?

Curator是一个zookeeper的开源客户端,也提供了分布式锁的实现。{try {= null ) {}// 获取当前所有节点排序后的集合// 获取当前节点的名称// 判断当前节点是否是最小的节点// 获取到锁} else {// 没获取到锁,对当前节点的上一个节点注册一个监听器= null ){= null ){break;}}}

LoveSummer 2万+

redis实现分布式锁

通过唯一标识值和原子操作,保证了锁的基本原子性和持有者的唯一性。Watchdog 自动续期确保任务执行超时时不会因锁过期被其他线程抢占。Redisson 提供了更高的易用性和可靠性,非常适合在 Spring Boot 中集成。

qq_35861084的博客 1525

Java 中利用 redis 实现一个分布式锁服务

在现代的编程语言中,接触过多线程编程的程序员多多少少对锁有一定的了解。简单的说,多线程中的锁就是在多线程环境下,多个线程对共享资源进行修改的时候,保证共享资源一致性的机制。这里不展开说。在分布式环境下,原来的多线程的锁就不管用了,也就出现了分布式锁的需求。所谓分布式锁服务也就是在分布式环境下,保证多个分布式的服务共享的资源一致性的服务。 在分布式环境下实现一个分布式锁服务并不太容易,需要考虑很多在单进程下的锁服务不需要考虑的问题。分布式锁锁的实现也有很多。这里我们讨论在 Java 中通过 redis 来实.

246

基于Redis的分布式锁

使用redis的特性实现分布式环境下的锁机制! pdf版本教程已发布

鸟哥哥的专栏 2626

redis setnx 分布式锁_Redis 分布式锁PHP

Redis 分布式锁的作用在单机环境下,有个秒杀商品的活动,在短时间内,服务器压力和流量会陡然上升。这个就会存在并发的问题。想要解决并发需要解决一下问题1、提高系统吞吐率也就是qps 每秒处理的请求书解决问题一:采用内存型数据库提高系统的qps解决问题二:就要用到经常会遇到的锁,例如MySQL 有读锁、写锁、排他锁、悲观锁、乐观锁。不过这里只讨论redis来实现锁简单版设置锁$redis...

weixin_39793420的博客 378

分布式锁——Redis实现

分布式锁是在分布式场景中,实现共享资源互斥访问的一种方式。Java中synchronized或ReentrantLock只能保证在一个jvm中的最多只有一个线程可以获取资源的锁,但是如果是分布式场景,会有多个jvm中各自的线程都会竞争共享资源。这时synchronized或ReentrantLock就无能为力,就需要使用分布式锁。 分布式锁的特点 互斥性:同一时间只能有一个线程获取锁 可重入性:一个线程获取锁之后,可以再次获取锁 锁超时:支持锁超时,防止死锁 分布式锁的实现方式 redis zo

BruceBupt的博客 341

在什么情况下需要分布式锁?

举个栗子: 高并发下争夺共享资源,比如秒杀对于库存这种共享资源需要用到分布式锁,如果不用分布式锁很可能造成超卖。 分布式锁也是锁 在单体应用的时候,如果多个线程要访问共享资源的时候,我们通常线程间加锁的机制,在某一个时刻,只有一个线程可以对这个资源进行操作,其他线程需要等待锁的释放,Java中也有一些处理锁的机制,比如synchronized。 而到了分布式的环境中,当某个资源可以被多个系统访问使用到的时候,为了保证大家访问这个数据是一致性的,那么就要求再同一个时刻,只能被一个系统使用,这时候线程之

shi_AXing_a的博客 6933

【Redis分布式锁】学习笔记

分布式锁

Wade__Hao的博客 792

Redis分布式锁简单入门

Redis Distributed Lock 1、分布式锁简介 锁是一种用来解决多个执行线程访问共享资源错误或数据不一致问题的工具 当前的互联网应用的架构都是分布式为主,所以引入了分布式锁来解决分布式应用之间共享资源的并发问题 一般情况下,使用分布式锁主要有以下两个场景: 避免不同节点重复相同的工作:比如向用户发送邮件,可能不同的分布式节点同时都向同一个用户发送了多封内容相同的邮件 避免破坏数据的正确性:两个分布式节点同时操作一份数据,可能造成数据错误或者不一致的情况 2、一些常

qq_41151580的博客 206

redis分布式锁

redis分布式锁

weixin_43008526的博客 306

redis 实现分布式锁

在单机系统中可以将锁的标识放入应用内存中。但分布式系统中需要将锁的标识放入共享存储系统中,如果不要求强一致性可以使用redis作为共享存储系统。 单节点分布式锁 单节点分布式锁指应用在设置标识时只操作单节点redis,如果对可靠性要求不高可以使用单节点实现分布式锁。其实现也比较简单。主要利用redis单线程处理请求模式设置锁标识。 流程如下图: 1.线程A,B两个请求,A先进入redis对flag进行setnx操作(setnx key ...

shaofei_huai的博客 280
上一篇: KeepAlived配置与Nginx高可用
下一篇: JVM性能调优总结
刘莅
博客等级 码龄10年 49粉丝 75原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值