redis分布式锁

本文探讨了基于Redis的分布式锁实现,包括基础的加锁、解锁操作,以及处理超时、可重入性、自旋锁和锁信息的发布订阅。文中提到通过设置看门狗线程来应对超时问题,Redisson框架提供了相应解决方案。同时,指出在Redis集群中可能存在的锁失效问题,以及RedLock的有效性争议。最后,建议在理解底层原理基础上使用成熟框架,并强调分布式锁无法做到100%有效性,对于重要数据应考虑数据端原子性保障。

1、基础实现

加锁通过redis的set命令实现:

key:锁名

requestId:锁值,用于解锁

NX:key不存在时才能添加成功,以此来实现锁

EX、expireTime:锁的超时时间

String result = jedis.set(key, requestId, "NX", "EX", expireTime);

解锁先判断锁名key是否存在以及归属自己(通过requestId值判断),若是则删除该key对应的锁

为了实现原子性,通过Lua脚本代码执行

private static final String DEL_SCRIPT = 
"if 
    redis.call('get', KEYS[1]) == ARGV[1] 
then 
    return redis.call('del', KEYS[1]) 
else 
    return 0 end
";

jedis.eval(DEL_SCRIPT, Collections.singletonList(key), Collections.singletonList(requestId));

2、如何处理超时情况出现

设置合理的超时时间,但如何才能定义一个合理的超时时间,即使预估了一般情况下业务执行所需耗费的最大时间,也仍然会有其他情况出现,比如网络、GC等。

可以增加看门狗线程(WatchDog)来监控,当剩余时间小于一定大小时,若加锁业务仍未处理完成则将超时时间恢复到原始大小,如此反复直到业务处理完成

Redisson框架提供了该具体实现

3、可重入性

基础实现不支持锁的可重入性,可通过redis的哈希表记录重入次数实现

Redisson框架提供了该具体实现

4、自旋锁

5、锁信息的订阅发布

6、redis单例

以上讨论均基于依赖的是redis单机实例,如果使用redis集群,会有概率出现锁失效的情况出现。

红锁(RedLock)的有效性目前还是有争议的,且性能损坏较大,因此实际使用不多。

7、总结

        a、在了解内部实现的基础上使用Redisson框架,不要自己造车轮,总有人想的比你多比你全

        b、分布式锁目前不存在100%有效的方案,所以对于重要性非常高的数据,建议在数据端保证数据操作的原子性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值