您现在的位置: 首页 > 网站导航收录 > 百科知识百科知识
如何实现靠谱的分布式锁?
节点,分布式,加锁如何实现靠谱的分布式锁?
发布时间:2020-12-06加入收藏来源:互联网点击:
如何实现靠谱的分布式锁?
回答于 2019-09-11 08:43:50
回答于 2019-09-11 08:43:50
在大型互联网系统中,经常涉及分布式架构,其中如果涉及多个节点对同一资源点进行写操作,为了确保数据的一致性,就涉及分布式锁了。
基于数据库
可以使用数据库的事务机制来保证分布式锁的正确性。在获取锁时,需要在数据库中插入一条记录,当释放锁时,需要删除该记录。在这个过程中,通过数据库的事务机制来保证多个节点之间的竞争关系。
基于Redis
通过Redis的原子操作来保证分布式锁的正确性。在获取锁时,需要使用Redis的SETNX命令来尝试将一个key设置为锁的标识符,如果返回1则获取到了锁,否则需要等待一段时间后再次尝试。在释放锁时,需要使用Redis的DEL命令来删除该key。
基于Zookeeper
通过Zookeeper的有序节点来保证分布式锁的正确性。在获取锁时,需要在Zookeeper中创建一个有序节点,并获取该节点的编号,如果该节点编号是当前节点中最小的,则获取到了锁,否则需要等待。在释放锁时,需要删除该节点。
回答于 2019-09-11 08:43:50
一.可以使用redis,zookeeper,etcd是实现分布式锁
二.redis主要是通过setnx、get、getset、del命令来完成加锁,抢锁和释放锁的操作的。
1.setnx实现加锁,返回1加锁成功
2.get查看锁是否超时
3.超时了使用getset抢锁
4.del实现释放锁
redis存在的问题
1、redis如果是单机的话是有单点问题的。
redis集群因为是ap模型,是不能保证一致性的,官方提供了redlock算法来解决这个问题,但是至少需要3个master-slave节点才能完成,成本也较大。redlock相当于是来实现一致性协议的。
2、锁的超时时间设定问题,太长太短都不合适,太长了如果服务挂掉了会一直阻塞业务,太短了有可能业务还没执行完成就释放了。当然可以用官方提供redisson解决。
三.zookeeper是基于顺序临时节点和watch机制实现分布式锁的
1.顺序节点可以保证最小的节点获取锁
2.临时节点可以保证业务挂了,可以释放锁
3.监听机制可以保证锁释放后及时得到通知,再次获取锁
zk采用zab协议保证一致性,并且不用设置超时时间了,如果服务加锁挂掉了,临时节点也会自动删除。 也可用使用Apache开源的 curator框架, 自带了分布式锁解决方案,原理和上述差不多。 zk加锁释放锁都是通过动态创建节点、销毁节点来实现的,性能消耗较大。
四.etcd调用可以通过restful API的方式进行,这些需要通过prevExist实现分布式锁,如果prevExist为true, 则这是一个更新请求,如果prevExist的值是false,则是一个创建请求。
1.server1获取锁,设置超时时间是3秒 http://127.0.0.1:2379/v2/keys/locks?value=xxx&ttl=3&prevExist=false
2.为了防止业务还没有执行完,锁释放,所以每隔1秒需求重新设置下值。这个就是锁续租约。 http://127.0.0.1:2379/v2/keys/locks?value=xxx&ttl=3&prevExist=true
3.server2这时候去获取锁,则会失败 http://127.0.0.1:2379/v2/keys/locks?value=xxx&ttl=3&prevExist=false
4.server2可以监听lock的变化。当lock目录有变化的时候就会接到通知,然后重复步骤3。 这里要注意watch事件不能太多。 http://127.0.0.1:2379/v2/keys/lock?wait=true
上面这个是etcd2的实现,etcd3本身已经支持分布式锁了,key增加Revision了,客户端可以判定自己key对应的Revision是不是最小来获取锁,机制和zk获取最小值类似。
上面就是redis、zk、etcd怎么实现分布式锁的过程了。 每种方案都有公司在使用,也比较成熟了。
只要能保持读取和修改状态是原子性操作都能当锁使用,但是分布式锁需要明确的几个条件:
获取锁的业务无论正常还是异常,都需要保证可以释放,否则会出现死锁的情况,还有就是锁释放后需要及时让等待锁的一方知道,方便再次获取锁。
希望对你有帮助,可以看我分享的另一文章,里面有每一步操作的截图。
欢迎关注我,后续会持续分享架构方面文章,谢谢。
下一篇:返回列表
相关链接 |
||
网友回复(共有 0 条回复) |