redis,zookeeper实现分布式锁

  • redis锁

Redis单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端Redis的连接并不存在竞争关系。其次Redis提供一些命令SETNXGETSET,可以方便实现分布式锁机制

SETNX命令(SETif Not eXists) 语法:SETNX keyvalue
功能:当且仅当key不存在,将key的值设为value,并返回1;若给定的key已经存在,则SETNX不做任何动作,并返回0

GETSET命令  语法:GETSETkeyvalue
功能:将给定 key的值设为value,并返回key的旧值(oldvalue),当key存在但不是字符串类型时,返回一个错误,当key不存在时,返回nil

GET命令  语法:GET key
功能:返回 key所关联的字符串值,如果key不存在那么返回特殊值nil

DEL命令    语法: DEL key[KEY …]
功能:删除给定的一个或多个key,不存在的key会被忽略

具体实现步骤如下:

SETNX将键 lock.foo的值设置为锁的超时时间(当前时间+锁的有效时间 +1

我们假设

进程P1执行 SETNXlock.foo命令,并返回1,首先获得锁lock.foo,然后进程P1挂掉了。接下来的情况:

进程P2执行 SETNXlock.foo以尝试获取锁

    由于进程P1已获得了锁,所以P2执行 SETNXlock.foo返回0,即获取锁失败

    P2执行 GET lock.foo来检测锁是否已超时,如果没超时,则等待一段时间,再次检测

    如果P2检测到锁已超时,即当前的时间大于键lock.foo的值,P2会执行以下操作 
    GETSETlock.foo<current Unix timestamp + lock timeout + 1>

    由于 GETSET操作在设置键的值的同时,还会返回键的旧值,通过比较键lock.foo的旧值是否小于当前时间,可以判断进程是否已获得锁

    假如 另一个进程 P3 检测到锁已超时,并在 P2 之前 执行了 GETSET 操作,那么 P2 GETSET 操作返回的是一个大于当前时间的时间戳,这样 P2 不会获得锁而继续等待。注意到,即使 P2 接下来 将键 lock.foo 的值设置了比 P3 设置 的更大的值也没影响

具体实现代码可参考如下:

  • zookeeper锁
                zookeeper分布式锁具体实现原理如下:
               

                ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。在分布式应用中,由于工程师不能很好地使用锁机制,以及基于消息的协调机制不适合在某些应用中使用,因此需要有一种可靠的、可扩展的、分布式的、可配置的协调机制来统一系统的状态。Zookeeper的目的就在于此

Zookeeper中,znode是一个跟Unix文件系统路径相似的节点,可以往这个节点存储或获取数据。如果在创建znodeFlag设置为EPHEMERAL,那么当创建这个znode的节点和Zookeeper失去连接后,这个znode将不再存在在Zookeeper

这里利用zookeeperEPHEMERAL_SEQUENTIAL类型znode节点watcher机制,来简单实现分布式锁。主要思想:

1、开启10个线程,在disLocks节点下各自创建名为subEPHEMERAL_SEQUENTIAL节点;

2、获取disLocks节点下所有子节点,排序,如果自己的节点编号最小,则获取锁;

3、否则watch排在自己前面的节点,监听到其删除后,进入第2步(重新检测排序是防止监听的节点发生连接失效,导致的节点删除情况);

4、删除自身sub节点,释放连接;


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值