分布式锁的原理解析与实现工具介绍

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 分布式锁的原理解析与实现工具介绍

锁与IPC

常见的锁:互斥锁、自旋锁、原子变量、读写锁、条件变量、信号量。

IPC(进程间通信的方式):pipe、FIFO、信号量、消息队列、共性内存、socket、信号。

(拓展)虚假唤醒解决:把pthread_cond_wait放在while循环体里面,循环里判断condition是否满足。由此还能解决信号劫持的问题,比如线程池里只有一个任务,但是signal唤醒了多个消费者线程,于是需要加入判断,只能有一个线程得到满足。

分布式锁

分布式锁:在分布式场景中使用的锁。操作系统并没有提供分布式锁,只能由用户自行实现。这个锁是抽象的锁,并不是真正的锁。

分布式场景:执行程序、存储等分布在多个节点(节点通常是独立的计算机或设备等)的场景。

分布式场景的特点:执行体分布在不同的节点上,一个节点至少是一个进程。

分布式场景与锁简化模型:

如图,如果s1\s2\s3\s4都想去操作DB(数据库),但是DB同一时间最多只允许一个节点操作,那么需要设置一个锁(lock)放在s1\s2\s3\s4均能取到的地方(比如数据库,有可能和要操作的数据库放在了一起,不过在不同的表里),谁能拿到锁谁就能去操作数据。

分布式锁的构成:资源+行为。

资源:是获取到锁的节点的id(比如s1的id)。

行为:加锁和解锁,分布式场景中加锁和解锁的方式都通过网络通信的方式实现。

加锁:原来没有标记,获取到锁之后打上标记。

解锁:持锁方取出标记。

特性:

锁超时:对持锁方能持有锁的最长时间有限制,如果持锁方崩坏,不至于让其他节点也获取不到资源。

可用性和容错性其实差不多,只不过容错性更侧重数据一致性,可用性更侧重共享节点崩坏的处理。

分布式锁的类型:

重入锁:允许线程多次持有锁。

公平锁:对应互斥锁。拿不到互斥锁的线程进入阻塞态,id进入阻塞队列。

非公平锁:对应自旋锁。拿不到自旋锁的线程进入阻塞态,但是忙等待。

分布式锁的实现工具

需要基于中间件来实现,资源存储在中间件当中,加锁解锁行为基于中间件的特性来实现。

以下分别以mysql和redis为例来实现分布式锁。

用mysql实现分布式锁

首先需要建立在mysql数据库里建立用于存储锁的table,加锁的时候还要记录加锁的时间,因此设置了一个字段记录锁建立的时间。锁类型唯一,说明只能被获取一次,注意:这里的锁类型不是互斥锁、自旋锁等,而是活动1的锁、活动2的锁等。

用户节点加锁。用户节点会将以下sql语句发送到mysql数据库进行加锁操作,如果有多个用户节点,那么先发送到的节点先获取到锁,后发送到的节点会获得操作失败的信息。因为lock_type唯一,因此只有一个节点能获取到锁,获取到锁的时候数据还有记录获取到了锁的owner_id。。

用户节点解锁。解锁的时候owner_id要和之前加锁的时候的记录匹配才能解锁。

其他想获取锁但是没能获取到锁的用户节点,只能每隔一段尝试向mysql去获取一次(因为mysql不会主动通知解锁操作),看看有没有解锁。因此mysql只能实现非公平锁。

Mysql还存在锁超时问题解决,即多起一个进程去检测锁从更新时间已经过了多久了,超时了就解锁。

因此我们发现mysql实现分布式锁有这些缺点:

  1. mysql分布式锁没有可用性。但mysql节点发生了故障,整个分布式系统就会失效。
  2. 消耗资源较多。要实现锁超时操作需要另开进程。
  3. 效率不高。其他用户节点需要不断轮询看看mysql是否解锁了,mysql‘节点不会主动发起通知。
  4. 功能有限。只能是新非公平锁。

用redis实现分布式锁

Redis的特性:

  1. 内存数据库。它将数据存储在内存中而不是磁盘中。
  2. 数据结构数据库。 Redis是一种键值对存储,键一般使用字符串(不绝对)类型,值可以是字符串、哈希表、列表、集合、有序集合等各种类型。

因为redis是一句数据库,启动了之后,会进入redis服务器的运行态,在这上面可以数据redis的操作命令,redis有自己的原语操作命令。

Redis收到以下命令,说明在完成相应的锁操作:

Setnx lock1 user1:用户1尝试抢锁并进行加锁(setnx:set no lock)。

Get lock1:某个用户在尝试看看是谁持有lock1。

Del lock1:如果用户发现锁的持有者是自己,那么可以进行解锁。

注意:get lock1和del lock1需要实现原子性,可以用redis的lua脚本实现。

Set lock user1 nx ex 20:Setnx lock1 user1的拓展版,多了20s之后会自动删除记录的功能,实现锁超时功能。

Ttl lock1:看看lock1还有多久被删除。

Redis分布式锁的lua脚本

用户节点向redis发送命令,redis去执行lua脚本。脚本的具体实现不用被用户知道,但此处进行一下redis的lua脚本的大致解析。

加锁:

先判断锁是否存在。如果不存在则设置锁与超时时间,如果存在则进入监听状态,监听未来释放锁的广播。

解锁:

解锁成功的时候要进行广播,告知给正在监听的用户。

注意防范锁不存在、锁与用户不匹配等问题。如果出现了这些情况那么直接return。

Red-lock算法

目录
相关文章
|
12月前
|
安全 算法 网络协议
解析:HTTPS通过SSL/TLS证书加密的原理与逻辑
HTTPS通过SSL/TLS证书加密,结合对称与非对称加密及数字证书验证实现安全通信。首先,服务器发送含公钥的数字证书,客户端验证其合法性后生成随机数并用公钥加密发送给服务器,双方据此生成相同的对称密钥。后续通信使用对称加密确保高效性和安全性。同时,数字证书验证服务器身份,防止中间人攻击;哈希算法和数字签名确保数据完整性,防止篡改。整个流程保障了身份认证、数据加密和完整性保护。
|
9月前
|
安全 JavaScript 前端开发
HarmonyOS NEXT~HarmonyOS 语言仓颉:下一代分布式开发语言的技术解析与应用实践
HarmonyOS语言仓颉是华为专为HarmonyOS生态系统设计的新型编程语言,旨在解决分布式环境下的开发挑战。它以“编码创造”为理念,具备分布式原生、高性能与高效率、安全可靠三大核心特性。仓颉语言通过内置分布式能力简化跨设备开发,提供统一的编程模型和开发体验。文章从语言基础、关键特性、开发实践及未来展望四个方面剖析其技术优势,助力开发者掌握这一新兴工具,构建全场景分布式应用。
854 35
|
9月前
|
NoSQL 算法 安全
分布式锁—1.原理算法和使用建议
本文主要探讨了Redis分布式锁的八大问题,包括非原子操作、忘记释放锁、释放其他线程的锁、加锁失败处理、锁重入问题、锁竞争问题、锁超时失效及主从复制问题,并提供了相应的优化措施。接着分析了Redis的RedLock算法,讨论其优缺点以及分布式专家Martin对其的质疑。此外,文章对比了基于Redis和Zookeeper(zk)的分布式锁实现原理,包括获取与释放锁的具体流程。最后总结了两种分布式锁的适用场景及使用建议,指出Redis分布式锁虽有性能优势但模型不够健壮,而zk分布式锁更稳定但部署成本较高。实际应用中需根据业务需求权衡选择。
|
11月前
|
机器学习/深度学习 人工智能 JSON
Resume Matcher:增加面试机会!开源AI简历优化工具,一键解析简历和职位描述并优化
Resume Matcher 是一款开源AI简历优化工具,通过解析简历和职位描述,提取关键词并计算文本相似性,帮助求职者优化简历内容,提升通过自动化筛选系统(ATS)的概率,增加面试机会。
1371 18
Resume Matcher:增加面试机会!开源AI简历优化工具,一键解析简历和职位描述并优化
|
10月前
|
存储 人工智能 API
离线VS强制登录?Apipost与Apifox的API工具理念差异深度解析
在代码开发中,工具是助手还是枷锁?本文通过对比Apipost和Apifox在断网环境下的表现,探讨API工具的选择对开发自由度的影响。Apifox强制登录限制了离线使用,而Apipost支持游客模式与本地存储,尊重开发者数据主权。文章从登录策略、离线能力、协作模式等方面深入分析,揭示工具背后的设计理念与行业趋势,帮助开发者明智选择,掌握数据控制权并提升工作效率。
|
11月前
|
机器学习/深度学习 数据可视化 PyTorch
深入解析图神经网络注意力机制:数学原理与可视化实现
本文深入解析了图神经网络(GNNs)中自注意力机制的内部运作原理,通过可视化和数学推导揭示其工作机制。文章采用“位置-转移图”概念框架,并使用NumPy实现代码示例,逐步拆解自注意力层的计算过程。文中详细展示了从节点特征矩阵、邻接矩阵到生成注意力权重的具体步骤,并通过四个类(GAL1至GAL4)模拟了整个计算流程。最终,结合实际PyTorch Geometric库中的代码,对比分析了核心逻辑,为理解GNN自注意力机制提供了清晰的学习路径。
732 7
深入解析图神经网络注意力机制:数学原理与可视化实现
|
11月前
|
机器学习/深度学习 缓存 自然语言处理
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
Tiktokenizer 是一款现代分词工具,旨在高效、智能地将文本转换为机器可处理的离散单元(token)。它不仅超越了传统的空格分割和正则表达式匹配方法,还结合了上下文感知能力,适应复杂语言结构。Tiktokenizer 的核心特性包括自适应 token 分割、高效编码能力和出色的可扩展性,使其适用于从聊天机器人到大规模文本分析等多种应用场景。通过模块化设计,Tiktokenizer 确保了代码的可重用性和维护性,并在分词精度、处理效率和灵活性方面表现出色。此外,它支持多语言处理、表情符号识别和领域特定文本处理,能够应对各种复杂的文本输入需求。
1352 6
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
|
12月前
|
数据采集 存储 调度
BeautifulSoup VS Scrapy:如何选择适合的HTML解析工具?
在Python网页抓取领域,BeautifulSoup和Scrapy是两款备受推崇的工具。BeautifulSoup易于上手、灵活性高,适合初学者和简单任务;Scrapy则是一个高效的爬虫框架,内置请求调度、数据存储等功能,适合大规模数据抓取和复杂逻辑处理。两者结合使用可以发挥各自优势,例如用Scrapy进行请求调度,用BeautifulSoup解析HTML。示例代码展示了如何在Scrapy中设置代理IP、User-Agent和Cookies,并使用BeautifulSoup解析响应内容。选择工具应根据项目需求,简单任务选BeautifulSoup,复杂任务选Scrapy。
285 1
BeautifulSoup VS Scrapy:如何选择适合的HTML解析工具?
|
11月前
|
数据可视化 测试技术 API
前后端分离开发:如何高效调试API?有工具 vs 无工具全解析
在前后端分离开发中,API调试至关重要。本文探讨有无调试工具时如何高效调试API,重点分析Postman、Swagger等工具优势及无工具代码调试方法。通过实际场景如用户登录接口,对比两者特性。同时介绍Apipost-Hepler(IDEA插件),将可视化与代码调试结合,提供全局请求头配置、历史记录保存等功能,优化团队协作与开发效率,助力API调试进入全新阶段。
|
11月前
|
JSON 监控 物联网
WebSocket 调试全攻略:核心解析、工具选择与对比!
WebSocket 是一种全双工、实时交互的网络通信协议,适用于即时通信、实时数据流、多人协作、IoT 等场景。调试 WebSocket 时,工具应具备握手管理、实时消息收发、自定义 Header、消息大小告警、分组管理、多连接支持和断线重现等功能。主流调试工具如 Postman、ApiPost 和 ApiFox 各有优劣:Postman 界面友好适合基础调试;ApiPost 支持高级功能如消息分组和自动重连;ApiFox 则强化了多连接支持。选择工具时需根据具体需求和团队熟悉度决定。

推荐镜像

更多
  • DNS