分布式锁的实现方式 - redis

场景:项目要从单实例变为多实例部署了,从而引入了一个问题,就是定时任务会多次执行(没一个实例都会执行一次)。为了解决这个问题,就要使用到分布式锁。

使用哪一种方式实现分布式锁

分布式锁的实现有多种:

  • 第一种:使用数据库,当要上锁时想数据库中添加一条数据,释放锁时删除数据即可。这种方式要维护一张存放锁状态的表。而且性能不好,不推荐使用。
  • 第二种:使用 zookeeper 来实现,zookeeper 是分布式协调服务,它的数据是以节点的方式存储,节点操作是原子性的。当我们要上锁时,添加一个临时节点,释放锁时删除这个节点。
  • 第三种:使用 redis 来实现。redis 中的 SETNX 命令是原子性的,命令可以尝试将一个指定的键设置为某个值,只有当该键不存在时才能设置成功。

因为我在项目中没有使用到 zookeeper ,所以不用为了实现分布式锁而去部署一套 zookeeper。 而数据库方式有性能问题,最终选择了使用 redis 方式实现。

创建 RedisDistributedLock 工具类

SpringBoot项目使用的 redisTemplate 来操作 redis,具体代码如下:

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

@Component
public class RedisDistributedLock {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public boolean lock(String lockKey, String lockValue, long expireTime) {
        return redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue,expireTime, TimeUnit.MILLISECONDS);
    }


    public void unLock(String lockKey, String lockValue) {
        String currentValue = redisTemplate.opsForValue().get(lockKey);
        if (currentValue != null && currentValue.equals(lockValue)) {
            String luaScript = "if redis.call('get', KEYS[1]) then return redis.call('del', KEYS[1]) else return 0 end";
            RedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class);
            redisTemplate.execute(redisScript, Collections.singletonList(lockKey));
        }
    }
}

lock 方法中的 lockKey 为锁的对象,lockValue 是为释放锁时会用到,防止释放了别人的锁,expireTime 是为了防止死锁。

unlock 方法中使用了 lua 脚本,确保正确的释放锁。

END

PS:欢迎大家关注我的公众号 小城边AI,直接搜索即可添加,可以体验AI问答,持续为大家推送相关优质技术文,共同进步,一起加油~

个人导航网站:小城边-个人导航 (gitee.io)

相关推荐
国科安芯3 小时前
低轨卫星姿态与轨道控制系统中高可靠MCU的选型研究——基于AS32S601的抗辐照性能试验数据分析
分布式·科技·单片机·嵌入式硬件·系统架构
ningmengjing_4 小时前
Redis 从入门到实战:Python操作全攻略
数据库·redis·python
谢白羽5 小时前
SGLang源码剖析-2-sglang双层体系架构全景
分布式·架构·llm·vllm·sglang
霸道流氓气质10 小时前
分布式锁 — 概念、原理与实践
分布式
杰佛史彦明 本王是暴君10 小时前
分布式日志收集系统: Facebook Scribe
分布式·facebook
JHC00000011 小时前
基于 DrissionPage 与 Xvfb 的分布式无头爬虫架构
分布式·kafka
梦云莓铃 脚后跟法11 小时前
结合领域驱动设计的SOA分布式软件架构
分布式
zcmodeltech12 小时前
火电厂模型多设备时序控制系统设计:基于STM32与Modbus RTU的燃煤-燃机全流程联动方案
分布式·stm32·单片机·嵌入式硬件·物联网
一嘴一个橘子12 小时前
Redis List 数据类型
redis
小园子的小菜13 小时前
Redis 核心原理深度解析:从数据结构、IO 模型到持久化机制
数据库·redis·缓存