Redis 分布式锁 - 觉悟吧,红锁!
🍁 作者:知识浅谈,CSDN 签约讲师,CSDN 博客专家,华为云云享专家,阿里云专家博主
📌 擅长领域:全栈工程师、爬虫、ACM 算法
💒 公众号:知识浅谈
🔥 联系方式 vx:zsqtcc
每次学到知识茅塞顿开都抑制不住自己想要去分享的冲动,说来就来...
🤞Redis 分布式锁红锁篇总结🤞分布式锁,我们常见的有 redis 的 setnx,zookeeper 等,zookeeper分布式锁实战篇,都是针对一些分布式服务,分布式环境下进行进行加锁形成隔离的解决方案。
🎈Redis 分布式锁的分析
本此分享的分布式锁主要集中在 redis 上进行操作。单机服务:1️⃣. 单个机器的 Redis 用作分布式锁,一般来说基本够小项目使用,但是肯定 redis 所在的机器宕机了整个项目就废了,得等 redis 重启才可以使用。
多机服务:主要包括如下三个 redis 主从,哨兵模式,redis 集群,哨兵模式也就是主从模式。
1️⃣. 针对 redis 主从模式,我们可以使用从 redis 做备份,当主 redis 宕机之后,从 redis 顶上接着服务,问题点:当 A 服务从主 redis 获取锁之后,主 redis 掉线了,但是因为还没有把 A 获得所得状态同步到从 redis 上去,这时候从 redis 升级为主 redis,B 服务又去申请了同一个分布式锁,因为并没有同步到 A 已经获得这把锁的状态,所以此时就有两个服务获得同一把锁,这样就会出问题了。
2️⃣. redis 集群模式,也就是我们这次要说的红锁的,就解决了主从同步出现的问题,采用所有机器都是集群中的 master,而没有了 slave 节点。
🎈Redis 红锁
正如上边 2️⃣中说那样,采用的是集群的形式而不是主从的形式,当某个服务分别向整个集群中每个实例去获取锁,如果从大于等于 n/2+1 个实例获取锁成功,则获取分布式所就成功。举个🌰:整个集群有 5 台机器,A 服务去 5 个实例中去,获得了 3 个 redis 实例返回成功才代表着成功。
🍮整个过程的具体步骤:
📐第 1 步:获取当前 Unix 时间,以毫秒为单位。
📐第 2 步 :依次尝试从 N 个实例,使用相同的 key 和随机值获取锁。在步骤 2,当向 Redis 设置锁时,客户端应该设置一个网络连接和响应超时时间,这个超时时间应该小于锁的失效时间。例如你的锁自动失效时间为 10 秒,则超时时间应该在 5-50 毫秒之间。这样可以避免服务器端 Redis 已经挂掉的情况下,客户端还在死死地等待响应结果。如果服务器端没有在规定时间内响应,客户端应该尽快尝试另外一个 Redis 实例。
📐第 3 步 :客户端使用当前时间减去开始获取锁时间(步骤 1 记录的时间)就得到获取锁使用的时间。当且仅当从大多数(这里是 3 个节点)的 Redis 节点都取到锁,获取到 3 个节点之后也会继续向其他节点发送获取锁,并且使用的时间小于锁失效时间时,锁才算获取成功。
📐第 4 步 :如果取到了锁,key 的真正有效时间等于有效时间减去获取锁所使用的时间(步骤 3 计算的结果,包括 3 个节点成功之后其他的节点的时间)。
📐第 5 步 :如果锁获取失败了,不管是因为获取成功的节点的数目没有过半,还是因为获取锁的耗时超过了锁的释放时间,都会将已经设置了 key 的 master 上的 key 删除,这里指的是向所有 redis 实例发送删除,但是只有本次请求已经设置的节点上的 key 进行删除。这里你可能会想到如果其他业务加锁,给其他业务设置的删了不就出问题了,其实对应 value 中可以设计指定不同的 id,这样 value 不同就无法删除就行。
📐第 6 步 :释放锁的方法:主动释放:服务已经执行完,不再需要锁,但是还没有到所过期的时间,就去释放锁。被动释放:锁 key 到期了,(这个常用于获取这个锁的服务异常了)redis 自动删除了,也就释放了,但是如果业务没有执行完就不好了,所以业务可以设置 watchdog 为分布式锁续约,增加过期时间。
🍚总结
以上就是自己看完之后做的一些总结,希望有所帮助,不求赞,一切随缘。
版权声明: 本文为 InfoQ 作者【知识浅谈】的原创文章。
原文链接:【http://xie.infoq.cn/article/8bd7728dfc7c9c7717eea4f31】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论