4、Redis高并发分布式锁实战

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

引言

在分布式系统中,保证数据的一致性和避免竞争条件是至关重要的。分布式锁是一种常用的机制,而Redis作为一款高性能的内存数据库,提供了简单而强大的分布式锁方案。本文将深入探讨如何利用Redis高并发分布式锁来解决分布式系统中的并发控制问题,并提供实战案例。

正常库存扣减代码

public void deductStock(){
    int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
    if(stock>0){
        stock = stock -1 ;
        redisTemplate.opsForValue().set("stock",stock+"");
        System.out.println("扣减成功,剩余库存:"+stock);
    }else {
        System.out.println("扣减失败,库存不足");
    }
}
//弊端:两个线程同时执行读取stock为50,然后各自-1 修改为49,实际应该50-2=48

代码调整后

public void deductStock(){
    synchronized (this){
        int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
        if(stock>0){
            stock = stock -1 ;
            redisTemplate.opsForValue().set("stock",stock+"");
            System.out.println("扣减成功,剩余库存:"+stock);
        }else {
            System.out.println("扣减失败,库存不足");
        }
    }
}
//弊端:适用于单体项目,如果该项目被部署两台服务器,两台服务器同时访问获取stock为50,然后各自-1 修改为49,实际应该50-2=48 也会存在上述问题,因为synchronized只能在当前项目下生效

redis的一个简单的分布式锁

public void deductStock(){
    String lockKey = "lockKey";
    try {
        Boolean result = redisTemplate.opsForValue().setIfAbsent("lockKey", "nuoyi",10, TimeUnit.SECONDS);
        if(!result){
            System.out.println("....");
            return ;
        }
        int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
        if(stock>0){
            stock = stock -1 ;
            redisTemplate.opsForValue().set("stock",stock+"");
            System.out.println("扣减成功,剩余库存:"+stock);
        }else {
            System.out.println("扣减失败,库存不足");
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        redisTemplate.delete("lockKey");
    }
}
//弊端:适用于访问量不高的系统  如果访问量非常的大,第一个a请求获取到锁 ,设置过期10s,执行业务需要15s,a业务执行10s后锁自动过期被第二个请求b拿到并执行业务,当b业务执行到第5s时,b的锁被a的请求给释放了,如此高并发循环,导致锁失效

优化上述redis的分布式锁解决不是自己的锁不释放
 

public void deductStock(){
    String lockKey = "lockKey";
    String clientId = UUID.randomUUID().toString();
    try {
        Boolean result = redisTemplate.opsForValue().setIfAbsent("lockKey", clientId,10, TimeUnit.SECONDS);
        if(!result){
            System.out.println("....");
            return ;
        }
        int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
        if(stock>0){
            stock = stock -1 ;
            redisTemplate.opsForValue().set("stock",stock+"");
            System.out.println("扣减成功,剩余库存:"+stock);
        }else {
            System.out.println("扣减失败,库存不足");
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        //不是自己的锁不删除
        if(clientId.equals(redisTemplate.opsForValue().get(lockKey))){
            redisTemplate.delete("lockKey");
        }
    }
}
//不是自己的锁不删除,但是这个只是解决了a请求删除b请求的锁,如果a请求15秒锁第十秒过期了,b请求就进来了还是会有问题,解决方案:给锁续命

 Redisson代码
 

private final Redisson redisson;

public void deductStock(){
    String lockKey = "lockKey";
    RLock redissonLock = redisson.getLock(lockKey);//获取锁
    try {
        redissonLock.lock();//加锁及锁续命   默认锁失效30s  守护线程每10s续命一次
        int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
        if(stock>0){
            stock = stock -1 ;
            redisTemplate.opsForValue().set("stock",stock+"");
            System.out.println("扣减成功,剩余库存:"+stock);
        }else {
            System.out.println("扣减失败,库存不足");
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        redissonLock.unlock();//释放锁
    }
}
//三行代码即可满足获取锁、锁续命、释放锁,完美解决上述redis的释放锁及锁续命问题  redisson的底层还是redis,使用了大量的lua脚本,lua脚本支持原子性

redisson配置
 

@Bean
public Redisson redisson(){
    Config config = new Config();
    //useSingleServer 单机版
    config.useSingleServer().setAddress("redis://"+instance.getRedisHost()+":"+instance.getRedisPort()).setDatabase(instance.getRedisDataBase());
    return (Redisson)Redisson.create(config);
}

4、Redis高并发分布式锁实战,分布式框架,redis,分布式,java
 

lua脚本语言:

  • 减少网络开销(批量操作)

  • 原子性

  • 替代redis的事务
     

为什么redis不常使用lua?

因为Redis是个单线程,如果lua有耗时运算或循环,Redis则阻塞,不会管其他的操作

通过学习本文,读者将深入了解Redis分布式锁的原理和实践应用。分布式锁在构建高并发、分布式系统中发挥着关键作用,正确使用和理解分布式锁是确保系统稳定性和可靠性的重要一环。希望本文能为读者提供有益的指导和实战经验。文章来源地址https://www.toymoban.com/news/detail-799657.html

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

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

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

相关文章

  • [Redis实战]分布式锁

    4.1 基本原理和实现方式对比 分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路。 分布式锁

    2024年02月03日
    浏览(53)
  • Redis实战之-分布式锁

    分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路 那么分布式锁他应该满足一些什么样的

    2024年01月19日
    浏览(40)
  • redis实战-redis实现分布式锁&redisson快速入门

    前言 集群环境下的并发问题  分布式锁 定义 需要满足的条件 常见的分布式锁 redis实现分布式锁 核心思路 代码实现 误删情况 逻辑说明 解决方案 代码实现 更为极端的误删情况 Lua脚本解决原子性问题 分布式锁-redission redisson的概念 快速入门 总结 在前面我们已经实现了单机

    2024年02月09日
    浏览(52)
  • Redis实战——Redisson分布式锁

    目录 1 基于Redis中setnx方法的分布式锁的问题 2 Redisson         2.1 什么是Redisson         2.2 Redisson实现分布式锁快速入门         2.3 Redisson 可重入锁原理                 什么是可重入锁?                 Redisson中又是如何实现的呢?         2

    2024年02月15日
    浏览(49)
  • Redis学习(三)分布式缓存、多级缓存、Redis实战经验、Redis底层原理

    单节点Redis存在着: 数据丢失问题:单节点宕机,数据就丢失了。 并发能力和存储能力问题:单节点能够满足的并发量、能够存储的数据量有限。 故障恢复问题:如果Redis宕机,服务不可用,需要一种自动的故障恢复手段。 RDB持久化 RDB(Redis database backup file,Redis数据库备份

    2024年02月16日
    浏览(41)
  • Redis7实战加面试题-高阶篇(手写Redis分布式锁)

    面试题: 1.Redis除了拿来做缓存,你还见过基于Redis的什么用法? 数据共享,分布式session分布式锁 全局ID 计算器、点赞位统计 购物车 轻量级消息队列(list,stream) 抽奖 点赞、签到、打卡 差集交集并集,用户关注、可能认识的人,推荐模型 热点新闻、热搜排行榜 2.Redis做分

    2024年02月07日
    浏览(37)
  • Redis学习(三)持久化机制、分布式缓存、多级缓存、Redis实战经验

    单节点Redis存在着: 数据丢失问题:单节点宕机,数据就丢失了。 并发能力和存储能力问题:单节点能够满足的并发量、能够存储的数据量有限。 故障恢复问题:如果Redis宕机,服务不可用,需要一种自动的故障恢复手段。 RDB持久化 RDB(Redis database backup file,Redis数据库备份

    2024年02月16日
    浏览(54)
  • (四)库存超卖案例实战——优化redis分布式锁

    在上一节内容中,我们已经实现了使用redis分布式锁解决商品“超卖”的问题,本节内容是对redis分布式锁的优化。在上一节的redis分布式锁中,我们的锁有俩个可以优化的问题。第一,锁需要实现可重入,同一个线程不用重复去获取锁;第二,锁没有续期功能,导致业务没有

    2024年02月07日
    浏览(45)
  • Redis集群(分布式缓存):详解持久化、主从同步原理、哨兵机制、Cluster分片集群,实现高并发高可用

            单机式Redis存在以下问题,因此需要Redis集群化来解决这些问题        Redis数据快照,简单来说就是 把内存中的所有数据都记录到磁盘中 。当Redis实例故障重启后,从 磁盘读取快照文件,恢复数据 。快照文件称为RDB文件,默认是保存在当前运行目录。     (1)

    2024年02月08日
    浏览(58)
  • 中间件系列 - Redis入门到实战(高级篇-分布式缓存)

    学习视频: 黑马程序员Redis入门到实战教程,深度透析redis底层原理+redis分布式锁+企业解决方案+黑马点评实战项目 中间件系列 - Redis入门到实战 本内容仅用于个人学习笔记,如有侵扰,联系删除 学习目标 Redis持久化 Redis主从 Redis哨兵 Redis分片集群 - 基于Redis集群解决单机R

    2024年02月03日
    浏览(53)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包