Redis进阶:分布式锁问题

这篇具有很好参考价值的文章主要介绍了Redis进阶:分布式锁问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 分布式锁问题

1.1 问题介绍

  • 单机单体中的锁机制在分布式集群系统中失效;
  • 单纯的Java API并不能提供分布式锁的能力,为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问;

1.2 解决方案

1.2.1 分布式锁主流的实现方案

  • 基于数据库实现分布式锁;
  • 基于缓存(Redis等),性能最高
  • 基于Zookeeper,可靠性最高;

1.2.2 使用Redis实现分布式锁

Redis进阶:分布式锁问题

  • 使用set命令添加一个mutex key,同时为该key设置过时时间,并要求该key存在时无法更新数据
  • 通过set命令设置的mutex key即为分布式锁,在该key过时或被删除以前,此key无法被其他请求获取到;
  • 具体可通过set mutex_key uuid nx ex 过期时间进行加锁,其中mutex_key为锁名,value为一唯一值,过期时间以秒为单位;
  • 可通过del mutex_key 手动释放锁,但缺乏原子性,可通过lua脚本进行删除保证操作原子性
    Redis进阶:分布式锁问题
  • set命令中使用UUID做value是为了解决该问题:当前服务器可能释放其他服务器的锁,而自身的锁也可能被其他服务器释放
  • UUID是一个唯一值,用于标识不同的服务器;

Redis进阶:分布式锁问题
Redis进阶:分布式锁问题文章来源地址https://www.toymoban.com/news/detail-474162.html

1.2.3 分布式锁需要满足的四个条件

  • 互斥性:在任意时刻,只有一个客户端能持有锁;
  • 不会发生死锁:即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁;
  • 解铃还须系铃人:加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了;
  • 加锁和解锁必须具有原子性

1.3 实现分布式锁

  • 基于SpringBoot框架,常用配置参考https://springdoc.cn/spring-boot/application-properties.html#application-properties.data.spring.data.redis.cluster.nodes;
  • 代码:
    // 分布式锁测试
    @RequestMapping("/lockTest")
    public void lockTest(){
        String uuid= UUID.randomUUID().toString();
        // 获取锁
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 10, TimeUnit.SECONDS);
        // 成功获取锁
        if (lock){
            // 逻辑业务
            Object value = redisTemplate.opsForValue().get("num");
            if(StringUtils.isEmpty(value)){
                return;
            }
            Long num = Long.parseLong(value+"");
            redisTemplate.opsForValue().set("num",num+1);
            // 手动释放锁
            String lockVal = (String) redisTemplate.opsForValue().get("lock");
            if (lockVal.equals(uuid)) {
                redisTemplate.delete("lock");
            }
            // 定义lua脚本
            String luaScript="if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1])" +
                    "else return 0 end";
            DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
            redisScript.setScriptText(luaScript);
            redisScript.setResultType(Long.class);
            // 第一个要是script 脚本 ,第二个需要判断的key,第三个就是key所对应的值
            redisTemplate.execute(redisScript, Arrays.asList("lock"),uuid);
        }else{
            // 等待一会再重新尝试获取锁
            try {
                Thread.sleep(100);
                lockTest();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

到了这里,关于Redis进阶:分布式锁问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis分布式锁问题

    1、业务单机情况下         问题:并发没有加锁导致线程安全问题。         解决方法:加锁处理,如lock、 synchronized         仍有问题:业务分布式情况下,代码级别加锁已经无效。需要借助第三方组件,如redis、zookeeper。 2、业务分布式情况下,使用redis的setNX,实现加

    2024年02月13日
    浏览(34)
  • Python爬虫分布式架构 - Redis/RabbitMQ工作流程介绍

    在大规模数据采集和处理任务中,使用分布式架构可以提高效率和可扩展性。本文将介绍Python爬虫分布式架构中常用的消息队列工具Redis和RabbitMQ的工作流程,帮助你理解分布式爬虫的原理和应用。 为什么需要分布式架构? 在数据采集任务中,单机爬虫可能面临性能瓶颈和资

    2024年02月11日
    浏览(45)
  • Redis 分布式锁存在什么问题 ?如何解决 ?

    目录 1. 如何实现分布式锁 2. Redis 分布式锁存在什么问题 2.1 解决死锁问题 2.2 解决锁误删问题 Redis 天生就可以作为一个分布式系统来使用,所以它实现的锁都是分布式锁。 Redis 可以通过 setnx(set if not exists)命令实现分布式锁~ setnx mylock true  -  加锁 del mylock  -  释放锁 通过

    2024年02月11日
    浏览(43)
  • Golang实现Redis分布式锁解决秒杀问题

    先写一个脚本sql,插入2000个用户 登录是通过2个字段,一个是mobile,一个是password,生成了mobile从1到2000,密码默认是123456 然后写一个单元测试,实现新注册的2000个用户登录,然后获取token 我们使用有缓冲的通道和sync.WaitGroup信号量,来控制协程的数量,经过测试,发现limi

    2024年02月14日
    浏览(42)
  • 深入理解PHP+Redis实现分布式锁的相关问题

    PHP使用分布式锁,受语言本身的限制,有一些局限性。 通俗理解单机锁问题:自家的锁锁自家的门,只能保证自家的事,管不了别人家不锁门引发的问题,于是有了分布式锁。 分布式锁概念:是针对多个节点的锁。避免出现数据不一致或者并发冲突的问题,让每个节点确保

    2024年03月23日
    浏览(70)
  • 【Redis 开发】分布式锁中的常见问题和Lua脚本

    分布式锁中我们设置的过期时间: 如果有一个线程获取锁之后在进行操作时,到达了锁的过期时间,之后就会有别的线程获得锁,如果这时,第一个线程执行完成后释放锁,就会将第二个锁的线程删除 针对这个情况如何改进: 在获取锁时存入线程标示(可以用UUID) 在释放

    2024年04月28日
    浏览(46)
  • Redis实现分布式锁之----超时和失效(非原子性)问题----解决方案

    Redis实现分布式锁之----超时和失效(非原子性)问题----解决方案 超时和失效(非原子性)问题 原子性问题 :上锁时存入线程名称,删除时要先判断锁内的名称是不是自己的,是再删除,但是后面的判断 和删除非原子性 ,会有并发安全问题。 不可重入问题 :一个线程只能

    2024年02月07日
    浏览(43)
  • 我是如何用 redis 分布式锁来解决线上历史业务问题的

    近期发现,开发功能的时候发现了一个 mq 消费顺序错乱(历史遗留问题),导致业务异常的问题,看看我是如何解决的 首先,简单介绍一下情况: 线上 k8s 有多个 pod 会去消费 mq 中的消息,可是生产者发送的消息是期望一定要有序去消费,此时要表达的是,例如 生产者如果

    2024年02月09日
    浏览(33)
  • Redis实现方式开启新篇章,解决分布式环境下的资源竞争问题,提升系统稳定性

    分布式锁一般有三种实现方式: 数据库乐观锁; 基于Redis的分布式锁; 基于ZooKeeper的分布式锁 本篇博客将介绍第二种方式,基于Redis实现分布式锁。 虽然网上已经有各种介绍Redis分布式锁实现的博客,然而他们的实现却有着各种各样的问题,为了避免误人子弟,本篇博客将

    2024年02月07日
    浏览(45)
  • 【flink番外篇】4、flink的sink(内置、mysql、kafka、redis、clickhouse、分布式缓存、广播变量)介绍及示例(8) - 完整版

    一、Flink 专栏 Flink 专栏系统介绍某一知识点,并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分,比如术语、架构、编程模型、编程指南、基本的datastream api用法、四大基石等内容。 3、

    2024年02月04日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包