《知识点扫盲 · Redis 分布式锁》

news2024/11/15 11:09:08

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

    • CSDN.gif
    • 技术简介
    • 示例说明
    • 总结陈词

CSDN.gif

技术简介

Redis 分布式锁是一种利用 Redis 的特性来实现的分布式锁机制,主要用于解决在分布式系统中多个实例对共享资源的并发访问问题。通过使用 Redis 作为锁的存储介质,可以确保在多个服务实例之间的互斥访问。
Redis 分布式锁的基本原理:

  • 加锁:通过 SETNX 命令,尝试设置一个锁的键。如果设置成功,表示获得锁;如果失败,表示锁已经被其他实例持有。
  • 设置过期时间:为了防止死锁,通常在加锁时会设置一个过期时间,确保即使持锁的实例崩溃,锁也会在一定时间后自动释放。
  • 解锁:在完成对共享资源的操作后,释放锁。解锁时需要确保只有持有锁的实例才能解锁,通常通过比较锁的值来实现。

Redis 分布式锁的注意事项:

  1. 锁过期时间: 设置合理的锁过期时间,避免死锁。
  2. 释放: 确保在使用完锁后及时释放锁,避免资源浪费。
  3. 重入锁: 如果需要同一个线程多次获取锁,可以使用可重入锁。
  4. 公平锁: 如果需要按照请求顺序分配锁,可以使用公平锁
  5. 锁竞争: 在高并发场景下,可能会出现锁竞争,需要考虑如何处理锁竞争。

示例说明

编写工具类 RedisLockUtil,代码如下:

public class RedisLockUtil {

    public static final String LOCK_KEY_PREFIX = "lock:";
    private static final String UNLOCK_LUA_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    private static final RedisScript<Long> UNLOCK_REDIS_SCRIPT = new DefaultRedisScript<>(UNLOCK_LUA_SCRIPT, Long.class);

    /**
     * 尝试Redis锁
     *
     * @param lockKey  锁名称
     * @param lockId   锁持有者唯一ID
     * @param duration 过期时间(过期自动释放锁)
     * @param timeUnit 时间单位
     * @return true: 获取锁成功 , false: 获取锁失败
     */
    public static boolean tryLock(@NonNull String lockKey, @NonNull String lockId, long duration, @NonNull TimeUnit timeUnit) {
        return RedisUtil.setIfAbsent(LOCK_KEY_PREFIX.concat(lockKey), lockId, duration, timeUnit);
    }

    /**
     * 释放Redis锁
     *
     * @param lockKey 锁名称
     * @param lockId  锁持有者唯一ID
     */
    public static boolean unlock(@NonNull String lockKey, @NonNull String lockId) {
        Object result = RedisUtil.getRedisTemplate().execute(UNLOCK_REDIS_SCRIPT, Collections.singletonList(LOCK_KEY_PREFIX.concat(lockKey)), lockId);
        return Long.valueOf(1).equals(result);
    }
}

核心工具类逻辑:

/**
 * 仅在Redis中键不存在时设置键的值并设置过期时间。
 *
 * @param redisKey Redis中的键。
 * @param value    要设置的值。
 * @param expire   键的过期时间。
 * @param timeUnit 过期时间的时间单位。
 * @return 如果成功设置了键值对,则返回true,否则返回false。
 */
public static boolean setIfAbsent(@NonNull String redisKey, Object value, long expire, TimeUnit timeUnit) {
    return checkBool(getRedisTemplate().opsForValue()
            .setIfAbsent(redisKey, value, expire, timeUnit));
}

使用示例:

    public void doSomething() {
        // 分布式锁标识,根据该标识进行加锁和解锁
        String lockKey = "myLockKey";
        // 随机ID,解锁时用于校验
        String lockId = UUID.randomUUID().toString();
        try {
            // 创建一个60秒后自动过期的锁. 返回true: 获取锁成功,返回false:获取锁失败(开发者自行决定获取锁失败时处理方案)
            boolean status = RedisLockUtil.tryLock(lockKey, lockId, 60, TimeUnit.SECONDS);
            // 获取锁失败
            if (!status) {
                // 执行获取锁失败的业务处理逻辑
                throw ApiException.createEx(ExceptionCodeEnum.REDIS_TRY_GET_LOCK_FAILURE, lockKey);
            }
            // 执行获取锁成功后的业务逻辑
            // ...
        } finally {
            // 解锁状态,true:解锁成功,false:解锁失败
            boolean unlockStatus = RedisLockUtil.unlock(lockKey, lockId);
            if (!unlockStatus) {
                log.error("[Redis分布式锁] 解锁失败, lockKey={}, lockId={}", lockKey, lockId);
            }
        }
    }


总结陈词

此篇文章介绍了 Redis 分布式的基础应用,仅供学习参考。
Redis 分布式锁是一种简单高效的实现分布式锁的方案,可以有效解决分布式系统中数据冲突问题。选择合适的实现方法,注意相关注意事项,可以确保锁的可靠性和性能。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。

CSDN_END.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1993980.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库索引设计原则

1. 概述 索引是优化数据库性能最重要的工具之一。但是&#xff0c;创建过多的索引或索引错误的列也会对性能产生负面影响。因此&#xff0c;在设计索引时遵循一定的原则很重要。 2. 原则A - 根据工作负载创建索引 创建高效索引最重要的原则是根据您的工作负载而不是表结构创…

数据库连接池的深入学习

为什么需要数据库连接池&#xff1f; 正常操作数据库需要对其进行连接&#xff0c;访问数据库&#xff0c;执行sql语句&#xff0c;断开连接。 创建数据库连接是一个昂贵的过程&#xff0c;在高并发的情况下&#xff0c;频繁的创建数据库的连接可能会导致数据库宕机。 有了连…

Leetcode JAVA刷刷站(8)字符串转换整数

一、题目概述 二、思路方向 要实现这个功能&#xff0c;我们可以遵循以下步骤来编写 myAtoi 函数&#xff1a; 去除前导空格&#xff1a;使用循环或字符串的 trim() 方法&#xff08;虽然直接操作字符串更高效的方式是使用循环&#xff09;。检查符号&#xff1a;记录第一个非…

TGANet部分复现

Kvasir-SEG复现结果 M e t h o d m I o U m D S C R e c a l l P r e c i s i o n F 2 P r a N e t − − − − − − 0.9663704860609511 − − T G A N e t 0.8331 0.8982 0.9132 − − 0.9029 \begin{array}{lccccr} Method&mIoU&mDSC&Recall&Precision&a…

5、Linux : 网络相关

OSI七层网络模型 TCP/IP四层 概念模型 对应网络协议 应用层&#xff08;Application&#xff09; HTTP、TFTP, FTP, NFS, WAIS、 表示层&#xff08;Presentation&#xff09; 应用层 Telnet, Rlogin, SNMP, Gopher 会话层&#xff08;Session&#xff09; SMTP…

ICETEK-DM6437-AICOM——CPU定时器及直流电机控制中断控制

一、设计目的&#xff1a; 1.1 CPU定时器程序设计&#xff1b; 1.2 2直流电机程序设计&#xff1b; 1.3 外中断。 二、设计原理&#xff1a; 2.1 定时器的控制&#xff1a; 在DM6437&#xff08;是一种数字信号处理器&#xff0c;DSP&#xff09;上使用其内部定时器和中断来…

设计模式-动态代理模式

目录 什么是代理模式&#xff1f; 为什么要用代理模式&#xff1f; 有哪几种代理模式&#xff1f; 动态代理&#xff08;jdk自带&#xff09;&#xff1a; 动态代理&#xff08;第三方库-cglib&#xff09;&#xff1a; 什么是代理模式&#xff1f; 代理模式给某一个对象提供…

Windows10不能直接拖拽文件到微信或者钉钉的解决办法【玖毅网】

不知道从何时起,微信、QQ和钉钉等相关软件,无法拖拽文件到对话窗口,拖拽的时候显示一个红色图标,可能是上次更新win之后导致的,所以嘛,系统真的不能设置自动更新,说不准哪些更新就把原设置覆盖或者关闭了,哎,吃一堑长一智吧,赶紧关闭自动更新,emmmm我在说我自己啊。…

日撸Java三百行(day17:链队列)

目录 一、队列基础知识 1.队列的概念 2.队列的实现 二、代码实现 1.链队列创建 2.链队列遍历 3.入队 4.出队 5.数据测试 6.完整的程序代码 总结 一、队列基础知识 1.队列的概念 今天我们继续学习另一个常见的数据结构——队列。和栈一样&#xff0c;队列也是一种操…

零基础5分钟上手谷歌云GCP核心云开发技能 - 利用语音AI服务搭建应用

简介&#xff1a; 欢迎来到小李哥全新谷歌云GCP云计算知识学习系列&#xff0c;适用于任何无云计算或者谷歌云技术背景的开发者&#xff0c;让大家零基础5分钟通过这篇文章就能完全学会谷歌云一个经典的服务开发架构方案。 我将每天介绍一个基于全球三大云计算平台&#xff0…

arcgis(shp)注记转CAD(dwg)文字

arcgis&#xff08;shp&#xff09;注记转CAD&#xff08;dwg&#xff09;文字方法如下&#xff1a; 1、添加shp文件&#xff0c;标注要素&#xff0c;然后选标注转注记 2、 点击文件夹图标打开文件夹&#xff0c;选择保存路径。&#xff08;提前需新建好文件地理数据库、数据…

Arm Linux 设置系统日期时间的方法

一、设置系统日期时间的方法 1.命令行工具 date 命令&#xff1a;是Linux系统中用于查看和设置系统时间的常用命令行工具。通过date -s选项&#xff0c;可以手动设置系统时间。 sudo date -s "YYYY-MM-DD HH:MM:SS"hwclock 命令&#xff1a;用于查询和设置硬件时钟…

8月8日复习内容(基础的文件IO操作)

man手册 主要分为以下几个章节&#xff1a; User Commands&#xff08;用户命令&#xff09;&#xff1a;这一章节包含了普通用户&#xff08;非root用户&#xff09;可以执行的命令。这些命令通常用于日常的文件管理、文本编辑、程序执行等任务。 System Calls&#xff08;系…

【JavaEE初阶】常见的锁策略及synchronized实现原理

目录 &#x1f333; 常见的锁策略 &#x1f6a9; 乐观锁 vs 悲观锁 &#x1f6a9; 重量级锁 vs 轻量级锁 &#x1f6a9; 自旋锁 vs 挂起等待锁 &#x1f6a9; 可重入锁 vs 不可重入锁 &#x1f6a9; 公平锁 vs 非公平锁 &#x1f6a9; 互斥锁 vs 读写锁 &#x1f384; …

2024年8月8日(python基础)

一、检查并配置python环境&#xff08;python2内置&#xff09; 1、检测是否安装 [rootlocalhost ~]# yum list installed| grep python [rootlocalhost ~]# yum -y install epel-release 2、安装python3 [rootlocalhost ~]# yum -y install python3 最新版3.12可以使用源码安…

数据结构.

1:基本大纲 数据结构、算法线性表&#xff1a;顺序表、链表、栈、队列树&#xff1a;二叉树、遍历、创建查询方法、排序方式 2:数据结构&#xff08;逻辑结构&#xff0c;存储结构&#xff0c;操作&#xff08;数据的运算&#xff09;&#xff09; 2.1&#xff1a;数据&#xf…

RabbitMQ面试题汇总

RabbitMQ面试题 一、RabbitMQ基础1. 什么是RabbitMQ&#xff0c;它的基本架构是怎样的&#xff1f;2. RabbitMQ支持哪些协议&#xff1f;3. 说一下AMQP协议&#xff1f;4. 为什么要使用RabbitMQ&#xff1f;5. MQ的应用场景有哪些&#xff1f;6. 解耦、异步、削峰是什么&#x…

【Linux之·工程构建·Cmake】

系列文章目录 文章目录 前言一、概述二、CMake的基本概念2.1 CMake的工作原理和基本组成部分2.2 CMakeLists.txt文件的结构和语法2.2.1 变量操作2.2.2 注释2.2.3 日志2.2.4 宏定义 2.3 CMakeLists.txt文件的作用 三、CMake的常用命令和变量3.1 常用的CMake命令和变量3.1.1 字符…

多尺度病理图像纹理特征作为肺腺癌预后预测的新指标|文献精读·24-08-09

小罗碎碎念 这一期推文分享的文献是2022年发表于 Journal of Translational Medicine 的一篇文章&#xff0c;目前IF6.1。 这篇文章值得刚入门病理AI领域的老师/同学仔细研读&#xff0c;因为思路清晰&#xff0c;该讲到的流程基本都涉及了&#xff0c;详细讲述了病理图像的各种…

PyTorch基于深度神经网络的语音情绪识别

【图书推荐】《PyTorch语音识别实战》-CSDN博客 《PyTorch语音识别实战&#xff08;人工智能技术丛书&#xff09;》(王晓华)【摘要 书评 试读】- 京东图书 (jd.com) 情绪数据的获取与标签的说明 首先是语音情绪数据集的下载&#xff0c;在这里使用瑞尔森情感语音和歌曲视听数…