Redis分布式锁实现方式
分布式锁一般有三种实现方式
1. 数据库乐观锁;
2. 基于ZooKeeper的分布式锁;
3. 基于Redis的分布式锁;
三种方式的优缺点分析
1、数据库乐观锁:
优点是实现简单,只需要for update关键词就可以实现,缺点是无法满足高并发量以及数据库读写频繁的系统;
2、ZooKeeper分布式锁:
无论是从性能以及实现的功能来说都是非常优秀,只是在开发起来需要一定的基础,对新手可能不是很友好;
3、Redis实现分布式锁
优点是开发相对简单,能满足一定并发量的系统,缺点是存在线程争抢锁的问题,当并发量到达一定级别,多个线程去争抢同一个锁,对性能的影响较大;
事务以及原子性
虽然Redis是单线程运行,但是在分布式的情况下对同一资源进行操作还是会出现问题,下图是一个简单的例子
所以一定要保证tomcat1以及tomcat2读写的原子性,既读与写要么都执行,要么都不执行。关于事务的原子性可以查询这里
那么如何保证呢,redis在2.6中加入了lua脚本功能可以轻松的解决这个问题,下面是一个简单的例子实现了上述的加100操作
Jedis jedis = jedisPool.getResource(); String script = "local a = redis.call('get', KEYS[0]) a = a + 100 redis.call('set', a)";jedis.eval(script, 1, rname+"Lock",RedisCacheFactory.FactoryUUID,"1000");
分布式锁的具体实现
先说下思路:首先加锁的方式是向redis里存入一个KEY-VALUE,KEY存入的加锁对象可以是方法、类、数据等等,VALUE存入持有锁的节点(例如tomcat1)
大概整理了一下几个问题:
问题:为什么VALUE存入持有锁的节点?
D:为的是防止A加的锁被B给解除,保证只有持有锁的节点才能解锁;
问题:怎么存入持有锁的节点?
D:这里只是我的思路是在tomcat启的时候生成一个uuid作为该tomcat的token存入到VALUE中;
问题:怎么防止死锁?
D:利用Redis设置键的过期时间
下面贴出部分代码,仅供参考
加锁
JedisPool jedisPool = new JedisPool(new JedisPoolConfig(),RedisInstance.hostName,Integer.parseInt(RedisInstance.port),5000,password);
Jedis jedis = jedisPool.getResource(); // key1 : key值 argv1 :value值 argv2 :
过期时间 String script = "if redis.call('EXISTS',KEYS[1]) ==0 then redis.call('set',KEYS[1],ARGV[1]) redis.call('EXPIRE',KEYS[1],ARGV[2]) return 1 else return 0 end";
long result = (long) jedis.eval(script, 1, rname+"Lock",RedisCacheFactory.FactoryUUID,"1000");
jedis.close();
jedisPool.close();
解锁
JedisPool jedisPool = new JedisPool(new JedisPoolConfig(),RedisInstance.hostName,Integer.parseInt(RedisInstance.port),5000,password);
Jedis jedis = jedisPool.getResource();
String script = "if redis.call('EXISTS',KEYS[1]) ==1 and redis.call('GET',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
long result = (long) jedis.eval(script, 1, rname+"Lock",RedisCacheFactory.FactoryUUID);
jedis.close(); jedisPool.close();
到这里就写完了,有问题,大家可以一起交流下;
Redis分布式锁实现方式相关推荐
- **Java有哪些悲观锁的实现_80% 人不知道的 Redis 分布式锁的正确实现方式(Java 版)...
点击上方"小哈学Java",选择"星标" 回复"资源",领取全网最火的Java核心知识总结 来源:http://sina.lt/gfZU 前 ...
- Redis分布式锁【正确实现方式】
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
- Redis分布式锁的正确实现方式(Java版)
转自:https://wudashan.cn/2017/10/23/Redis-Distributed-Lock-Implement/ 前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于 ...
- redis 分布式锁的实现方式
情景如下: 我们有一批任务需要由多个分布式线程处理,每个任务都有一个taskId,为了保证每个任务只被执行一次,在工作线程执行任务之前,先获取该任务的锁,锁的key可以为taskId 方式1:set( ...
- Redis分布式锁的正确实现方式
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
- Java版基于Redis分布式锁的实现方式
一.什么是分布式锁? 要介绍分布式锁,首先要提到分布式锁相对应的线程锁和进程锁, 线程锁:组要是给方法.代码块加锁,当方法或者代码块使用锁时,在同一时刻只有一个线程可以执行该方法或者代码块,线程锁只在 ...
- Redis分布式锁的正确打开方式
Redis分布式锁的正确打开方式 为什么需要分布式锁 分布式锁原理 单机锁和分布式锁的联系与区别 Redis分布式锁的演进史 第一版 SETNX 如何避免死锁 解决锁被别人释放 锁过期时间不好评估 R ...
- Redis分布式锁的正确实现方式(转发来至博客园Ruthless )
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
- Java三种方式实现redis分布式锁
一.引入原因 在分布式服务中,常常有如定时任务.库存更新这样的场景. 在定时任务中,如果不使用quartz这样的分布式定时工具,只是简单的使用定时器来进行定时任务,在服务分布式部署中,就有可能存在定时 ...
最新文章
- centos上安装anaconda并配置虚拟环境
- 带FIFO的UART收发器设计(转发)
- DML、DDL、DCL的分别是什么
- ubuntu20.04LTS系统的终端terminal透明化设置
- shell脚本 如何切换当前目录
- 在百度搜索页添加公司总部的客服电话
- 5G(7)---5G NR协议栈及功能2 - MAC RLC PDCP SDAP
- 一个SpringBoot项目,开发业务前至少应该引入哪些配置?
- pyspark报错问题 Exception in thread main java.lang.UnsupportedClassVersionError 成功解决
- 眼图在通信系统中有什么意义_OA协同办公系统存在的意义是什么?协同OA的显着优势又在哪儿?...
- Linux之常用Shell脚本总结
- 多智能体协同视觉SLAM技术研究进展
- ◇Windows 7 XP SP3 2in1 集成安装版 2010贺岁版◇
- 初探一个0代码开发—iVX平台
- 【python面向对象】技能系统
- dsolve()函数求解微分方程
- 实现一个简单的Database1(译文)
- QGIS-wgs坐标和gcj坐标的区别
- codeforces 1090B切题记录
- 【航天】【火箭】长征九号
热门文章
- Docker学习笔记_安装和使用Apache
- 线段树模板hdu 1754:I Hate It
- Zabbix 3.2.6 升级到 Zabbix 3.4.3
- ssh报错:Could not load host key:/etc/ssh/ssh_host_rsa_keyssh_host_ecdsa_keyssh_host_ed25519_key...
- WKQ学习(后台知识)
- 三星第二财季净利69亿美元 同比增50%
- 最近面试,笔试题中的一道sql题
- 深入浅出剖析 OpenCV 视觉处理
- mysql 踩过的坑_MySQL数据库踩过的一些坑
- 单片机小精灵t2_51单片机定时器T2初始化设置