redis分布式锁篇

carney carney     2023-03-24     556

关键词:

18、什么是分布式锁?

概述:在分布式系统中,多个线程访问共享数据就会出现数据安全性的问题。而由于jdk中的锁要求多个线程在同一个jvm中,因此在分布式系统中无法使

用jdk中的锁保证数据的安全性,那么此时就需要使用分布式锁。

作用:可以保证在分布式系统中多个线程访问共享数据时数据的安全性

举例:

在电商系统中,用户在进行下单操作的时候需要扣减库存。为了提高下单操作的执行效率,此时需要将库存的数据存储到Redis中。订单服务每一次生成订

单之前需要查询一下库存数据,如果存在则生成订单同时扣减库存。在高并发场景下会存在多个订单服务操作Redis,此时就会出现线程安全问题。

分布式锁应该具备哪些条件:

1、在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行

2、高可用的获取锁与释放锁

3、高性能的获取锁与释放锁

4、具备可重入特性

5、具备锁失效机制,防止死锁

可重入特性:获取到锁的线程再次调用需要锁的方法的时候,不需要再次获取锁对象。
使用场景:遍历树形菜单的时候的递归调用。

注意:锁具备可重入性的主要目的是为了防止死锁。

19、分布式锁的实现方案都有哪些?(高频)

分布式锁的实现方案:

1、数据库

2、zookeeper

3、redis

20、Redis怎么实现分布式锁思路?(高频)

Redis实现分布式锁主要利用Redis的setnx命令。setnx是SET if not exists(如果不存在,则 SET)的简写。

127.0.0.1:6379> setnx lock value1 #在键lock不存在的情况下,将键key的值设置为value1
(integer) 1
127.0.0.1:6379> setnx lock value2 #试图覆盖lock的值,返回0表示失败
(integer) 0
127.0.0.1:6379> get lock #获取lock的值,验证没有被覆盖
"value1"
127.0.0.1:6379> del lock #删除lock的值,删除成功
(integer) 1
127.0.0.1:6379> setnx lock value2 #再使用setnx命令设置,返回0表示成功
(integer) 1
127.0.0.1:6379> get lock #获取lock的值,验证设置成功
"value2"

上面这几个命令就是最基本的用来完成分布式锁的命令。

加锁:使用setnx key value命令,如果key不存在,设置value(加锁成功)。如果已经存在lock(也就是有客户端持有锁了),则设置失败(加锁失败)。

解锁:使用del命令,通过删除键值释放锁。释放锁之后,其他客户端可以通过setnx命令进行加锁。

21、Redis实现分布式锁如何防止死锁现象?(高频)

产生死锁的原因:如果一个客户端持有锁的期间突然崩溃了,就会导致无法解锁,最后导致出现死锁的现象。

所以要有个超时的机制,在设置key的值时,需要加上有效时间,如果有效时间过期了,就会自动失效,就不会出现死锁。

 

然后加锁的代码就会变成这样。

// 加锁的代码
// requestId描述请求的唯一性,哪一个线程加锁了在解锁的时候就需要使用哪一个线程
public static boolean tryLock(Jedis jedis , String key, String requestId , int expireTime)
SetParams setParams = new SetParams();
setParams.nx() ;
setParams.ex(expireTime) ;
return "OK".equalsIgnoreCase(jedis.set(key , requestId , setParams)); // 不存则保存成功返回的是OK

22、Redis实现分布式锁如何合理的控制锁的有效时长?(高频)

有效时间设置多长,假如我的业务操作比有效时间长?我的业务代码还没执行完就自动给我解锁了,不就完蛋了吗。

解决方案:

1、第一种:程序员自己去把握,预估一下业务代码需要执行的时间,然后设置有效期时间比执行时间长一些,保证不会因为自动解锁影响到客户端业务代

码的执行。

2、第二种:给锁续期。

锁续期实现思路:当加锁成功后,同时开启守护线程,默认有效期是用户所设置的,然后每隔10秒就会给锁续期到用户所设置的有效期,只要持有锁的客

户端没有宕机,就能保证一直持有锁,直到业务代码执行完毕由客户端自己解锁,如果宕机了自然就在有效期失效后自动解锁。

上述的第二种解决方案可以使用redis官方所提供的Redisson进行实现。

Redisson是Redis官方推荐的Java版的Redis客户端。它提供的功能非常多,也非常强大分布式服务,使用Redisson可以轻松的实现分布式锁。Redisson

中进行锁续期的这种机制被称为"看门狗"机制。

redission支持4种连接redis方式,分别为单机、主从、Sentinel、Cluster 集群。

23、Redis实现分布式锁如何保证锁服务的高可用?(高频)

解决方案:

1、使用Redis的哨兵模式构建一个主从架构的Redis集群

2、使用Redis Cluster集群

24、当同步锁数据到从节点之前,主节点宕机了导致锁失效,那么此时其他线程就可以再次获取到锁,这个问题怎么解决?(高频)

使用Redission框架中的RedLock进行处理。

RedLock的方案基于2个前提:

1、不再需要部署从库和哨兵实例,只部署主库

2、但主库要部署多个,官方推荐至少5个实例

也就是说,想使用RedLock,你至少要部署5个Redis实例,而且都是主库,它们之间没有任何关系,都是一个个孤立的实例。

工作流程如下所示:

1、客户端先获取【当前时间戳T1】

2、客户端依次向这个5个Redis实例发起加锁请求,且每个请求会设置超时时间(毫秒级,要远小于锁的有效时间),如果某一个实例加锁失败(包括网络超

时,锁被其他的人持有等各种异常情况),就立即向下一个Redis实例申请加锁

3、如果客户端从 >=3 个(大多数)以上Redis实例加锁成功,则再次获取【当前时间戳T2】, 如果 T2 - T1 < 锁的过期时间,此时,认为客户端加锁成功,

否则加锁失败

4、加锁成功,去操作共享资源

5、加锁失败,向【全部节点】发起释放锁请求

总结4个重点:

1、客户端在多个Redis实例上申请加锁

2、必须保证大多数节点加锁成功

3、大多数节点加锁的总耗时,要小于锁设置的过期时间

4、锁释放,要向全部节点发起释放锁请求

24.1 为什么要在多个实例上加锁?

本质上是为了【容错】, 部分实例异常宕机,剩余的实例加锁成功,整个锁服务依旧可用。

 

 

 

 

 

 

 

 

 

java并发-显式锁篇可重入锁+读写锁(代码片段)

作者:汤圆个人博客:javalover.cc前言在前面并发的开篇,我们介绍过内置锁synchronized;这节我们再介绍下显式锁Lock显式锁包括:可重入锁ReentrantLock、读写锁ReadWriteLock关系如下所示:简介显式锁和内置锁最... 查看详情

智能锁百问百答视频锁篇第2期:视频锁可以和智能家居联动吗

【智能锁百问百答】视频锁篇第1期(点击链接访问)推出后,获得广大读者热烈反响,本次推出第2期7个问题,欢迎广大读者朋友提出宝贵意见。⑧ 视频锁的对讲通话是实时的吗?传统的单向对讲实时性... 查看详情

redis实战-redis分布式篇(上)

本文主要讲解Redis分布式篇(上),帮助大家打好Redis基础。——continue 查看详情

redis实战-redis分布式篇(下)

本文主要讲解Redis分布式篇(下),帮助大家打好Redis基础。——continue 查看详情

「智能锁百问百答」视频锁篇第1期:什么是视频锁?……

编者按为了推动智能锁普及,2018年9月18日,智哪儿面向智能锁行业首度推出了「 智能锁百问百答」,至2019年5月13日第10期收宫,共推出了10期100个问答,在行业内引起很大反响,被很多智能锁企业、智能... 查看详情

redis--springboot实现redis的分布式锁

目录1.redis的应用场景2.redis的分布式锁3.通过redisson框架实现redis分布式锁1.redis的应用场景商品秒杀点赞等现在有一个减少商品的场景,我们很容易能写出其代码@Controller@ResponseBodypublicclassTest{@AutowiredprivateStringRedisTemplateredisTemplate;... 查看详情

redis分布式工具类----redisshardedpoolutil

这个是redis分布式的工具类,看非分布式的看  这里说一下redis的分布式,分布式,无疑,肯定不是一台redis服务器。假如说,我们有两台redis服务器,一个6379端口,一个6380端口。那么,我们存储一个数据,他会存在哪个re... 查看详情

redis分布式锁(代码片段)

1.概述分布式锁一般有三种实现方式:1.基于数据库实现分布式锁;2. 基于缓存(Redis,memcached,tair)实现分布式锁;3.基于Zookeeper实现分布式锁。本片博客将介绍基于缓存实现分布式锁,这里主讲分别针对Redis2.6.12之前版本... 查看详情

v80.01鸿蒙内核源码分析(内核态锁篇)|如何实现快锁futex(下)|百篇博客分析openharmony源码

百篇博客分析|本篇为:(内核态锁篇)|如何实现快锁Futex(下)进程通讯相关篇为:v26.08鸿蒙内核源码分析(自旋锁)|当立贞节牌坊的好同志v27.05鸿蒙内核源码分析(互斥锁)|同样是锁它却更丰满v28.04鸿蒙内核源码分析(进程通讯)|九种进... 查看详情

v79.01鸿蒙内核源码分析(用户态锁篇)|如何使用快锁futex(上)|百篇博客分析openharmony源码

百篇博客分析|本篇为:(用户态锁篇)|如何使用快锁Futex(上)进程通讯相关篇为:v26.08鸿蒙内核源码分析(自旋锁)|当立贞节牌坊的好同志v27.05鸿蒙内核源码分析(互斥锁)|同样是锁它却更丰满v28.04鸿蒙内核源码分析(进程通讯)|九种进... 查看详情

[redis]基于redis的分布式锁

前言分布式锁一般有三种实现方式:1.数据库乐观锁;2.基于Redis的分布式锁;3.基于ZooKeeper的分布式锁。本篇博客将介绍第二种方式,基于Redis实现分布式锁。可靠性首先,为了确保分布式锁可用,我们至少要确保锁的实现同时... 查看详情

php+redis+lua实现redis分布式锁(代码片段)

阅读目录效果预览Redis申请分布式锁的命令,此命令符合原子性源码效果预览分别执行,具体执行结果:<?php//申请分布式锁$obj=newlocks();//执行完成申请解锁if($obj 查看详情

v80.01鸿蒙内核源码分析(内核态锁篇)|如何实现快锁futex(下)|百篇博客分析openharmony源码

百篇博客分析|本篇为:(内核态锁篇)|如何实现快锁Futex(下)进程通讯相关篇为:v26.08鸿蒙内核源码分析(自旋锁)|当立贞节牌坊的好同志v27.05鸿蒙内核源码分析(互斥锁)|同样是锁它却更丰满v28.04鸿蒙内核源码分析(进程通讯)|九种进... 查看详情

springboot集成redis分布式锁以及redis缓存

https://blog.csdn.net/qq_26525215/article/details/79182687集成Redis首先在pom.xml中加入需要的redis依赖和缓存依赖<!--引入redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifact 查看详情

redis笔记整理:javaapi使用与redis分布式集群环境搭建

[TOC]Redis笔记整理(二):JavaAPI使用与Redis分布式集群环境搭建RedisJavaAPI使用(一):单机版本RedisAPI使用Redis的JavaAPI通过Jedis来进行操作,因此首先需要Jedis的第三方库,因为使用的是Maven工程,所以先给出Jedis的依赖:<dependenc... 查看详情

redis个人笔记:redis应用场景,redis常见命令,reids缓存击穿穿透,redis分布式锁实现方案,秒杀设计思路,redis消息队列,reids持久化,redis主从哨兵分片集群

...,Redis应用场景,Redis常见命令,Reids缓存击穿穿透,Redis分布式锁实现方案,秒杀设计思路,Redis消息队列,Reids持久化,Redis主从哨兵分片集群Redis常见数据结构及高级数据结构使用场景,Redis应用场景,Redis常见命令,Reids缓存... 查看详情

死磕java同步系列之redis分布式锁进化史

问题(1)redis如何实现分布式锁?(2)redis分布式锁有哪些优点?(3)redis分布式锁有哪些缺点?(4)redis实现分布式锁有没有现成的轮子可以使用?简介Redis(全称:RemoteDictionaryServer远程字典服务)是一个开源的使用ANSIC语言... 查看详情

redis教程-----redis事务记录日志到redis分布式锁(代码片段)

redis事务Redis事务可以一次执行多个命令,并且带有以下两个重要的保证:批量操作在发送EXEC命令前被放入队列缓存。收到EXEC命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。在事务执行过程,其他客户... 查看详情