常见分布式锁方案

在单机环境中,应用是在同一进程下的,只需要保证单进程多线程环境中的线程安全性,通过 JAVA 提供的 volatile、ReentrantLock、synchronized 以及 concurrent 并发包下一些线程安全的类等就可以做到。而在多机部署环境中,不同机器不同进程,就需要在多进程下保证线程的安全性了。因此,分布式锁应运而生。

第一种

基于redis命令

  1. 加锁:执行setnx,若成功再执行expire添加过期时间
  2. 解锁:执行delete命令

实现简单,相比数据库和分布式系统的实现,该方案最轻,性能最好
1.setnx和expire分2步执行,非原子操作;若setnx执行成功,但expire执行失败,就可能出现死锁
2.delete命令存在误删除非当前线程持有的锁的可能
3.不支持阻塞等待、不可重入

第二种

基于redis Lua脚本能力

  1. 加锁:执行SET lock_name random_value EX seconds NX 命令

  2. 解锁:执行Lua脚本,释放锁时验证random_value
    – ARGV[1]为random_value, KEYS[1]为lock_name
    if redis.call(“get”, KEYS[1]) == ARGV[1] then
    return redis.call(“del”,KEYS[1])
    else
    return 0
    end

redis+lua基本可应付工作中分布式锁的需求。
不足之处:不支持锁重入,不支持阻塞等待

第三种

redisson 分布式锁
redisson保持了简单易用、支持锁重入、支持阻塞等待、Lua脚本原子操作。
我们在网上看到的redis分布式锁的工具方法,大都满足互斥、防止死锁的特性,有些工具方法会满足可重入特性。

如果只满足上述3种特性会有哪些隐患呢?redis分布式锁无法自动续期,比如,一个锁设置了1分钟超时释放,如果拿到这个锁的线程在一分钟内没有执行完毕,那么这个锁就会被其他线程拿到,可能会导致严重的线上问题,我已经在秒杀系统故障排查文章中,看到好多因为这个缺陷导致的超卖了。

redisson 提供的分布式锁是支持锁自动续期的,也就是说,如果线程仍旧没有执行完,那么redisson会自动给redis中的目标key延长超时时间,这在Redisson中称之为 Watch Dog 机制。

同时 redisson 还有公平锁、读写锁的实现。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值