分布式锁--redis和ZooKeeper

一、分布式锁——Redis

1、分布式锁在项目中的应用场景?

  • 1、系统是一个分布式系统,集群,java锁已经锁不住了
  • 2、操作共享资源,比如说库里的唯一的用户数据
  • 3、同步访问,即多个进程同时操作共享资源

2、分布式锁有哪些解决方案?

  • 1、Redis的分布式锁,很多大公司会基于做扩展开发 setnx key value,redisson

    watch dog 防止key过期而我的程序没有执行万

  • 2、基于zookeeper,顺序节点,临时节点

  • 3、基于数据库,比如mysql,主键或唯一索引的唯一性

3、Redis做分布式锁用什么命令

SETNX

格式:setnx key value 将key的值设为value,当且仅当key不存在。

若给定的key已经存在,则setnx不做任何动作,操作失败

setnx 是SET if Not exists (如果不存在,则set的简写)

加锁:set key value nx ex 10s

释放锁:delete key

4、Redis做分布式锁死锁有哪些情况,如何解决

情况1:加锁,没有释放锁。需要加释放锁的操作,比如 delete key

情况2:加锁后,程序没有执行释放锁,程序挂了。需要用的key的过期机制

5、Redis如何做分布式锁

假设有两个服务A,B都希望获得锁,执行过程如下:

第一步:服务A为了获取锁,向Redis发起了如下的命令:SET productid:lock value NX EX 30000,其中,‘productid’由自己定义,一般与本次业务的id有关, value是一串随机值,必须保证全局的唯一性, NX指的是当且仅当key在Redis中不存在的时候执行成功,否则失败, EX 30000指的是在30秒后key自动删除,执行成功后返回成功,表明服务成功获得了锁

第二步:服务B为了得到多,向Redis发起同样的命令,但是由于Redis中存在同名的key,且并未过去,因此执行命令失败,服务B 未能获得锁,服务B进入循环请求的状态,比如每秒向Redis发起请求,直达成功获取到锁

第三步:服务A的业务代码执行时间超过30秒了,导致key过期,因此Redis自动删除了key。此时服务B再次发送命令执行成功,假设本次请求中设置的value为0000222,此时需要在服务A中对key进行续期,watch dog

第四步:服务A执行完毕,为了释放锁,服务A会主动向Redis发起删除key的命令,注意:删除key前,一定要判断服务A持有的value与redis内存存储的value是否一致。

一般使用的是lua脚本,具体如下:

if redis.call("get",KEYS[1])==ARGV[1] then
    return redis.call("del",KEYS[1])\
else
    return 0
end

二、分布式锁——ZooKeeper

1、基于ZooKeeper的分布式锁的实现原理 ?

顺序节点的特性:

使用ZooKeeper的顺序节点特性,假如我们在/lock/目录下创建三个节点,节点分别为/lock/00000001、/lock/00000002、/lock/00000003,最后一位数是一次递增的,节点名由zk来完成

临时节点的特性:

ZK中还有一个名为临时节点的节点,临时节点由某个客户端创建,当客户端与ZK集群断开连接,则该节点自动被删除,EPHEMERAL_AEQUENTIAL为临时顺序节点

根据ZK中节点是否存在,可以作为分布式锁的状态,以此来实现一个分布式锁,下面是分布式锁的逻辑:

1、客户端1调用create()方法创建名为/业务ID/lock的临时节点

2、客户端1调用getChildren(“业务ID”)方法来获取所有已经创建的子节点

3、客户端获取收到的所有的子节点path之后,如果发现自己在步骤1中创建的节点是所有序号最小的,就是看自己创建的序列号是否排第一,如果是第一,那么认为这个客户端1获得了锁,在他前面没有别的客户端拿到锁

4、如果创建的节点不是所有的节点中需要最小的,那么则监视比自己创建节点的序列号小的最大节点,进入等待,直到下次监视的节点变更的时候,再进行节点的获取,判断是否获取锁。

2、ZooKeeper和Redis做分布式锁有什么区别

Redis:

1.Redis只保持最终一致性,副本件的数据复制是异步进行的(set是写,get是读,Redis集群一般是读写分离的架构,存在主从同步延迟的情况),主从切换之后可能有部分数据没有复制过去可能会丢数据情况,故一般强一致性的业务不推荐使用Redis,而是使用ZK

2.Redis集群各方法的响应时间均为最低,随着并发量和业务数量的提升其影响时间会有明显的提升,但是极限qps可以达到最大且基本无异常

Redis集群的两种形式:
在这里插入图片描述
在这里插入图片描述

ZooKeeper:

1、使用ZooKeeper集群,锁原理是使用的ZooKeeper的顺序节点,临时节点的生命周期在client与集群的session结束时候结束。因此如果某个client节点存在网络问题,与ZooKeeper集群断开连接,session超时同样会导致锁被错误释放,ZooKeeper无法保证完全一致

2、ZooKeeper有较好的稳定性,响应时间抖动很小,没有出现异常,但是随着开发量和业务数量的提升其响应时间和qps会明显下降

总结:

1.ZK每次进行锁操作前都要创建若干节点,完成后要释放节点,会浪费时间

2.Redis只是简单的数据操作,没有这个问题

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值