zoukankan      html  css  js  c++  java
  • Redis笔记-Redisson实现分布式锁

    Redis在项目中除了用作session共享、缓存静态数据等用途外,还有一个比较常见的用途就是实现分布式锁,一般在java中,我们除了自己代码实现,还可以用Redisson来实现分布式锁,也是官方比较推荐的一种方案。实现分布式锁需要考虑以下几个问题:

    1、分布式锁实际就是实现互斥

    2、需要防止死锁,需要有对应的方案来防止死锁

    3、如何标记加锁和释放锁的是同一个进程

    4、如果在指定过期时间内程序未处理完,如何实现续期

    Redisson基本实现了以上要求。互斥主要利用redis存储key的唯一性来实现,防止死锁只需要给定指定的过期时间即可,加锁和释放锁通过在程序中传入线程ID来标记是否同一进程,并且如果程序未显示指定过期时间,Redisson提供了默认过期时间+WatchDog机制,实现续期功能。这里通过Redisson3.5.4版本,来分析具体实现,核心代码在RedissonLock类:

     加锁的源码如上,如果直接能上锁,则返回,如果so被占用,则尝试重复获取锁。接下来看看具体的加锁逻辑:

    看看具体的加锁过程:

    加锁过程通过一段LUA脚本实现,其中参数含义如下:

    KEYS[1]表示的是加锁的key

    ARGV[1]表示的是锁的过期事件

    ARGV[2]表示的是加锁的客户端ID

    所以,当前锁没被占用的情况,执行流程是,判断当前key是否存在,不存在,则set当前key,value是程序线程ID经过处理后的一个标识客户端的ID,1可以理解为锁被占用的次数,并返回空。此时,如果另外一个进程尝试对这个key加锁,则不满足条件,同时判断书否满足第二个条件,也不满足,则放回锁被占用的时间信息。

    如果当前锁被占用,第二个进程对这个key加锁,分两种情况,一是与被占用的锁不是同一个进程,则直接返回;二是尝试加锁的是和之前已经占用锁的是同一个进程,则会进入第二个判断语句,执行流程为对当前占用锁的 占用次数加1,这里其实就是锁可重入的机制,然后更新过期时间,并返回空。

    WatchDog实现续期的逻辑如下:

    Redisson实现分布式锁需要注意的问题,如果Redis是Master-Slave模式,可能会出现不同客户端同时获取锁的情况,主要场景是在一个客户端获取了锁,并尝试同步信息到Slave时,这个时候Master如果出现异常挂机,此时其他Salve就会升级为Master,然后其他客户端尝试对相同key加锁,在在新的Master上再次上锁,从而出现同时加锁的情况。

    ☺☺☺爱学习的逗比☺☺☺
  • 相关阅读:
    Educational Codeforces Round 92
    练习
    03 并查集(带权,分类) 树状数组 线段树
    02 动态规划 LIS LCS
    05 矩阵优化 (斜率优化等待补)
    01 STL 打表 二分查找
    AtCoder Beginner Contest 174
    Codeforces Round #660 (Div. 2)
    PCHMI工控组态开发视频教程
    分享一款免费的工控组态软件(PCHMI)
  • 原文地址:https://www.cnblogs.com/funnyboy0128/p/15204115.html
Copyright © 2011-2022 走看看