Redisson分布式锁介绍及实战应用(防止缓存击穿)

本地锁

    浏览器把100w请求由网关随机往下传,在集群情况下,每台服务都放行10w请求过来,这时候每台服务都用的是本地锁是跨JVM的, 列如这些服务都没有49企业,此时有几个服务进行回原了打击在DB上面,那后期把这个服务部署了N台,N台用的都是自己的锁,是锁不住的

Redisson分布式锁介绍及实战应用(防止缓存击穿)_第1张图片

分布式锁第一阶段

让微服务都去公共位置去,列如Redis去抢占坑位利用setnx命令,如果是1了,操作成功,是1变成0操作失败,

问题:如下图如果抢到锁了 业务在执行期间机器宕机或停电了,后面解锁业务没有执行到,锁一直在,其他服务如果还想获取到这个锁,就会导致永远获取不到这个锁了,所以得引入过期时间

Redisson分布式锁介绍及实战应用(防止缓存击穿)_第2张图片

 分布式锁第二阶段

引入过期时间后即使业务爆炸等10s以后再自行删除

问题:如果执行过期时间的时候停电了,导致这行代码没有设置上,所以加锁和过期时间必须是一起的保证原子性操作。

Redisson分布式锁介绍及实战应用(防止缓存击穿)_第3张图片

 分布式第三阶段

为了保证原子性可以使用set key value EX “过期时间” NX,加锁+过期时间 用原子操作没问题了

极端情况:
假设锁10s过期,

  1. A运行9.5s业务结束开始删锁,给redis发请求。速度慢
  2. redis第10s锁过期自动删除,然后B抢到了锁,这个锁是B,B已经开始执行业务了
  3. B执行业务的时候,A删锁命令顺着网线爬到redis。直接调用del lock,删除了这个key。导致删除了B的锁的错误。B锁没有,其他C可能又进来。两个人都在执行业务,没锁住 

Redisson分布式锁介绍及实战应用(防止缓存击穿)_第4张图片 分布式锁第四阶段

为了避免解别人的锁,利用UUID作为每个线程自己锁的唯一值

问题解除锁的时候可能会解到别人的锁

Redisson分布式锁介绍及实战应用(防止缓存击穿)_第5张图片

分布式锁终极阶段

利用Lua脚本删除锁

Redisson分布式锁介绍及实战应用(防止缓存击穿)_第6张图片

使用redisson

特点:
    1,锁名称相同就认为是同一把锁
    2,自动续期 默认是30S  每10S 会续期30S  
        只要锁没有指定释放时间,每隔lockWatchdogTimeout/3 就会给锁续期,续满看门狗时间30S  也就是每10S会进行喂狗操作
private long lockWatchdogTimeout = 30 * 1000;
    3,加锁操作 + 过期时间操作 能保证原子性,获取锁 + 判断锁 + 删除锁 也能保证原子性
4,redisson底层的所有操作都依赖于lua脚本
Redisson分布式锁介绍及实战应用(防止缓存击穿)_第7张图片

看门狗如何自动续期 

Redisson看门狗机制, 只要客户端加锁成功,就会启动一个 Watch Dog。

redisson底层有个 看门狗时间 = lockWatchdogTimeout ; 30s;每10s进行一次 喂狗

1,scheduleExpirationRenewal(threadId); 定时重新设置过期时间

  • 底层使用 Timeout;定时任务。每隔internalLockLeaseTime / 3执行重新设置超时时间的任务;

    • 超时时间设置好以后,递归调用自己,又启动一个定时任务

    • 定时任务是在 internalLockLeaseTime[30000] / 3 毫秒以后执行

    • 每10s执行一次任务。

2,如果服务宕机了,Watch Dog 机制线程也就没有了,此时就不会延长 key 的过期时间,到了 30s 之后就会自动过期了,其他线程就可以获取到锁。

你可能感兴趣的:(java,开发语言,分布式)