这次彻底读透 Redis !( 六 )


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 解决了这个问题 。

这次彻底读透 Redis !

文章插图
 
Redisson 在方法执行期间,会不断的检测锁是否到期,如果发现锁快要到期,但是方法还没有执行完成,便会延长锁的过期时间,从而解决了锁超时释放问题 。
Redlock
上面所介绍的分布式锁,都是在单台 Redis 服务器下的解决方案 。真实的生产环境中,我们通常会部署多台 Redis 服务器,也就是集群模式,这种情况上述解决方案就失效了 。
对于集群 Redis,Redis 的作者 antirez 提出了另一种解决方案,Redlock 算法
Redlock 算法大致流程如下:
这次彻底读透 Redis !

文章插图
 
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 模式
主从复制 
主从复制概念
主从复制模式,有一个主,多个从,从而实现读写分离 。主机负责写请求,从机负责读请求,减轻主机压力
这次彻底读透 Redis !

文章插图
 
主从复制原理
这次彻底读透 Redis !

文章插图