[机柜]分布式Redis的分布式锁Redlock

来源: 作者: 发布时间:2022-01-04 17:41:36

引言

以前用redis实现分布式锁的时候,都是基于单个redis的例子,也就是说redis本身有单点故障。redis的官方文件介绍了一种“认为”合理的算法,redlock实现分布式redis下的分布式锁。

《redis》一文

实现库Redlock

dedstar

虽然后面的算法是一样的,不过这个点赞数确实服。

单点Redis锁锁

先简单回顾一下单点的Redis锁是怎么实现的。

获取锁

SETresource_namemy_random_valueNXPX3万

客户端A在Redis上设置一个特定的键值对,同时给出超时(避免锁定)。其他客户端在访问时首先查看key是否存在,值等于my_random_value。如果存在,等待,否则会成功执行业务代码。所有客户端都知道并共享resource_name和my_random_value。

释放锁

ifredis.call(“get”,KEYS[1])==ARGV[1]thenreturnredis.call(del”,keys[1])elsereturn0end

比较key获得的相应value是否相等,如果相等,则删除(释放),否则返回失败。

我以前也写过一篇文章。

单点Redis锁缺陷

其实这个缺陷很明显,如果只有一个Redis实例,这个挂了,所有依赖他的服务都挂了。显然不适合大型应用。

简单的Redis主要从架构遇到的问题

为了避免单点故障,我们为Redis制作了Master/Slave的主从架构构,一个Master,一个Slave。下面会有这样的问题。以下是使用场景。

客户端A在Master上获得锁。当Master将数据同步到Slave时,它被挂断(因为Master和Slave之间的同步是异步的)。Slave成为Master。客户端B通过相同的key和value获得锁。分布式锁失效

Redlock算法

假设我们NN假设5)Redi有一个例子,所有节点都是独立的,业务系统也是简单的调用,没有其他类似的辅助系统,比如新闻重发。模拟算法如下:

1.客户端获取服务器当前时间t0,毫秒。

2.使用相同的key和value依次从五个例子中获取锁。客户端在获取锁时,设置远小于业务锁所需持续时间的超时时间。例如,假设锁需要10秒,超时时间可以设置为5-50毫秒。这避免了Redis本身已经挂断,但客户端一直在尝试获得锁。加班后跳到下一个节点。

3.客户端当前时间(t1)减去t0,计算获取锁所消耗的时间t2(=t1-t0)。只有t2小于锁的业务有效时间(即第二步的10秒),客户端至少在3(5/认为是通过1)。

4.如果获得了锁,锁的有效时间为10s-t2。

5.如果客户没有得到大于等于N/2的锁,可能没有得到1的实例,也可能是时间(10s-t2)为负,我们试图释放锁,即使没有得到那个节点。

锁的释放

释放比较简单,直接删除所有实例上对应的key就好。喜欢文章的可以点个关注哟,感谢你的阅读!