Redis:分布式锁setnx(只 实现了 互斥性和容错性)
Redis:分布式锁setnx(只 实现了 互斥性和容错性)
关键词
- 同时在redis上创建同一个key,只有一个能成功,即获得锁
- 获取锁:原子性操作 set方法(推荐),谁set成功谁获取到锁(过期时间,避免死锁)
- 释放锁:redis+lua脚本实现
- 问题1(同一性):主从架构,主机宕机,重复获得锁问题(可以使用红锁解决99%,降低重复获取概率,redis在分布式环境下是ap模型)
红锁:三个节点,往两个节点上set成功,才能获取锁 - 问题2(续租):无法续租问题(使用Redisson的看门狗进行续租)
- 问题3:(重入性)
一、实现原理
共享资源 互斥
共享资源 串行化
分布式应用中使用锁:(多进程多线程)
- 分布式锁是控制分布式系统之间同步访问共享资源的一种方式
- 利用Redis的单线程特性对共享资源进行串行化处理
单应用中使用锁:(单进程多线程)
- synchronized、ReentrantLock
二、实现方式
2.1 获取锁
方式1 (使用set命令实现) – 推荐
/**
* 使用redis的set命令实现获取分布式锁
* @param lockKey 可以就是锁
* @param requestId 请求ID,保证同一性 uuid+threadID
* @param expireTime 过期时间,避免死锁
* @return
*/
public boolean getLock(String lockKey,String requestId,int expireTime) {// NX: 保证互斥性// hset 原子性操作 只要lockKey有效 则说明有进程在使用分布式锁String result = jedis.set(lockKey, requestId, "NX", "EX", expireTime);if("OK".equals(result)) {return true;}return false;
}
方式2 (使用setnx命令实现) – 并发会产生问题
public boolean getLock(String lockKey,String requestId,int expireTime) {Long result = jedis.setnx(lockKey, requestId); //如果挂了,没有设置expire,别人永远无法获取锁if(result == 1) {//成功设置 进程down 永久有效 别的进程就无法获得锁jedis.expire(lockKey, expireTime);return true;}return false;
}
2.2 释放锁
方式1 (del命令实现) – 并发
/**
* 释放分布式锁
* @param lockKey
* @param requestId
*/
public static void releaseLock(String lockKey,String requestId) {if (requestId.equals(jedis.get(lockKey))) { //并发会有问题jedis.del(lockKey);}
}
问题:如果调用jedis.del()方法的时候,这把锁已经不属于当前客户端的时候会解除他人加的锁。
那么是否真的有这种场景?答案是肯定的,比如客户端A加锁,一段时间之后客户端A解锁,在执行jedis.del()之前,锁突然过期了,此时客户端B尝试加锁成功,然后客户端A再执行del()方法,则将客户端B的锁给解除了。
方式2 (redis+lua脚本实现)–推荐
public static boolean releaseLock(String lockKey, String requestId) {// 获取到你自己的锁,则删除 ('get', KEYS[1]) == ARGV[1]String script = "if redis.call('get', KEYS[1]) == ARGV[1] then returnredis.call('del', KEYS[1]) else return 0 end";Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));if (result.equals(1L)) {return true;}return false;
}
三、存在问题
单机
- 无法保证高可用
主–从
- 无法保证数据的强一致性,在主机宕机时会造成 锁的重复获得。(红锁方案解决)
无法续租
- 超过expireTime后,不能继续使用
四、本质分析
CAP模型分析
在分布式环境下不可能满足三者共存,只能满足其中的两者共存,在分布式下P不能舍弃(舍弃P就是单机了)。
所以只能是CP(强一致性模型)和AP(高可用模型)。
分布式锁是CP模型,Redis集群是AP模型。 (base)
Redis集群不能保证数据的随时一致性,只能保证数据的最终一致性。
为什么还可以用Redis实现分布式锁?
与业务有关
- 当业务 不需要数据强一致性 时,比如:社交场景,就可以使用Redis实现分布式锁
- 当业务必须要数据的强一致性,即不允许重复获得锁,比如金融场景( 重复下单,重复转账 )就不要使用,可以使用CP模型实现,比如:zookeeper和etcd。
Redis:分布式锁setnx(只 实现了 互斥性和容错性)相关推荐
- Redis分布式锁—SETNX+Lua脚本实现篇
前言 平时的工作中,由于生产环境中的项目是需要部署在多台服务器中的,所以经常会面临解决分布式场景下数据一致性的问题,那么就需要引入分布式锁来解决这一问题. 针对分布式锁的实现,目前比较常用的就如下几种 ...
- Redis 分布式锁笔记
Redis 分布式锁笔记 (公众号:水滴与银弹)深度剖析:Redis分布式锁到底安全吗? 一.初识分布式锁 1.什么是分布式锁 分布式环境下,我们在写多线程程序时,避免同时操作一个共享变量产生数据 ...
- 2022年Redis最新面试题- Redis分布式锁
最近整理一份关于Redis常见面试题的,也会根据自己的经验, 标注一些出现的概率,最高5颗★出现的概率最高.比如这样: Redis 最适合的场景, 可以简单的说说吗? 出现概率: ★★★★ 整体目录大 ...
- 集群部署中解决定时任务重复执行的问题-redis分布式锁应用
背景描述 有小伙伴私信我,关于存在定时任务的项目在集群环境下部署如何解决重复执行的问题,PS:定时任务没有单独拆分. 概述:之前的项目都是单机器部署,所以定时任务不会重复消费,只会执行一次.而在集群环 ...
- redis setnx 分布式锁_手写Redis分布式锁
分布式锁使用场景 现在的系统都是集群部署,每个服务都不是单节点的了.比如库存服务,可能部署到3台机器上分别命名为节点1,节点2,节点3.库存服务需要扣减库存,扣减库存肯定需要锁吧,如果使用Lock或者 ...
- 快来学习Redis 分布式锁的背后原理
以前在学校做小项目的时候,用到Redis,基本也只是用来当作缓存.可阿粉在工作中发现,Redis在生产中并不只是当作缓存这么简单.在阿粉接触到的项目中,Redis起到了一个分布式锁的作用,具体情况是这 ...
- Redis 分布式锁没这么简单,网上大多数都有 bug
Redis 分布式锁这个话题似乎烂大街了,不管你是面试还是工作,随处可见,「码哥」为啥还写? 因为看过很多文章没有将分布式锁的各种问题讲明白,所以准备写一篇,也当做自己的学习总结. 在进入正文之前,我 ...
- 深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!
阅读本文大约需要 20 分钟. 大家好,我是 Kaito. 这篇文章我想和你聊一聊,关于 Redis 分布式锁的「安全性」问题. Redis 分布式锁的话题,很多文章已经写烂了 ...
- **Java有哪些悲观锁的实现_80% 人不知道的 Redis 分布式锁的正确实现方式(Java 版)...
点击上方"小哈学Java",选择"星标" 回复"资源",领取全网最火的Java核心知识总结 来源:http://sina.lt/gfZU 前 ...
最新文章
- DBUnit使用介绍
- 路由异常的起源-如何影响最终用户?——Vecloud微云
- 【ROM修改教程】添加高级电源重启菜单(安卓4.0.4官方ROM)
- 台式电脑可以连接手机热点吗_移动硬盘可以连接手机吗
- spring管理的类如何调用非spring管理的类
- Python解决滑块验证,Scarpy框架采集数据到redis数据库!
- select, poll, epoll
- 奇瑞采用英伟达GPU,将实现L3自动驾驶
- 基于jQuery鼠标悬停上下滑动导航条
- 使用vue开发的网页游戏
- ipv6 ospf配置方法_思科路由器 RIP、OSPF、EIGRP 路由协议最简单的配置实例详解
- 客户价值模型:RFM
- XFtp - 显示隐藏的文件和文件夹
- Snapchat面经
- 2022-nc-Widespread increasing vegetation sensitivity to soil moisture
- stm32中的CAN通讯列表模式配置解析与源码
- K-means聚类算法的应用——Python数据工程No.5
- JMS入门(一)--JMS基础
- html discription 属性,@description
- 射影几何----射影坐标系下点(1,0,1)的位置