分布式锁的实现方式 - 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)

相关推荐
AI木马人3 小时前
9.【AI任务队列实战】如何在高并发下保证系统不崩?(Redis + Celery完整方案)
数据库·人工智能·redis·神经网络·缓存
aLTttY3 小时前
【Redis实战】分布式锁的N种实现方案对比与避坑指南
数据库·redis·分布式
CyrusCJA11 小时前
在Windows系统上将Redis注册为系统服务使其实现开机自启
数据库·windows·redis·缓存
小江的记录本13 小时前
【微服务与云原生架构】DevOps、CI/CD流水线、GitOps 系统性知识体系
分布式·后端·ci/cd·微服务·云原生·架构·devops
许愿OvO13 小时前
Redis 7.4.8高可用集群实战:主从复制+哨兵+Cluster全解析
数据库·redis·bootstrap
2603_9547083114 小时前
微电网混合控制架构:主从与对等控制的优势融合
分布式·安全·架构·能源·需求分析
zhangzeyuaaa15 小时前
Python多进程同步与共享内存完全指南:从Lock到分布式共享
开发语言·分布式·python
aini_lovee15 小时前
多智能体点对点转换的分布式模型预测控制(DMPC)
分布式
_F_y15 小时前
仿RabbitMQ实现消息队列-项目设计
分布式·rabbitmq
逆境不可逃16 小时前
一篇速通Redis 从原理到Java实战(含缓存问题解决方案+集群配置)
数据库·redis·缓存