分布式锁-redis和zookeeper

1.分布式锁有哪些实现方式?

分布式锁:在多系统中,对同一共享资源保证最终一致性(也就是要保证cp,一致性和分区容错)。 在单机中,可以通过锁来保证线程对共享资源的安全,在多机器上可以通过分布式锁来保证对共享资源的安全。

用redis和zookeeper来实现分布式锁。


2.使用redis如何设计分布式锁

普通的方式实现分布式锁

在setnx命令创建一个key,这算加锁。

SET resource_name my_random_value NX PX 30000 

注:1.NX:表示只有 key 不存在的时候才会设置成功。(如果此时 redis 中存在这个 key,那么设置失败,返回 nil

2.PX 30000:意思是 30s 后锁自动释放。别人创建的时候如果发现已经有了就不能加锁了。

 释放锁就是删除key,一般使用lua脚本,判断value一样才删除(删除锁的时候,找到key对应的value,跟自己传过去的value做比较,一样才删除)

用random_value是因为如果某个客户端获取到了锁,但是阻塞了很长时间才执行完,比如说超过了 30s,此时可能已经自动释放锁了,此时可能别的客户端已经获取到了这个锁,要是你这个时候直接删除 key 的话会有问题,所以得用随机值加上面的 lua 脚本来释放锁。

问题:如果是普通的 redis 单实例,那就是单点故障。如果 redis 普通主从,那 redis 主从异步复制,如果主节点挂了(key 就没有了),key 还没同步到从节点,此时从节点切换为主节点,别人就可以 set key,从而拿到锁。 

redlock算法

 在多个实例中,多个master节点上创建锁,要求是n/2+1(如5 个节点就要求是 3 个节点建立锁);如果建立锁的时间小于超时时间就算建立成功了,如果失败就删除建立过的锁。

目的:避免单节点故障。

 
3.使用zk实现分布式锁

 创建临时节点

两个机器节点同时在zookeeper上创建同一个临时节点,如果某个节点创建成功,就获取到锁,这时候其他节点就会创建失败,只能注册监听器来监听这个锁;释放锁就是删除这个临时节点,一旦释放锁监听器就会通知其他的节点,其他节点就可以加锁了。

创建临时顺序节点

如果有一把锁,被多个人给竞争,此时多个人会排队(创建的最小节点获得锁),第一个拿到锁的人会执行,然后释放锁;后面的每个人都会去监听排在自己前面的那个人创建的 node 上,一旦某个人释放了锁,排在自己后面的人就会被 zookeeper 给通知,一旦被通知了之后,就 ok 了,自己就获取到了锁,就可以执行代码了。 


4.redis和zk分布式锁的对比

  • redis 分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能。
  • zk 分布式锁,获取不到锁,注册个监听器即可,不需要不断主动尝试获取锁,性能开销较小。

 注:如果是 redis 获取锁的那个客户端 出现 bug 挂了,那么只能等待超时时间之后才能释放锁;而 zk 的话,因为创建的是临时 znode,只要客户端挂了,znode 就没了,此时就自动释放锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值