Redisson 实现分布式锁

雨点打透心脏的1/2处 2022-11-21 04:14 282阅读 0赞

前言

Redis对于我们来说并不陌生,它是线程安全的(单线程),单机redis支撑万级,超过十万+级别并发量就需要用的Redis集群了。然而虽然并发量提升了同时也会有另外的问题,那就是数据不一致问题,这个时候我们就可以用的分布式锁,而Redisson已经帮我们实现好了,我们只要引入Redisson Jar包就行。

介绍

Redisson 不只是一个 Java Redis 客户端,它是一个以内存 Redis 服务器作为后端的处理 Java 对象 (如 java.util.List, java.util.Map, java.util.Set, java.util.concurrent.locks.Lock 等)的一个框架。

咱们这篇文章就来聊聊分布式锁这块知识,具体的来看看Redis分布式锁的实现原理。

一、要实现分布式锁需要满足那些前提条件呢

1、互斥

在高并发环境下,同一时刻只能有一个线程持有锁,这是最基本的条件

2、防止死锁

持有锁的线程发生故障或因为其他原因无法释放锁的时候,会导致其他线程都无法获得锁,从而造成死锁。这个时候我们很有必要设置锁的超时时间。确保故障期间能第一时间去释放锁,可以有效的防止死锁。

3、可重入

我们都知道ReentrantLock是可重入锁,它的特点就是:同一线程可以重复使用资源锁,有利于资源的高效利用。

二、Redisson 的原理分析

下面给大家看一段简单的使用代码片段,先直观的感受一下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMDM3NDc4_size_16_color_FFFFFF_t_70

看到了吗,是不是很简单,接下来我们进去看一下实现原理。

为了更直观的理解,我画了张原理图

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMDM3NDc4_size_16_color_FFFFFF_t_70 1

守护线程:有些业务逻辑处理可能不止30秒,这时我们可以开启个守护线程去扫描,如果持有锁的线程快到达超时时间,就主动去延长超时时间。

lua脚本

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMDM3NDc4_size_16_color_FFFFFF_t_70 2

Lua是一个高效的轻量级脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能

优点:

  1. 减少网络开销,在Lua脚本中可以把多个命令放在同一个脚本中运行
  2. 原子操作,redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。换句话说,编写脚本的过程中无需担心会出现竞态条件
  3. 复用性,客户端发送的脚本会永远存储在redis中,这意味着其他客户端可以复用这一脚本来完成同样的逻辑

lua脚本参数意思

KEYS[1]代表的是你加锁的那个key,比如说:RLock lock = redisson.getLock(“myLock”); 加锁的那个锁key就是“myLock”

ARGV[1]代表的就是锁key的默认生存时间,默认30秒。

ARGV[2]代表的是加锁的客户端的ID,数据类型为Hash类型相当于我们java的 <key,<key1,value>>

  1. myLock:{ "8743c9c0-0795-4907-87fd-6c719a6b4586:1" : 1 }

前面这串字符串对应意思 :myLock是锁key :{ guid(唯一标识符):” 当前线程的id ” :锁重入次数 }

这就是Redisson**分布式锁框架的实现机制。**一般我们在生产系统中,可以用Redisson框架提供的这个类库来基于redis进行分布式锁的加锁与释放锁。

发表评论

表情:
评论列表 (有 0 条评论,282人围观)

还没有评论,来说两句吧...

相关阅读

    相关 分布式Redisson实现

    分布式锁相信大家都已经听过了,常见的方案呢,也就那么几种,今天我们来讲讲使用Redisson框架来实现redis的分布式锁 那么第一个问题来了,为什么不直接使用redis,而