Lua 脚本如下:
if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end
此方案解决了锁被其他客户端解除的问题,但是依然没有解决锁过期释放,但是业务还没有执行完成的问题
Redisson框架
方案四中并没有解决方法未执行完成,锁就超时释放的问题 。这里有个方案大家比较容易想到,那就是锁的超时时间设置长一点,比如2min,一个接口执行时间总不能比 2 min 还长,那你就等着领盒饭吧,哈哈哈 。但是这么做,一来是不能每个锁都设置这么久超时时间,二来是如果接口出现异常了,锁只能 2 min 后才能释放,其他客户端等待时间较长 。
这个问题早就有人想到了,并给出了解决方案,开源框架 Redisson 解决了这个问题 。
文章插图
Redisson 在方法执行期间,会不断的检测锁是否到期,如果发现锁快要到期,但是方法还没有执行完成,便会延长锁的过期时间,从而解决了锁超时释放问题 。
Redlock
上面所介绍的分布式锁,都是在单台 Redis 服务器下的解决方案 。真实的生产环境中,我们通常会部署多台 Redis 服务器,也就是集群模式,这种情况上述解决方案就失效了 。
对于集群 Redis,Redis 的作者 antirez 提出了另一种解决方案,Redlock 算法
Redlock 算法大致流程如下:
文章插图
1、获取当前Unix时间,以毫秒为单位 。
2、依次尝试从N个实例,使用相同的key和随机值获取锁 。在步骤2,当向Redis设置锁时,客户端应该设置一个网络连接和响应超时时间,这个超时时间应该小于锁的失效时间 。例如你的锁自动失效时间为10秒,则超时时间应该在5-50毫秒之间 。这样可以避免服务器端Redis已经挂掉的情况下,客户端还在死死地等待响应结果 。如果服务器端没有在规定时间内响应,客户端应该尽快尝试另外一个Redis实例 。
3、客户端使用当前时间减去开始获取锁时间(步骤1记录的时间)就得到获取锁使用的时间 。当且仅当从大多数(这里是3个节点)的Redis节点都取到锁,并且使用的时间小于锁失效时间时,锁才算获取成功 。
4、如果取到了锁,key的真正有效时间等于有效时间减去获取锁所使用的时间(步骤3计算的结果) 。
5、如果因为某些原因,获取锁失败(没有在至少N/2+1个Redis实例取到锁或者取锁时间已经超过了有效时间),客户端应该在所有的Redis实例上进行解锁(即便某些Redis实例根本就没有加锁成功) 。
总结:简单总结一下就是客户端向 Redis 集群中所有服务器发送获取锁的请求,只有半数以上的锁获取成功后,才代表锁获取成功,否则锁获取失败 。
Redis 集群Redis 集群的三种模式
在生产环境中,我们使用 Redis 通常采用集群模式,因为单机版 Redis 稳定性可靠性较低,而且存储空间有限 。
Redis 支持三种集群模式
- 主从复制
- 哨兵模式
- Cluster 模式
主从复制概念
主从复制模式,有一个主,多个从,从而实现读写分离 。主机负责写请求,从机负责读请求,减轻主机压力
文章插图
主从复制原理
文章插图
- 从数据库启动成功后,连接主数据库,发送 SYNC 命令;
- 主数据库接收到 SYNC 命令后,开始执行 BGSAVE 命令生成 RDB 文件并使用缓冲区记录此后执行的所有写命令;
- 主数据库 BGSAVE 执行完后,向所有从数据库发送快照文件,并在发送期间继续记录被执行的写命令;
- 从数据库收到快照文件后丢弃所有旧数据,载入收到的快照;
推荐阅读
- 谢霆锋|谢霆锋发文示爱王菲:我爱了你20年,打脸两子,渣男属性彻底暴露
- 谢霆锋|“锋菲恋”沸沸扬扬二十年,这次是否真的画上句号?
- 吉克隽逸|从淳朴大山妹到目中无人耍大牌,吉克隽逸彻底垮台!
- 唐莲|《少年歌行》两位主角结局被改,唐莲彻底下线,赵玉真重伤退隐
- 地下室怎么防潮除湿更彻底? 地下室如何防水防潮
- 乙肝能否彻底治愈? 治疗乙肝
- 叶童|靳东这次的“清醒”,让多少实力派演员“大梦初醒”?
- 李思思|李思思带儿子游玩,自拍大变样不敢认,尖下巴彻底没了一姐气派
- 家里的蚂蚁怎么彻底消除? 家里有蚂蚁怎么办
- 订阅号消息怎么彻底删除—手机微信上的订阅号消息怎么关闭?
