分布式-Zookeeper-分布式锁

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 分布式-Zookeeper-分布式锁

分布式锁的由来:

其实:分布式锁的原理和jdk中提供的自旋锁,偏向锁,公平锁/非公平锁,同步锁的原理是一样的。但是jvm中的锁只针对一个jvm有效。如果是在多JVM上执行共享资源操作的时候,这个jdk中的锁就失效了,这时候的锁不能锁住每个jvm,多个jvm就相当于多个java虚拟机了操作共享资源,这时就应该使用分布式锁。举个例子:以秒杀为例:相当于每台机子上部署了相同的程序去执行对共享资源操作。三台机器同时去抢商品10件,谁先获得到时间片,谁就先执行count--。可能第二,三台机器拿到的是10,这时商品总数为9,第一台拿到是9,这时商品总数为8,现在三个人都抢购完了,第一个人却拿到了9。明明是三个人抢到了,商品数量却为8,肯定是不行的。所以这就是在多线程的情况可能导致数据不安全的问题,因为商品是共享资源。

解决:

①、如下图所示:在操作商品的时候不能去直接操作商品的数量,需要先拿到锁。一般为了效率问题,一般会用zk的分布式锁,因为分布式锁可以做集群。prod_lock是zk集群中的永久节点,下面是三个jvm。在同一个时间去抢在永久节点下面创建Lock节点。刚开始Lock节点是不存在的。

②、如下图所示:

谁创建成功了Lock节点,谁就可以操作商品的数量,比如A先创建了Lock节点,然后A就可以去操作商品,这时商品的数量减1为9。

③、然后A这个客户端将Lock节点给删掉。然后去通知B,C两个客户端。

B,C就马上去抢占Lock这个节点。谁先创建成功,谁就先获得到锁。


④、如果C创建了Lock节点,然后C拿到了锁,从而去操作商品。然后操作完又会去释放Lock,然后通知。

这里当每一个客户端释放Lock的时候,下一轮也会去抢锁。

上面的分布式锁是排它锁(X锁):当一个客户端获取到了锁之后,其他的客户端将处于一种阻塞的状态。

上面的锁是有问题的,比如当一个客户端拿到锁之后,不下单,这时锁就不会被释放,所有的客户端都会在等待,这时就会成为死锁的状态。

针对上面的问题:解决方案如下:

A、可以加一个过期的时间,如果超过了规定的时间内,还没有删除的话,可以定义一个定时器去删除这个节点。

B、创建的节点为临时节点,超过了有效的时间,它会自动的断开,那么会话将会被结束,会话结束,临时节点将自动删除掉,一旦干掉,这里又可以竞争锁了。

排它锁的执行效率是不高的,针对小项目是可以够用的,针对大项目的话效率是低的因为比如说有100个客户端,其中有一个拿到了锁,剩下的99个客户端都在等。

2、实际项目中用的锁是共享锁:

①、这个Lock锁是共享的,任何的人都可以去拿它。不需要这个Lock删了才可以去拿,这个Lock不需要平凡的建和删,每一个客户端都可以拿到这个Lock锁,只要拿到了这个Lock节点,由于线程是无序的,就可以在Lock节点下面创建很多个临时顺序节点。

②、临时顺序节点会随着顺序的增加而增加,由于网速的原因,所以创建的节点不能按照1,2,3,4,5这样的顺序而排序 。这时需要对Lock节点下面的所有的子节点进行排序,比如从小到大的排序,然后筛选出最小的节点,然后最小的节点所对应的客户端获取到锁,这里是获得锁的时候就需要排序。

③、最小的节点获取到锁之后,会释放-Lock-0000021,从而释放锁。

方式1:然后没有获取到锁的所有的顺序节点将会订阅一个最小节点被删除的订阅事件。

这种方式是不可取的,假如说有100个客户端,这个时候将会最小的节点获取到锁,将会有99个节点将会收到通知,这时会引起网络阻塞或者锁故障。因为这些的节点也不知道自己是最小的,所以都会去尝试获得锁,所以99个节点将会同时去获得锁,这时就会出现网络故障。这就有点像经济学中的羊群效应。如果业务量非常小的话,用这种方法是可取的。

方式2:业务量比较大,集群比较大的话,客户端很大的情况下是不可取的。

解决办法:所有的临时顺序节点将监听比自己小的节点就可以了。小的节点删掉的话会通知下一个节点。每次获取锁的时候,执行完然后删除,然后再进行排序。-lock-00000021监听-lock-00000011,-lock-00000031监听-lock-0000021。这样就可以解决了大流量去获取到锁的情况。

共享锁更有效的减少了创建了锁的时间,效率会很高。

3、分布式锁的优化:

如果在创建临时顺序节点的时候会出现网络抖动(网络不稳定的情况)

由于网络不稳定导致节点15的会话断开,从而17的节点和11的节点从而同时拿到锁。这时会造成并发的问题。下面的图是解决方案:


革命尚未成功,继续努力!!!

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
3月前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
3月前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
14天前
|
存储 运维 NoSQL
分布式读写锁的奥义:上古世代 ZooKeeper 的进击
本文作者将介绍女娲对社区 ZooKeeper 在分布式读写锁实践细节上的思考,希望帮助大家理解分布式读写锁背后的原理。
|
2月前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
67 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
|
2月前
|
分布式计算 NoSQL Java
Hadoop-32 ZooKeeper 分布式锁问题 分布式锁Java实现 附带案例和实现思路代码
Hadoop-32 ZooKeeper 分布式锁问题 分布式锁Java实现 附带案例和实现思路代码
48 2
|
2月前
|
分布式计算 Hadoop
Hadoop-27 ZooKeeper集群 集群配置启动 3台云服务器 myid集群 zoo.cfg多节点配置 分布式协调框架 Leader Follower Observer
Hadoop-27 ZooKeeper集群 集群配置启动 3台云服务器 myid集群 zoo.cfg多节点配置 分布式协调框架 Leader Follower Observer
50 1
|
2月前
|
SQL NoSQL 安全
分布式环境的分布式锁 - Redlock方案
【10月更文挑战第2天】Redlock方案是一种分布式锁实现,通过在多个独立的Redis实例上加锁来提高容错性和可靠性。客户端需从大多数节点成功加锁且总耗时小于锁的过期时间,才能视为加锁成功。然而,该方案受到分布式专家Martin的质疑,指出其在特定异常情况下(如网络延迟、进程暂停、时钟偏移)可能导致锁失效,影响系统的正确性。Martin建议采用fencing token方案,以确保分布式锁的正确性和安全性。
52 0
|
2月前
|
存储 SQL 消息中间件
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
51 0
|
2月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
9天前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
27 5