分布式系统中如何实现临界资源的互斥访问?

摘要:一次仅允许一个进程使用的资源称为临界资源。

网络时代,购物、社交等之前只能在线下进行的活动,如今都可以在网络上完成。为了促进消费,电商网、网络店铺经常推出商品限定数量内的”秒杀”,”抢购”活动,类似的临界资源访问还有我们生活中常见的微信多人抢红包。这种临界资源,多人访问的情况,如何保证避免一个资源被多人(一人以上)互斥访问呢?

临界资源

多道程序系统中存在许多进程,它们共享各种资源,然而有很多资源一次只能供一个进程使用。一次仅允许一个进程使用的资源称为临界资源。

上面我们提到的在抢购中对商品提交订单,微信中打开多人红包都属于这种临界资源的访问,一次只允许一个进程使用。

临界资源互斥访问

分布式互斥是随着分布式系统的出现而出现的,并随着分布式系统理论发展而发展。在分布式系统中,很多进程能够在微观上并行执行。但由于共享资源的有限性,以及全局数据要求的一致性,一些临界资源的访问需要以互斥的方式实现同步。

Java原生锁

在传统单机部署的情况下,可以使用Java并发处理相关的API(如ReentrantLock或synchronized)进行互斥控制。这种Java提供的原生锁机制可以保证在同一个Java虚拟机进程内的多个线程同步执行,避免出现无序现象。

但在互联网场景,特别是抢购活动中,随着整个系统的并发访问飙升,需要多台机器并发运行,以应对用户井喷式访问,假设此时多个用户的请求同时到来,但落在了不同的机器上,虽然这两个请求是可以同时执行,但是因为两个机器运行在两个不同的Java虚拟机里面,他们加的锁只对属于自己Java虚拟机里面的线程有效,对于其他Java虚拟机的线程是无效的。因此,Java提供的原生锁机制在多机部署场景下失效了,这是因为两台机器加的锁不是同一个锁(两个锁在不同的Java虚拟机里面),这样便会出现库存超卖的现象。

分布式锁

基于存在的现状,我们只要保证多台机器加的锁是同一个锁,用加锁的方式对某种资源进行顺序访问控制。这就需要分布式锁登场了。

分布式锁是一种解决分布式临界资源并发读写的一种技术,对分布式应用加锁,能够避免出现库存超卖及无序访问等现象。

分布式锁的思路是:在整个系统提供一个全局、唯一的获取锁的”东西”,然后每个系统在需要加锁时,都去问这个”东西”拿到一把锁,这样不同的系统拿到的就可以认为是同一把锁。

当前分布式加锁主要有三种方式:(磁盘)数据库、缓存数据库、Zookeeper。

用 Redis 实现分布式锁

使用Redis类型的缓存实例实现分布式加锁,有几大优势:

• 加锁操作简单,使用SET、GET、DEL等几条简单命令即可实现锁的获取和释放。

• 性能优越,缓存数据的读写优于磁盘数据库与Zookeeper。

使用redis的del方法即可实现锁的释放。

相对于传统redis,如今各大云厂商也都推出了redis 云服务,以即开即用、安全可靠、弹性扩容、便捷管理等特点受到软件开发企业和开发者的欢迎。

参考资料

李美安. 普适分布式互斥算法及应用[D]. 电子科技大学, 2006.

Original: https://www.cnblogs.com/huaweiyun/p/16719334.html
Author: 华为云开发者联盟
Title: 分布式系统中如何实现临界资源的互斥访问?

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/616764/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 还有人不懂布隆过滤器吗?

    还有人不懂布隆过滤器吗? 1.介绍 我们在使用缓存的时候都会不可避免的考虑到如何应对 缓存雪&#x5D29…

    Java 2023年6月8日
    0107
  • Java8 Stream流式编程,极大解放你的生产力!

    java8自带常用的函数式接口 Predicate<t> boolean test(T t)</t> 传入一个参数返回boolean值 Consumer&l…

    Java 2023年5月29日
    074
  • (java)数据接口与算法-时间复杂度和空间复杂度

    原文链接:https://blog.csdn.net/uftjtt/article/details/802454311. 基本概念数据结构到底是什么呢?我们先来谈谈什么叫数据。数据…

    Java 2023年6月9日
    080
  • java对象与Json字符串之间的转化(fastjson)

    首先引入jar包 在pom.xml文件里加入下面依赖: 创建一个Person类(方面下面使用) 实现java对象与Json字符串之间的转化 public class Test { …

    Java 2023年5月29日
    066
  • springboot 整合druid–Java 注解+代码配置 Bean

    1.pom.xml引入 2.druid配置类: 3.构建DataSource对象 4.配置监控拦截器 5.配置Druid监控视图 6.去除druid监控页面广告 7.启动类加@Se…

    Java 2023年6月6日
    0104
  • 如何下载 blob 地址的视频资源

    如何下载视频资源以blob:http开头的资源 一、问题场景 想下载知乎视频资源,却发现视频链接是这个样子的 blob:https://v.vzuu.com/b6146956-6e…

    Java 2023年6月9日
    0107
  • 设计模式

    设计模式 工厂模式 public class Test { public static void main(String[] args) { Computer c1 =Comput…

    Java 2023年6月9日
    077
  • 2.69分钟完成BERT训练!新发CANN 5.0加持

    摘要:快,着实有点快。 现在,经典模型BERT只需2.69分钟、ResNet只需16秒。 啪的一下,就能完成训练! 快,着实有点快。 现在,经典模型BERT只需 2.69分钟、Re…

    Java 2023年6月15日
    072
  • elasticsearch7.6.1版本+jsoup爬取京东商品数据并使用

    实战: elasticsearch7.6.1版本+jsoup爬取京东商品数据并使用 前言 本文的实战需求是:从京东网页上拉去对应【关键字】的数据且存放到elasticsearch(…

    Java 2023年6月5日
    084
  • Effective Java 第三版——77. 不要忽略异常

    Tips书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code注意,书中的有些代码里方法是基于Java 9…

    Java 2023年5月29日
    0103
  • NotePad++的基本使用方法

    第一步:下载完成后的基本设置 设置>>首选项 进行如下操作 这个设置主要是为了在NotePad++的页面中可以输入汉字 第二步:在文件夹中新建文本文档 将后面的后缀改成…

    Java 2023年6月16日
    089
  • 内存

    内存分析 Java虚拟机的内存大分为三个区域:栈,堆和方法区,其实细分是只有两个,因为方法区也是在堆里的。 栈(stack): 每个方法被调用都会创建一个栈帧,用以存储局部变量、操…

    Java 2023年6月5日
    089
  • nginx 转发 minio 服务

    现有3台服务器 192.168.1.225 nginx 192.168.1.229 其他应用服务 192.168.1.234 minio nginx配置文件如下 1 # For m…

    Java 2023年5月30日
    083
  • Java Servlet单元测试

    Java Servlet单元测试 1. 解决痛点 虽然目前主流的开发方式,很多都是通过controll或者微服务提供api.但是不免还是需要写几个 servlet完成接口开发.按照…

    Java 2023年6月13日
    091
  • java中scanner获取char字符类型的方法

    java中基本数据类型的输⼊包括整形的输⼊: in.nextInt();单精度浮点型: in.nextFloat();双精度浮点型: in.nextDouble();字符串类型: …

    Java 2023年6月9日
    068
  • JUC入门

    参考 1.什么是JUC 1.JUC简介 JUC就是java.util.concurrent工具包的简称,这是一个处理线程的工具包,JDK1.5开始出现的。 2.进程和线程 进程:资…

    Java 2023年6月15日
    077
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球