redis cluster 分布式锁_一分钟了解Redis分布式锁

v2-70a4aa84b8b360e0c6088367ba01f7b6_1440w.jpg?source=172ae18b

为什么需要分布式锁?

在我们业务中,有些数据操作是不允许同时出现多次请求的。如添加一条订单,或者发起一笔支付,如果出现double-click事件,那么会出现脏数据,甚至重复支付的风险。我们必须要禁止对同一个订单进行多次下单和支付。那这个时候就需要对这种业务进行加锁。
同时,因为我们的应用很可能不只部署在一台机器上,那么我们就不能锁定一个单机资源,而是要锁住一个所有服务器都能访问到的资源,形成只能由单机持有资源的情况。单机A使用资源完成,需要释放资源,此时B才能继续申请试用资源。

Redis该用什么命令来支持分布式锁的场景?

分布式锁要求我们对资源获取的时候,如发现资源已被占用则返回一个错误状态。Redis里面的setNX即支持此命令。
A线程setnx key value,返回1。
当A未释放锁的时候,B请求setnx key value返回0,则B加锁失败。

上面的命令可能存在的问题

当A线程死循环或者A线程意外退出,导致无法释放锁,那么B及之后访问该资源的线程都无法再进行加锁操作,这样整个功能都无法使用,后果非常严重。所以我们需要对锁进行过期时间的控制。

解决办法

Redis可以用expire key seconds的方式去使key过期。
但是还有个问题,两条指令的执行也可能在中间出现问题,导致expire执行失败。还有什么办法呢?此处可以用Redis的set指令。set key value EX seconds NX
上面在一条语句指令中在原来的基础上设置了过期时间。可以满足我们的需求。对value的要求: value需要是一个随机值。因为有可能出现以下情况。
1. A执行获取key命令成功。
2. A执行时间较长,key已过期,自动失效。
3. B申请加锁,执行命令成功。
4. A执行任务完成,删除B申请的锁。
所以,我们要在删除之前进行验证。所以删除时需要对随机设置的value进行验证,避免删除别的客户端申请的锁。

Redis分布式锁的弊端

Redis分布式锁的实现看起来貌似没问题了,但是随着业务量的增长和用户数量的增加,单台redis服务已经无法满足我们的需求。在分布式系统中,假设A & B & C都存储了部分锁信息,那么其中一台redis服务器的宕机和网络抖动都有可能导致加锁的失败。或者主从结构,主库还没来得及同步给从库,主服务宕掉了。那么这个锁就无法正确锁住相关业务,有可能造成脏数据的产生。

Red Lock

Red Lock是redis的作者antirez设计的一个非常复杂的分布式锁功能。这个功能还让分布式专家Martin和antirez进行了一系列的讨论,详见 antirez的文章。总之,RedLock的实现非常复杂,细节参看 Redis分布式锁 抽空再专门整理一下RedLock​

其他分布式锁实现

Zookeeper!在《分布式锁ZK篇》我们再详细看一下ZK的分布式锁是如何使用的。

总结

Redis单机的分布式锁使用方式简单,但是集群不能保证高可用性。如果希望能保证分布式锁的高可用可以使用较为复杂的RedLock 或者 ZK。


觉得文章不错的话,欢迎转发收藏(请注明出处哦)。能够关注公众号就更好啦~
作者:BigBigBigPeach
地址:https://www.deepstack.top/articles/2019/07/18/1563462985488.html
微信公众号:deepstack

v2-7a6e0910a60ed68349402f02992fc030_b.jpg
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值