网站首页 > java教程 正文
分布式锁在分布式系统经常都会使用到,下面重点详解分布式锁的原理与实现@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万字《阿里架构师进阶专题合集》里面。
- 上一篇: Redis中是如何实现分布式锁的?
- 下一篇: java为我们已经提供了各种锁,为什么还需要分布式锁?
猜你喜欢
- 2024-11-22 redis分布式锁
- 2024-11-22 4K字深度剖析redisson分布式锁原理
- 2024-11-22 java都为我们提供了各种锁,为什么还需要分布式锁?
- 2024-11-22 一文带你了解Java手写分布式锁的实现
- 2024-11-22 如何用Redisson框架实现分布式锁?
- 2024-11-22 基于 Redis 实现的分布式锁
- 2024-11-22 京东秒杀系统模块的Redis分布式锁深度剖析,没给你讲明白你打我
- 2024-11-22 面试官:Redis分布式锁超时了,任务还没执行完怎么办?
- 2024-11-22 聊聊Redis分布式锁
- 2024-11-22 浅谈分布式锁
你 发表评论:
欢迎- 最近发表
-
- 五,网络安全IDA Pro反汇编工具初识及逆向工程解密实战
- 「JAVA8」- Lambda 表达式(java lambda表达式原理)
- 深入探讨Java代码保护:虚拟机保护技术的新时代
- Nginx反向代理原理详解(图文全面总结)
- 逆向拆解日本IT,哪些Java技术栈薪资溢价高
- mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比
- Spring Boot集成ProGuard轻松实现Java 代码混淆, Java 应用固若金汤
- 从 Java 代码逆向工程生成 UML 类图和序列图
- 人与人相处:尊重是标配,靠谱是高配,厚道是顶配
- Windows系统安装日期如何修改(windows10怎么修改安装日期)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)