Redis常见分布锁的原理和实现

2022-08-18 13:17:36
目录
前言基于数据库悲观锁实现原理具体实现乐观锁简介实现原理具体实现Redis实现分布式锁Zooker实现分布式锁加锁过程释放锁的过程异常场景分析具体实现Zookpeer实现分布式锁实现库存扣减总结

前言

Java中的锁主要包括synchronized锁和JUC包中的锁,这些锁都是针对单个JVM实例上的锁,对于分布式环境是无效的,那么基于分布式锁的如何实现呢?

常见的分布式锁的实现如下图:

基于数据库

悲观锁

悲观锁(Pessimistic>

实现原理

悲观并发控制实际上是"先取锁再访问"的保守策略,为数据处理的安全提供了保证.

具体实现

例如通过悲观锁来实现库存扣减的伪代码如下:

// 对于库存记录进行行锁

SELECT *FROM sys_goods s WHERE s.Id='1' FOR UPDATE;

//执行库存扣减
update sys_stock s set s.stockQty=s.stockQty-#{number} where s.goodId=1 and s.stockQty>0;

//提交事务,自动释放悲观锁。

乐观锁

简介

乐观锁是基于数据版本号(version)的机制来实现的。数据库表添加"version"字段,>

实现原理

相对悲观锁,乐观锁的实现不会使用到数据库的锁机制,乐观锁的原理使用的CAS的机制来实现的,CAS(Compare-and-Swap)即比较并替换.

    1、比较:读取到了一个值A,在将其更新为B之前,检查原值是否仍为A(未被其他线程改动).2、设置:如果是未发送变化,则将A更新为B结束。如果发生变化,则什么都不做。

    具体实现

    例如乐观锁来实现库存扣减的伪代码如下:

    // 查询库存记录,获取版本号
    SELECT stockQty,version FROM sys_goods s WHERE s.Id='1'
    
    //执行库存扣减,防止出现超卖
    update sys_stock s set 
      s.stockQty=s.stockQty-#{number},
      s.version=version+1
      where s.goodId=1 and s.stockQty>0 and version=#{version};

    Redis实现分布式锁

    关于Redis分布式锁的实现,已经在前期的文章中进行了讲解,大家可以参考如下文章

    Spring Boot 实现Redis分布式锁原理

    Spring Boot 集成Redisson实现分布式锁详细案例

    Zooker实现分布式锁

    Zookper实现分布式锁,主要是应用zookeeper节点的临时和有序性来实现。

    加锁过程

    当客户端1请求时,Zookeeper客户端会创建一个持久节点Locks节点,如果客户端1想获取锁,会在locks节点下创建临时节点/node_000000,如果查找Locks下面所有临时有序子节点,当自己为最小的节点是则获取锁成功。

    当客户端2尝试获取锁时,也会查看locks下面的临时节点,判断自己的节点/node_000001是不是最小,如果不是最小则获取锁失败,客户端2会向它排序靠前的节点node_000000注册watch事件,用来监听node_000000是否存在,虽然抢锁失败,但是node_000001进入等待状态。

    释放锁的过程

    Zookeeper的客户端业务完成或者客户端发生故障,都会删除临时节点并且释放锁。如果是任务完成,客户端1还会显式调用删除node_000000的指令。

    例如上述图,客户端1断开,临时节点node_000000已被删除,而此时node_000001通过watcher监听发现自己为为最小的临时节点,所以获取锁成功。

    异常场景分析

    客户端1创建临时节点后,会与Zookeeper服务器维护一个Session,这个Session会依赖客户端>

    具体实现

    Zookeeper实现分布式锁,可以采用Curator实现分布式锁,关于SpringBoot如何集成Curator,大家可以参考如下文章:

    Java Spring Boot 集成Zookeeper

    Zookpeer实现分布式锁实现库存扣减

     @RequestMapping("/lockStock")
        public void lockStock()
        {
           zooKeeperUtil.lock("/Locks", 1000, TimeUnit.SECONDS, ()->{
               //业务逻辑
           });
        }

    小结:

    关于分布式锁的实现的对比,详情请查看下图:

    总结

    本文详细的介绍了几种分布式锁的实现和使用,业务需要根据场景选择合适的分布式锁的实现,如有疑问,请随时反馈。

    到此这篇关于Redis常见分布锁的原理和实现的文章就介绍到这了,更多相关Redis分布锁原理内容请搜索易采站长站以前的文章或继续浏览下面的相关文章希望大家以后多多支持易采站长站!