iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >架构师带你玩转分布式锁
  • 614
分享到

架构师带你玩转分布式锁

2023-06-05 05:06:20 614人浏览 薄情痞子
摘要

大多数互联网系统都是分布式部署的,分布式部署确实能带来性能和效率上的提升,但为此,我们就需要多解决一个分布式环境下,数据一致性的问题。当某个资源在多系统之间,具有共享性的时候,为了保证大家访问这个资源数据是一致的,那么就必须要求在同一时刻只

大多数互联网系统都是分布式部署的,分布式部署确实能带来性能和效率上的提升,但为此,我们就需要多解决一个分布式环境下,数据一致性的问题。

当某个资源在多系统之间,具有共享性的时候,为了保证大家访问这个资源数据是一致的,那么就必须要求在同一时刻只能被一个客户端处理,不能并发的执行,否者就会出现同一时刻有人写有人读,大家访问到的数据就不一致了。

1、我们为什么需要分布式

在单机时代,虽然不需要分布式锁,但也面临过类似的问题,只不过在单机的情况下,如果有多个线程要同时访问某个共享资源的时候,我们可以采用线程间加锁的机制,即当某个线程获取到这个资源后,就立即对这个资源进行加锁,当使用完资源之后,再解锁,其它线程就可以接着使用了。例如,在JAVA中,甚至专门提供了一些处理锁机制的一些api(synchronize/Lock等)。

但是到了分布式系统的时代,这种线程之间的锁机制,就没作用了,系统可能会有多份并且部署在不同的机器上,这些资源已经不是在线程之间共享了,而是属于进程之间共享的资源。

因此,为了解决这个问题,我们就必须引入「分布式锁」。

分布式锁,是指在分布式的部署环境下,通过锁机制来让多客户端互斥的对共享资源进行访问。

分布式锁要满足哪些要求呢?

  • 排他性:在同一时间只会有一个客户端能获取到锁,其它客户端无法同时获取

  • 避免死锁:这把锁在一段有限的时间之后,一定会被释放(正常释放或异常释放)

  • 高可用:获取或释放锁的机制必须高可用且性能佳

讲完了背景和理论,那我们接下来再看一下分布式锁的具体分类和实际运用。

二、分布式锁的实现方式有哪些?

目前主流的有三种,从实现的复杂度上来看,从上往下难度依次增加:

无论哪种方式,其实都不完美,依旧要根据咱们业务的实际场景来选择。

基于数据库实现:

基于数据库来做分布式锁的话,通常有两种做法:

  • 基于数据库的乐观锁

  • 基于数据库的悲观锁

我们先来看一下如何基于「乐观锁」来实现:

乐观锁机制其实就是在数据库表中引入一个版本号(version)字段来实现的。

当我们要从数据库中读取数据的时候,同时把这个version字段也读出来,如果要对读出来的数据进行更新后写回数据库,则需要将version加1,同时将新的数据与新的version更新到数据表中,且必须在更新的时候同时检查目前数据库里version值是不是之前的那个version,如果是,则正常更新。如果不是,则更新失败,说明在这个过程中有其它的进程去更新过数据了。

下面找图举例:

架构师带你玩转分布式锁
(图片来源网络

如图,假设同一个账户,用户A和用户B都要去进行取款操作,账户的原始余额是2000,用户A要去取1500,用户B要去取1000,如果没有锁机制的话,在并发的情况下,可能会出现余额同时被扣1500和1000,导致最终余额的不正确甚至是负数。但如果这里用到乐观锁机制,当两个用户去数据库中读取余额的时候,除了读取到2000余额以外,还读取了当前的版本号version=1,等用户A或用户B去修改数据库余额的时候,无论谁先操作,都会将版本号加1,即version=2,那么另外一个用户去更新的时候就发现版本号不对,已经变成2了,不是当初读出来时候的1,那么本次更新失败,就得重新去读取最新的数据库余额。

通过上面这个例子可以看出来,使用「乐观锁」机制,必须得满足:

(1)锁服务要有递增的版本号version
(2)每次更新数据的时候都必须先判断版本号对不对,然后再写入新的版本号

我们再来看一下如何基于「悲观锁」来实现:

悲观锁也叫作排它锁,在Mysql中是基于 for update 来实现加锁的,例如:

//锁定的方法-伪代码public boolean lock(){    connection.setAutoCommit(false)    for(){        result =         select * from user where         id = 100 for update;        if(result){         //结果不为空,        //则说明获取到了锁            return true;        }        //没有获取到锁,继续获取        sleep(1000);    }    return false;}//释放锁-伪代码connection.commit();

上面的示例中,user表中,id是主键,通过 for update 操作,数据库在查询的时候就会给这条记录加上排它锁。

(需要注意的是,在InnoDB中只有字段加了索引的,才会是行级锁,否者是表级锁,所以这个id字段要加索引)

当这条记录加上排它锁之后,其它线程是无法操作这条记录的。

那么,这样的话,我们就可以认为获得了排它锁的这个线程是拥有了分布式锁,然后就可以执行我们想要做的业务逻辑,当逻辑完成之后,再调用上述释放锁的语句即可。

基于Redis实现

基于Redis实现的锁机制,主要是依赖redis自身的原子操作,例如:

SET user_key user_value NX PX 100

redis从2.6.12版本开始,SET命令才支持这些参数:

NX:只在在键不存在时,才对键进行设置操作,SET key value NX 效果等同于 SETNX key value 

PX millisecond:设置键的过期时间为millisecond毫秒,当超过这个时间后,设置的键会自动失效

上述代码示例是指:

当redis中不存在user_key这个键的时候,才会去设置一个user_key键,并且给这个键的值设置为 user_value,且这个键的存活时间为100ms

为什么这个命令可以帮我们实现锁机制呢?

因为这个命令是只有在某个key不存在的时候,才会执行成功。那么当多个进程同时并发的去设置同一个key的时候,就永远只会有一个进程成功。

当某个进程设置成功之后,就可以去执行业务逻辑了,等业务逻辑执行完毕之后,再去进行解锁。

解锁很简单,只需要删除这个key就可以了,不过删除之前需要判断,这个key对应的value是当初自己设置的那个。

另外,针对redis集群模式的分布式锁,可以采用redis的Redlock机制。

基于ZooKeeper实现

其实基于ZooKeeper,就是使用它的临时有序节点来实现的分布式锁。

原理就是:当某客户端要进行逻辑的加锁时,就在zookeeper上的某个指定节点的目录下,去生成一个唯一的临时有序节点, 然后判断自己是否是这些有序节点中序号最小的一个,如果是,则算是获取了锁。如果不是,则说明没有获取到锁,那么就需要在序列中找到比自己小的那个节点,并对其调用exist()方法,对其注册事件监听,当监听到这个节点被删除了,那就再去判断一次自己当初创建的节点是否变成了序列中最小的。如果是,则获取锁,如果不是,则重复上述步骤。

当释放锁的时候,只需将这个临时节点删除即可。

架构师带你玩转分布式锁

(图片来自网络)

如图,locker是一个持久节点,node_1/node_2/…/node_n 就是上面说的临时节点,由客户端client去创建的。

client_1/client_2/…/clien_n 都是想去获取锁的客户端。以client_1为例,它想去获取分布式锁,则需要跑到locker下面去创建临时节点(假如是node_1)创建完毕后,看一下自己的节点序号是否是locker下面最小的,如果是,则获取了锁。如果不是,则去找到比自己小的那个节点(假如是node_2),找到后,就监听node_2,直到node_2被删除,那么就开始再次判断自己的node_1是不是序列中最小的,如果是,则获取锁,如果还不是,则继续找一下一个节点。

以上,就讲完了为什么我们需要分布式锁这个技术,以及分布式锁中常见的三种机制,欢迎大家一起交流。

出处:https://mp.weixin.qq.com/s/29FI3t7BYyRw3yjB_X1phA

--结束END--

本文标题: 架构师带你玩转分布式锁

本文链接: http://www.lsjlt.com/news/241588.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 架构师带你玩转分布式锁
    大多数互联网系统都是分布式部署的,分布式部署确实能带来性能和效率上的提升,但为此,我们就需要多解决一个分布式环境下,数据一致性的问题。当某个资源在多系统之间,具有共享性的时候,为了保证大家访问这个资源数据是一致的,那么就必须要求在同一时刻只...
    99+
    2023-06-05
  • 带你轻松掌握Redis分布式锁
    目录1. 什么是分布式锁2. 分布式锁该具备的特性3. 基于数据库做分布式锁4. 基于Redis做分布式锁4.1 超时问题4.2 可重入锁4.3 集群环境的缺陷4.4 Redlock...
    99+
    2024-04-02
  • 一文带你搞懂Redis分布式锁
    目录1、分布式锁简介2、setnx3、Redis-分布式锁-阶段14、Redis-分布式锁-阶段25、Redis-分布式锁-阶段36、Redis-分布式锁-阶段47、Redis-分布...
    99+
    2024-04-02
  • ASP分布式架构,你真的了解吗?
    ASP(Active Server Pages)是一种动态网页开发技术,它允许开发人员使用服务器端脚本语言生成动态内容。ASP分布式架构是在ASP技术的基础上,通过分布式技术实现的一种多节点协作的架构。在本文中,我们将深入探讨ASP分布式架...
    99+
    2023-06-14
    分布式 面试 函数
  • 从架构思维角度分析分布式锁方案
    目录1 介绍2 关于分布式锁3 分布式锁的实现方案3.1  基于数据库实现3.1.1 乐观锁的实现方式3.1.2 悲观锁的实现方式3.1.3 数据库锁的优缺点3.2基于Re...
    99+
    2024-04-02
  • 带你分分钟玩转C语言指针
    目录何为指针数组指针指针数组字符串数组数组指针的sao气操作二级指针函数指针指针函数文件指针总结何为指针 指针这玩意说白了,就是用来存储一个变量地址的东东 如图: (编辑器为vc2...
    99+
    2024-04-02
  • springmvc+mybatis +Jeesz 分布式架构
    spring mvcSpring框架(框架即:编程注解+xml配置的方式)MVC是Spring框架的一大特征,Spring框架有三大特征(IOC(依赖注入),AOP(面向切面),MVC(建模M-视图V-控制器C)。框架一般用于团队...
    99+
    2023-06-03
  • 阿里架构师:带你快速理解微服务架构,理解微服务架构的核心
    什么是微服务首先微服务并没有一个官方的定义,想要直接描述微服务比较困难,我们可以通过对比传统WEB应用,来理解什么是微服务。传统的WEB应用核心分为业务逻辑、适配器以及API或通过UI访问的WEB界面。业务逻辑定义业务流程、业务规则以及领域...
    99+
    2023-06-04
  • 一篇文章带你用C语言玩转结构体
    目录前言一、结构体的声明与定义1.结构体的声明2.结构成员的类型3.结构体的定义二、初始化结构体三、访问结构体成员四、结构体嵌套五、结构体指针六、结构体传参总结前言 C语言提供了不同...
    99+
    2024-04-02
  • ASP 框架和 Django:如何选择适合你的分布式架构?
    随着互联网技术的快速发展,分布式架构已经成为了现代应用程序开发的核心。在这个多变的世界里,选择一个合适的框架是非常重要的。在这篇文章中,我们将探讨ASP框架和Django框架的区别,以及如何选择适合你的分布式架构。 ASP框架 ASP框架是...
    99+
    2023-07-08
    框架 django 分布式
  • GO语言分布式系统架构设计,你了解吗?
    随着互联网的快速发展,分布式系统逐渐成为了现代软件开发中的热门话题。GO语言是一门高效、强类型、支持并发编程的开源编程语言,由于其天生的并发能力,越来越多的开发者开始使用GO语言来构建分布式系统。在本文中,我们将探讨GO语言分布式系统的架...
    99+
    2023-06-29
    分布式 面试 教程
  • 分别使用Redis、MySQL、ZooKeeper构建分布式锁
    文章目录 前言一、分布式锁简介二、分布式锁要求三、实现方案四、数据库分布式锁1、悲观锁2、乐观锁 五、Zookeeper分布式锁1、引入Curator和ZooKeeper2、配置ZooKe...
    99+
    2023-09-16
    分布式 redis mysql
  • PHP 微服务架构:解锁分布式系统的强大力量
    什么是 PHP 微服务架构? PHP 微服务架构是一种将大型单体应用程序分解为一组较小的、相互独立的服务的体系结构。这些服务称为微服务,每个服务都负责应用程序的特定功能。微服务通常通过轻量级协议(如 HTTP 或 gRPC)进行通信。 ...
    99+
    2024-02-16
    PHP 微服务 分布式系统 可扩展性 敏捷性 可靠性
  • 分布式数据库如何玩转HTAP场景
    这篇文章给大家介绍分布式数据库如何玩转HTAP场景,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。传统数据库架构面临的痛点1. 集群分散不利于整合,数据结构同步工作量大第一招:...
    99+
    2024-04-02
  • 怎样分析JEESZ分布式架构平台
    这期内容当中小编将会给大家带来有关怎样分析JEESZ分布式架构平台,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1.   项目核心代码结构截图<!-- jeesz 工具jar -...
    99+
    2023-06-03
  • Java和Spring框架如何帮助你构建分布式系统?
    随着互联网的不断发展,分布式系统越来越普遍。分布式系统是指由多个独立计算机组成的系统,这些计算机通过网络进行协作,共同完成一项任务。例如,电子商务网站需要处理海量的订单、支付和物流信息,而这些信息需要通过不同的服务器进行处理。分布式系统可...
    99+
    2023-06-18
    分布式 spring linux
  • PHP 分布式系统架构与实践
    php 分布式系统架构通过将不同组件分布在网络互联的机器上实现可伸缩性、性能和容错性。该架构包括应用服务器、消息队列、数据库、缓存和负载均衡器。将 php 应用迁移到分布式架构的步骤包括...
    99+
    2024-05-04
    php 分布式系统 laravel docker 库存管理
  • Java分布式架构原理是什么
    这篇文章主要介绍“Java分布式架构原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java分布式架构原理是什么”文章能帮助大家解决问题。1. 分布式术语1.1. 异常服务器宕机内存错误、服...
    99+
    2023-06-02
  • 分布式微服务云架构实例分析
    今天就跟大家聊聊有关分布式微服务云架构实例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。源码结构JEESZ驱动式项目构建内置高效可靠的代码生成器支持多种数据模型,根据数据库表生成...
    99+
    2023-06-05
  • Hadoop分布式文件系统HDFS架构分析
    本文小编为大家详细介绍“Hadoop分布式文件系统HDFS架构分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Hadoop分布式文件系统HDFS架构分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Hadoo...
    99+
    2023-06-27
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作