当前位置: 首页 > news >正文

业界内分布式锁

技术主题

在分布式系统中,面对分布式微服务日益流行的场景,分布式锁一直是分布式系统老生常谈的内容。分布式锁可以防止用户重复点击,对于电商场景中,分布式锁可以防止用户重复下单,给用户带来更好的体验。

技术实现方式

一基于Redis的实现方式

通过在Redis中存储一个唯一的key,利用Redis的原子性操作来实现锁的获取和释放

二基于ZooKeeper的实现方式

利用Zookeeper的节点临时性和唯一性特点,在一个节点上创建一个临时节点表示锁的占用状态,释放锁时直接删除该节点

三基于数据库的实现方式

通过在数据库中创建一张表,将表的相关信息作为表的字段,通过事务的控制来实现锁的获取和释放

技术具体实现原理

一基于Redis的具体实现原理

  1. Redis操作必须是原子的:获取锁和释放锁的Redis操作必须是原子的,可以使用Redis的setnx命令实现。它可以原子地执行一次 SET 命令,当且仅当 key 不存在,可以设置成功。
  2. 设置过期时间:为避免死锁,需要设置锁的过期时间,若处理业务超时导致锁未被释放,则其他节点可以重新竞争获取锁。使用Redis的expire命令可以设置key的过期时间。
  3. 避免误删:为避免误删其他线程的锁,建议在删除前先判断锁是否属于自己。尽管不同线程生成的随机字符串保持一定的唯一性,但是无法完全避免重复。

二基于ZooKeeper的具体实现原理

  1. ZooKeeper操作必须是原子的:获取锁和释放锁的ZooKeeper操作必须是原子的,可以使用ZooKeeper的create命令实现。它可以原子地创建一个唯一且临时的节点。
  2. 设置临时节点:在ZooKeeper中创建一个临时节点,表示锁的占用状态。当该节点的客户端断开连接或删除该节点时,ZooKeeper将自动清除该节点。
  3. 利用顺序号:在创建临时节点时,可以利用ZooKeeper中的顺序号进行排序,使得节点可以按照一定的顺序排列。其他客户端在同样的目录下依照节点顺序创建临时节点,获得锁的客户端是首个创建临时节点的客户端。
  4. 避免死锁:由于删除节点操作可以避免死锁,因此在释放锁的时候需要删除该节点。如果释放锁的时候出现异常导致无法删除节点,可以设置一个超时时间,让ZooKeeper自动删除该节点。
  5. 处理异常情况:在分布式系统中,可能会出现各种异常情况,比如网络异常、ZooKeeper节点宕机等情况,需要对这些异常情况进行处理。通常的做法是捕获异常并释放锁。

三基于数据库的实现原理

基于数据库乐观锁实现分布式锁的方法是,为每个需要锁定的资源在数据库中创建一个对应的记录,记录包含以下信息:

  • 资源名称(resource)
  • 当前锁定者的标识(owner)
  • 最后一次锁定时间(last_lock_time)
  • 版本号(version)

其中,owner、last_lock_time 和 version 可以使用数据库的行版本号实现,而资源名称是唯一的。

实现步骤如下:

  1. 当需要锁定资源时,在数据库中执行以下 SQL 语句:
UPDATE lock_table SET owner=<当前线程标识>, last_lock_time=NOW(), version=version+1 
WHERE resource=<资源名称> AND owner IS NULL;

该语句会尝试更新 lock_table 表中指定资源的记录,并将 owner 设置为当前线程的标识。如果更新成功,则表示当前线程获取了锁;如果更新失败,则表示有其他线程正在持有该资源的锁。

  1. 当释放锁时,在数据库中执行以下 SQL 语句:
UPDATE lock_table SET owner=NULL, last_lock_time=NOW(), version=version+1 
WHERE resource=<资源名称> AND owner=<当前线程标识> AND version=<当前版本号>;

该语句会尝试将持有资源锁的线程标识和版本号更新为 NULL 和当前版本号+1。如果更新成功,则表示当前线程成功释放了锁;如果更新失败,则表示要么该资源并没有被当前线程锁定,要么在锁定期间该资源的版本号已经被修改了。

需要注意的是,由于乐观锁是基于数据版本号的,因此在高并发情况下,会有一定的冲突率,需要在应用程序中进行重试或回退等操作来保证锁定操作的可靠性。另外,该实现方案也需要确保数据库的事务隔离级别为 SERIALIZABLE,以避免并发情况下的数据不一致性问题。

四数据库悲观锁

数据库的被关锁
此外,MySQL 还支持通过 SELECT FOR UPDATE 或 SELECT … LOCK IN SHARE MODE 语句来实现悲观锁。例如:

SELECT field1, version FROM your_table WHERE id = your_id FOR UPDATE;

该语句会将该记录上锁,防止其他事务修改该记录,从而实现悲观锁的效果。在 MySQL 中,悲观锁机制使用的是表锁和行锁,因此在高并发情况下,也需要注意锁冲突导致的性能问题。

相关文章:

业界内分布式锁

技术主题 在分布式系统中&#xff0c;面对分布式微服务日益流行的场景&#xff0c;分布式锁一直是分布式系统老生常谈的内容。分布式锁可以防止用户重复点击&#xff0c;对于电商场景中&#xff0c;分布式锁可以防止用户重复下单&#xff0c;给用户带来更好的体验。 技术实现…...

基于Java+Springboot+Vue+elememt甜品屋蛋糕商城系统设计和实现

基于JavaSpringbootVueelememt甜品屋蛋糕商城系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系…...

C/C++每日一练(20230424)

目录 1. 只出现一次的数字 &#x1f31f; 2. 有效的括号 &#x1f31f;&#x1f31f; 3. 递归反序正整数 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 只出现一次…...

三百左右的蓝牙耳机哪个音质好?三百左右音质最好的蓝牙耳机推荐

在外出携带的数码产品中&#xff0c;蓝牙耳机的出现频率居高不下&#xff0c;一部手机&#xff0c;一副耳机已经成为不少人外出的标配。蓝牙耳机无外乎是用来听的&#xff0c;下面&#xff0c;我来给大家推荐几款三百左右音质好的蓝牙耳机&#xff0c;一起来看看吧。 一、南卡…...

把阿里大鸟花3个月时间整理的软件测试面经偷偷给室友,差点被他开除了···

写在前面 “这份软件测试面经看起来不错&#xff0c;等会一起发给他吧”&#xff0c;我看着面前的面试笔记自言自语道。 就在这时&#xff0c;背后传来了leder“阴森森”的声音&#xff1a;“不错吧&#xff0c;我可是足足花了三个月整理的” 始末 刚入职阿里的我收到了大学…...

跳槽时的决策逻辑是什么?

你好&#xff0c;我是辰洋&#xff0c;《郭东白的架构课》的项目负责人。 我们正文的第二个模块已经更新过半。之前已经预告过&#xff0c;东白老师会时不时邀请一些不同行业的技术领导者来交流与对话&#xff0c;为你提供更多的视角、更宽阔的视野和更多元的思考维度。 正值…...

vs2022下配置zxing cpp环境

生成zxing 下载zxing&#xff0c;zxing-cpp-master https://github.com/zxing-cpp/zxing-cpp Cmake生成项目&#xff0c;点Generate&#xff0c;把OpenCV_DIR修改了&#xff0c;NameValue没有报红就点Generate。然后点Open Project打开项目。 打开项目后&#xff0c;右击解决…...

【linux】linux入门级别指令

一些基础指令 前言用户登录新建用户 ls指令pwd命令cd 指令which指令alias指令touch指令mkdir指令rmdir指令 && rm 指令rmdirrm man指令cp指令mv指令catmoreless指令head 指令tail指令输出重定向时间相关的指令cal指令find指令grep指令zip/unzip指令tar指令bc指令uname指…...

Android 开发之核心技术点——性能优化篇(带面试题)~

性能优化对于Android开发的重要性非常大。随着Android设备的不断升级&#xff0c;用户对应用的要求也越来越高&#xff0c;包括应用的运行速度、响应速度、流畅度等方面。如果应用的性能不能满足用户的需求&#xff0c;很可能会导致用户流失、差评以及应用被卸载等情况。 另外…...

typescript全局安装卸载以及npm相关问题

全局安装 npm install -g typescript 全局安装之后&#xff0c;如果想要卸载要使用 npm uninstall -g typescript 全局安装之后可以在终端使用 tsc xxx 编译ts文件 本地安装&#xff0c;也就是在项目目录下安装 npm install typescript 本地卸载 npm uninstall type…...

一条SQL如何被MySQL架构中的各个组件操作执行的?

文章目录 1. 单表查询SQL在MySQL架构中的各个组件的执行过程2. SELECT的各个关键字在哪里执行&#xff1f;3. 表关联查询SQL在MySQL架构中的各个组件的执行过程4. LEFT JOIN将过滤条件放在子查询中再关联和放在WHERE子句上有什么区别&#xff1f;5. 聚集索引和全表扫描有什么区…...

Go语言面试题--进阶语法(30)

文章目录 1.下面的代码能否正确输出&#xff1f;2.下面代码输出什么&#xff1f;3.下面的代码有什么问题&#xff1f;4.下面代码有什么不规范的地方吗&#xff1f; 1.下面的代码能否正确输出&#xff1f; func main() {var fn1 func() {}var fn2 func() {}if fn1 ! fn2 {pri…...

JavaScript概述四(DOM文档对象模型)

1.DOM(Document Object Model) 会把网页里面的元素当成对象去操作,包含对象的属性,属性值,方便我们去 操作网页。 整个页面最终会形成一个对象 :document ,页面里面的所有的元素(如 标签 ) 最终都会转换成 js 里面的对象。 1.1 获取页面的元素&#xff08;通过选择器&#xff0…...

【玩转client-go】如何获取 Kubernetes API 客户端的 *rest.Config 对象

目录 1. 使用 kubeconfig 文件 2. 使用 Kubernetes 集群内的 Service Account 3. 直接指定 API Server 的地址和认证信息 4. 使用 genericclioptions.NewConfigFlags() 总结 在使用 Kubernetes API 客户端——client-go 的过程中&#xff0c;我们通常需要获取 *rest.Config 配…...

保护模式段描述符

目前为止&#xff0c;内存还是分段模式&#xff0c;所以想要保护内存&#xff0c;就需要保存段。由于CPU的扩展导致了32位的段基地址和段内偏移&#xff0c;所以16位的段寄存器就无法放下这些信息。现在就需要把这些信息放到内存中&#xff0c;这些信息被封装成特定的段描述符。…...

两个数组的交集

给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 思路&#xff1a; 由于这道题目&#xff0c;输出结果中的每个元素一定是唯一的&#xff0c;也就是说输出的结果的去重的&#xff0c; 同时可…...

原创文章生成器在线版-ai写作生成器

随着人工智能技术的迅猛发展&#xff0c;越来越多的人开始意识到&#xff0c;利用AI可以实现许多以前不可能想象的事情。其中&#xff0c;一种最能体现人工智能技术优势的应用就是“ai原创文章生成器”。它可以为营销从业者提供一种全新的营销推广方式。 那么&#xff0c;什么是…...

打造高性能CSS的九个技巧我是这么做的

在Web开发中&#xff0c;CSS是不可或缺的一部分。但是&#xff0c;如果CSS代码不够优化&#xff0c;会导致页面加载速度变慢&#xff0c;用户体验下降。以下是九个技巧&#xff0c;用于打造高性能的CSS代码。 避免使用通配符选择器&#xff1a;通配符选择器会匹配页面中的所有…...

python tqdm教程

文章目录 1. 搭配迭代器使用2. 设置动态数据打印3. 中途打印不干扰进度条4. 在jupyter中打印不干扰进度条5. 使用gui显示进度条6. 双循环嵌套进度条7. enumerate和tqdm搭配使用参考文献tqdm是python中打印进度条的一个简易工具包,可以方便查看循环的进度。具体见tqdm文档 1. …...

深度学习 - 41.Word2vec、EGES 负采样实现 By Keras

目录 一.引言 二.实现思路 1.样本构建 2.Word2vec 架构 3.EGES 架构 4.基于 NEG 的 Word2vec 架构 三.Keras 实现 Word2vec 1.样本构建 2.模型构建 3.向量获取 四.keras 实现 EGES 1.样本构建 2.模型构建 3.Dot Layer 详解 3.1 init 方法 3.2 call 方法 3.3 完…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...