mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-11-17 06:33:49 +08:00
fix img
This commit is contained in:
@@ -216,15 +216,15 @@ function hide_canvas() {
|
||||
<p>接下来我就通过 ZooKeeper 来实现一个排他锁。</p>
|
||||
<h4>创建锁</h4>
|
||||
<p>首先,我们通过在 ZooKeeper 服务器上创建数据节点的方式来创建一个共享锁。其实无论是共享锁还是排他锁,在锁的实现方式上都是一样的。唯一的区别在于,<strong>共享锁为一个数据事务创建两个数据节点,来区分是写入操作还是读取操作</strong>。如下图所示,在 ZooKeeper 数据模型上的 Locks_shared 节点下创建临时顺序节点,临时顺序节点的名称中带有请求的操作类型分别是 R 读取操作、W 写入操作。</p>
|
||||
<p><img src="assets/CgqCHl8Oc56AEMuZAAAsuQwHWCY999.png" alt="image" /></p>
|
||||
<p><img src="assets/CgqCHl8Oc56AEMuZAAAsuQwHWCY999.png" alt="png" /></p>
|
||||
<h4>获取锁</h4>
|
||||
<p>当某一个事务在访问共享数据时,首先需要获取锁。ZooKeeper 中的所有客户端会在 Locks_shared 节点下创建一个临时顺序节点。根据对数据对象的操作类型创建不同的数据节点,如果是读操作,就创建名称中带有 R 标志的顺序节点,如果是写入操作就创建带有 W 标志的顺序节点。</p>
|
||||
<p><img src="assets/Ciqc1F8Oc6aAH44DAAA1aVd9UXo732.png" alt="image" /></p>
|
||||
<p><img src="assets/Ciqc1F8Oc6aAH44DAAA1aVd9UXo732.png" alt="png" /></p>
|
||||
<h4>释放锁</h4>
|
||||
<p>事务逻辑执行完毕后,需要对事物线程占有的共享锁进行释放。我们可以利用 ZooKeeper 中数据节点的性质来实现主动释放锁和被动释放锁两种方式。</p>
|
||||
<p>主动释放锁是当客户端的逻辑执行完毕,主动调用 delete 函数删除ZooKeeper 服务上的数据节点。而被动释放锁则利用临时节点的性质,在客户端因异常而退出时,ZooKeeper 服务端会直接删除该临时节点,即释放该共享锁。</p>
|
||||
<p>这种实现方式正好和上面介绍的死锁的两种处理方式相对应。到目前为止,我们就利用 ZooKeeper 实现了一个比较完整的共享锁。如下图所示,在这个实现逻辑中,首先通过创建数据临时数据节点的方式实现获取锁的操作。创建数据节点分为两种,分别是读操作的数据节点和写操作的数据节点。当锁节点删除时,注册了该 Watch 监控的其他客户端也会收到通知,重新发起创建临时节点尝试获取锁。当事务逻辑执行完成,客户端会主动删除该临时节点释放锁。</p>
|
||||
<p><img src="assets/CgqCHl8O5rOADPbBAACVhsBN-NU550.png" alt="X.png" /></p>
|
||||
<p><img src="assets/CgqCHl8O5rOADPbBAACVhsBN-NU550.png" alt="png" /></p>
|
||||
<h3>总结</h3>
|
||||
<p>通过本课时的学习,我们掌握了什么是分布式锁,以及分布式锁在实际生产环境中面临的问题和挑战。无论是单机上的加锁还是分布式环境下的分布式锁,都会出现死锁问题。面对死锁问题,如果我们不能很好地处理,会严重影响系统的运行。在本课时中,我为你讲解了两种处理死锁问题的方法,分别是超时设置和死锁监控。然后重点介绍了利用 ZooKeeper 实现一个共享锁。</p>
|
||||
<p>在具体实现的过程中,我们利用 ZooKeeper 数据模型的临时顺序节点和 Watch 监控机制,在客户端通过创建数据节点的方式来获取锁,通过删除数据节点来释放锁。</p>
|
||||
|
||||
Reference in New Issue
Block a user