Redis实现分布式锁的原理

一、为什么需要分布式锁

分布式系统 中,多个节点或服务实例可能同时修改同一份共享资源(例如数据库、库存、订单),

为防止并发修改、超卖、数据不一致 ,我们需要一种 跨节点的"互斥"机制

在单机中可用 synchronizedReentrantLock

但在多机(分布式)环境下,它们无法保证互斥性。

这时就需要分布式锁


⚙️ 二、Redis 分布式锁的基本原理

Redis 本身是一个单线程 、支持原子操作的 KV 数据库,非常适合实现分布式锁。

核心思想:

使用 Redis 的原子命令 SETNX(Set if Not Exists)

  • 过期时间(防止死锁)
    来确保在分布式环境中,同一时刻只有一个客户端能获得锁

🔑 三、最常见的实现方式(单节点版本)

🧠 思路:

  1. 加锁 :使用 SET key value NX PX expireTime

    • NX:只有 key 不存在时才能设置成功(防止被覆盖)
    • PX:设置过期时间(毫秒)
  2. 释放锁:只有锁的持有者才能删除锁(防止误删)

🔑 四、 Redisson 高级实现(推荐)

Redisson 是官方推荐的 Java Redis 客户端之一,封装了稳定的分布式锁逻辑

Redisson 实现了:

  • 自动续期机制(Watchdog)
  • 支持 RedLock 多节点锁算法
  • 防止主从切换导致锁丢失

RedLock 的基本思想

假设有 5 个独立的 Redis 节点(N = 5),RedLock 的核心流程是:

  1. 客户端向所有 Redis 节点尝试获取锁**,每个节点的锁具有 唯一标识(UUID)过期时间(TTL)

  2. 获取锁成功的条件:

    • 客户端在多数节点(> N/2,比如至少3个节点) 成功获取到锁。
    • 并且总耗时 < TTL
  3. 业务执行完毕释放锁:

    • 客户端向获取成功的 Redis 节点发送解锁请求。
    • 每个节点只删除与自己 UUID 匹配的锁,保证安全释放。
  4. 如果获取锁失败(未超过多数节点或超时),回滚已获取的锁

js 复制代码
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

public class RedissonManager {

    private static RedissonClient redissonClient;

    static {
        Config config = new Config();
        // Redis 集群模式配置
        config.useClusterServers()
              .addNodeAddress("redis://127.0.0.1:7000", "redis://127.0.0.1:7001", "redis://127.0.0.1:7002");
        redissonClient = Redisson.create(config);
    }

    public static RedissonClient getClient() {
        return redissonClient;
    }
}
js 复制代码
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.concurrent.TimeUnit;

public class DistributedLockExample {

    public static void main(String[] args) {
        RedissonClient redisson = RedissonManager.getClient();

        // 获取锁对象
        RLock lock = redisson.getLock("myLock");

        try {
            // 尝试加锁,最多等待3秒,锁超时10秒自动释放
            boolean isLocked = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if (isLocked) {
                try {
                    // 加锁成功,执行业务逻辑
                    System.out.println("获得锁,执行业务逻辑");
                    Thread.sleep(5000); // 模拟业务操作
                } finally {
                    lock.unlock(); // 释放锁
                    System.out.println("释放锁");
                }
            } else {
                System.out.println("获取锁失败,其他线程在执行");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
相关推荐
幽络源小助理37 分钟前
springboot校园车辆管理系统源码 – SpringBoot+Vue项目免费下载 | 幽络源
vue.js·spring boot·后端
刀法如飞39 分钟前
一款开箱即用的Spring Boot 4 DDD工程脚手架
java·后端·架构
uzong1 小时前
后端系统设计文档模板
后端
幽络源小助理1 小时前
SpringBoot+Vue车票管理系统源码下载 – 幽络源免费项目实战代码
vue.js·spring boot·后端
uzong1 小时前
软件架构指南 Software Architecture Guide
后端
又是忙碌的一天1 小时前
SpringBoot 创建及登录、拦截器
java·spring boot·后端
勇哥java实战分享2 小时前
短信平台 Pro 版本 ,比开源版本更强大
后端
学历真的很重要3 小时前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
计算机毕设VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue二手家电管理系统(源码+数据库+文档)
vue.js·spring boot·后端·课程设计
上进小菜猪3 小时前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端