分布式锁最全详解(图文全面总结)

分布式锁最全详解(图文全面总结)分布式锁在分布式系统经常都会使用到 下面重点详解分布式锁的原理与实现 mikechen 本篇已收于 mikechen 原创超 30 万字 阿里架构师进阶专题合集 里面 什么是分布式锁 分布式锁 是一种用于在分布式系统中实现互斥访问的机制 在分布式系统

大家好,欢迎来到IT知识分享网。

分布式锁最全详解(图文全面总结)

分布式锁在分布式系统经常都会使用到,下面重点详解分布式锁的原理与实现@mikechen

本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。

分布式锁最全详解(图文全面总结)

什么是分布式锁?

分布式锁:是一种用于在分布式系统中实现互斥访问的机制,在分布式系统加锁,这就是分布式锁。

为什么需要分布式锁?

在传统的单机部署中,可以使用Java的ReentrantLock或Synchronized关键字进行互斥控制。

如下图所示:

分布式锁最全详解(图文全面总结)

但是,在分布式系统中,由于多个节点分布在不同的机器上,传统的锁机制在这种情况下失效,所以,需要分布式锁来解决。

如下图所示:

分布式锁最全详解(图文全面总结)

通过分布式锁,可以有效的解决跨JVM的互斥机制,从而,保证了数据的一致性和正确性。

因此,分布式锁成为了分布式系统中,解决共享资源访问问题的重要机制。

分布式锁的特点

首先为了确保分布式锁可用,我们至少要确保分布式锁的实现,同时满足以下3个条件。

1.互斥性

分布式锁:确保在任意时刻只有一个客户端能够获取锁,从而避免多个客户端同时访问共享资源导致的数据竞争和数据不一致性问题。

只有获取到锁的客户端才能对共享资源进行操作,其他客户端需要等待锁的释放。

2.避免死锁

分布式锁通常支持客户端多次获取锁而不会出现死锁的情况,即同一个客户端在持有锁的情况下可以重复获取锁,而不会被阻塞。

这样可以避免在复杂业务场景下出现死锁的情况,提高系统的稳定性和可靠性。

3.高可用性

分布式锁通常具有高可用性,能够在分布式系统中保持可用状态,即使在节点故障或网络分区等异常情况下也能够正常工作。

分布式锁的实现方式

分布式锁的实现方式,常见有3种,如下图所示:

分布式锁最全详解(图文全面总结)

主要会包含:数据库分布式锁、Redis实现分布式锁、以及Zookeeper实现分布式锁。

1.基于数据实现分布式锁

要实现分布式锁,最简单的方式可能就是直接创建一张锁表,如下图所示:

分布式锁最全详解(图文全面总结)

当我们想要锁住某个方法时,执行以下SQL,如下所示:

分布式锁最全详解(图文全面总结)

使用数据库作为锁的存储介质,可以利用数据库自身的事务处理和锁机制,使得实现分布式锁相对简单。

但是,使用数据库分布式锁可能会引入较大的性能开销,特别是在高并发情况下,频繁地进行数据库操作可能成为系统的瓶颈。

所以,一般我们都不会采用这种方式,而是会考虑使用Redis来实现分布式锁。

2.Redis分布式锁实现

为什么会采用Redis来是实现分布式锁呢,原因很简单,数据库性能不太好。

很显然,内存的性能会远远大于数据库么,而内存里面用的最多就是:Redis。

Redis 实现分布式锁,主要就会涉及到获取锁和释放锁。

第一步:获取锁

SET key value [EX seconds] [PX milliseconds] [NX|XX]
  • 如果该键不存在,则设置成功,获得了锁,设置过期时间来防止锁死。
  • 如果该键已存在,表示锁已被其他客户端持有,获取锁失败,需要等待或重试。

第二步:解锁

客户端通过 DEL 命令删除锁对应的键,可以释放锁。

也可以,通过 Lua 脚本在一次原子操作中判断键值并删除,确保释放锁的原子性。

如下所示:

-- 检查锁是否存在并且是当前客户端持有的 if redis.call("GET", KEYS[1]) == ARGV[1] then -- 如果是当前客户端持有的锁,则删除它 redis.call("DEL", KEYS[1]) return 1 -- 表示成功释放锁 else return 0 -- 表示锁已被其他客户端获取或已过期 end 

假设锁的键是作为 KEYS[1] 传递的,脚本首先检查锁是否存在,并且它是由当前客户端持有的。

如果是,则删除锁并返回成功释放的信号,否则返回失败的信号。

3.ZooKeeper分布式锁实现

Zookeeper 分布式锁的实现,主要是基于 临时顺序节点来实现的。

如下图所示:

分布式锁最全详解(图文全面总结)

主要会包含如下步骤:

1.创建一个 ZNode 作为锁的根节点

在 ZooKeeper 中,分布式锁通常通过创建一个临时有序节点来实现。

首先,在 ZooKeeper 中创建一个根节点来表示锁。例如,/locks。

2.尝试获取锁

当某个客户端想要获取锁时,它会在 /locks 节点下创建一个顺序临时节点,例如 /locks/lock-000000001,创建节点的顺序由 ZooKeeper 自动分配。

客户端检查自己创建的节点是否是当前 /locks 节点下最小的节点,如果是,则表示该客户端获取了锁,否则,它需要监听前一个节点的变化事件。

3.释放锁

当客户端完成了它的任务后,它会删除自己创建的节点,释放锁。

以上

本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。

分布式锁最全详解(图文全面总结)

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/174395.html

(0)
上一篇 2025-03-24 07:45
下一篇 2025-03-24 08:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信