Go微服务: 理解分布式锁

news2025/1/16 5:54:01

概述

  • 我们先看一个场景,到了双11,我们的商户又开始卖商品啦
  • 但是,我们的库存是有限的,如果超卖了,可能平台就会涉及相关法律责任了
  • 所以,我们的库存扣除问题,一定是一个非常经典的问题
  • 先看上图,我们库存服务部署在一台机器上,现在有 2个 Goroutine
  • 这个库存是被并发读取的,但是读取后扣除明显是一个异步的问题
  • 用 Goroutine 来模拟并发, 2个Goroutine 分别是G1, G2 都去下单,扣减库存
  • 一共100件,2个Goroutine查询的时候很可能都还是100
  • 在计算扣除的时候都是 100 - 10 = 90 这个肯定不对,应该最终的结果是 80
  • 引发这个问题的原因是:并发查询和扣减一起操作,无法得到时时的真实的数据
  • 当时查询的数据和时时的数据并不是同一个数据
  • 现在,我们用分布式锁来解决这个问题
  • 分布式锁好比一个独立的第三方,是可信任的,从计算机角度来说,这是一把锁
  • 我们约定谁拿到了这把锁就可以扣减库存,查询库存
  • 在查询之前先获得锁,没有锁你连查询都不能查询,就可以保证顺序执行
  • 抢到了锁,执行完自己的操作,就要释放锁

分布式锁的发展

  • 上面蓝色的圈代表2个 Goroutine
  • 现在的场景是在一个服务器上,在服务器上会有一些服务,其中2个服务都有 Goroutine
  • 我们的这个锁是操作系统提供的,它针对的是操作系统的这把锁
  • 这是一开始go语言当中的这一部分锁的范畴
  • 再看这张图,当我们一台服务器不够的时候,比如双11活动, 这种一台服务器,它肯定是扛不住的
  • 在我们这个订单的web服务问题下,在多个服务器集群的场景下,Goroutine 不能实现跨服务器的锁
  • 因为是两个完全物理隔绝的服务器,两个完全不一样的硬件,为了高并发,必须提供更多的服务器
  • 为了解决这个问题,分布式锁应运而生
  • 看这里简化的图,就是说服务器一和服务器,我们这个锁并不在服务器上,是单独的一把锁
  • 这个锁不属于任何一个服务器,是一个公共的第三方,任何服务抢到就可以优先执行任务
  • 就是说你这个服务器1和服务器2,谁先抢到这把分布式的锁,谁就执行这个任务
  • 各个服务器都是平权的,要想争夺公共的资源,谁优先抢到了,就是谁的

常见的锁和分布式锁的区别


1 ) 常见的锁

  • 第一个就是golong程序里面用到的锁
    • Mutex 互斥锁,也叫独占锁,就是我占有了你就不能占有,除非被释放
    • RWMutex 读共享,写互斥的锁, 当大家一起读的时候,这个锁的性能是不错的,如果是写,就是互斥的
      • 适合读多写少的场景,比如读博客人多,写博客人少;看视频人多,发视频人少
    • 以上是golang程序中两种类型的锁
  • 第二个是 mysql 里面的 悲观锁和乐观锁
    • 这都是赋予人的这种情绪上的描述
    • mysql里一般有什么锁呢?排他锁, 共享锁,表锁,行锁等等,这些呢就容易混
    • 1 )而这里的悲观锁是一种从思想上处理并发的一种方式
    • 比如,悲观所和某人性格有关,比如这个人就是悲悲的,他总是负面情绪很大
    • 就是没有什么正能量,在数据库里也是一样,总是会认为会和别人发生冲突,总觉别人会修改它的数据
    • 既然这样,我就在修改的时候,拿一把锁给他锁住,别人谁也别想用,就是这么个情绪
    • 通常这把锁就是排他锁,因为说只有我能用,别人不能用,别人能用,我就不能用,它就是一个排他的
    • mysql的悲观锁对应一句笑话:“总有刁民想害朕”,就是一直觉得总有人和我竞争,抢夺资源
    • 2 )与之相对应的就是说乐观锁,它就是赋予人的这种乐观情绪,什么事也不放在心上。
    • 但是mysql它一定要解决这个数据的竞争问题,乐观锁用一个version字段去记录这一条记录
    • 这记录,大家都可以修改,但总有一人会修改成功,与 version 匹配的,在某些场景下比悲观锁好一些
    • 但是,有的时候也分业务场景,具体的性能要根据压测,很多在上线之前都会有压测和相关指标
    • 在编码阶段不会超过整个产品研发三分之一的时间,其他的时间可能在
    • 准备环境,准备case,准备压测的case,还有性能,还有监控,还有的运维,以及应对后续突发流量等
    • 很多预案都要考虑到,并不是说我们把代码写完了就结束了

2 ) 分布式锁

  • 第三个是redis的分布式锁
    • 这是在mysql的库存服务的一张表,它的 id 是66,数量是100
    • 库存服务1想要拿到id是 1 的这个记录的锁
    • 库存服务2也想要拿到id是 1 的这个记录的锁
    • 这个锁是mysql提供的,悲观锁它就是一个互斥锁
    • 如果你用悲观锁,那就是永远是这么一个服务,被一方拿到之后就被锁定
    • 只有一方执行完了,退出了,才会被其他服务锁定
    • 如果有更多的服务,就排队一个一个来
    • 谁抢到,谁先执行,抢不到就在旁边等着
    • 所以它不适合并发场景要求相对高的情况

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1810504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《Vue》系列文章目录

Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以…

实现3-8译码器①

描述 下表是74HC138译码器的功能表. E3 E2_n E1_n A2 A1 A0 Y0_n Y1_n Y2_n Y3_n Y4_n Y5_n Y6_n Y7_n x 1 x x x x 1 1 1 1 1 1 1 1 x x 1 x x x 1 1 1 1 1 1 1 1 0 x x x x x 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 …

C语言之argc、argv与main函数的传参

一 :谁给main函数传参 (1)调用main函数所在的程序的它的父进程给main函数传参,并且接收main函数的返回值 二 :为什么需要给main函数传参 (1)首先mian函数不传承是可以的,也就是说它的…

01-Linux网络设置

1、查看及测试网络 查看及测试网络配置是管理Linux网络服务的第一步,其中的大多数命令以普通用户的权限就可以完成操作,但普通用户在执行/sbin目录中的命令时需要指定命令文件的决对路径。 1.1 查看网络接口地址 主机的网卡通常称为网络接口&#xff…

轻松驾驭视频节奏:灵活调整视频播放速度,让视频内容更出彩!

视频已经成为了我们生活中不可或缺的一部分。无论是观看电影、电视剧,还是浏览短视频、直播内容,我们都希望能够根据自己的喜好和需求来调整视频的播放速度,甚至精确控制每一秒的播放内容。那么,如何轻松实现这一愿望呢&#xff1…

torchmetrics,一个无敌的 Python 库!

更多Python学习内容:ipengtao.com 大家好,今天为大家分享一个无敌的 Python 库 - torchmetrics。 Github地址:https://github.com/Lightning-AI/torchmetrics 在深度学习和机器学习项目中,模型评估是一个至关重要的环节。为了准确…

Springboot结合redis实现关注推送

关注推送 Feed流的模式 Timeline:不做内容筛选,简单的按照内容发布时间排序。常用于好友与关注。例如朋友圈的时间发布排序。 优点:信息全面,不会有缺失。并且实现也相对简单 缺点:信息噪音较多,用户不一定感兴趣,内容获取效率…

打造精细化运维新玩法(三)

实践SLO,概括下就是在相对标准、统一的框架下指导和推动服务质量的数字化建设,形成对组织有价值的数据资产和流程规范。借用在人工智能和机器学习领域的观点,算法的上限受限于数据质量的好坏,所以从源头上建设高质量的数据非常重要…

【电赛】STM32-PID直流减速电机小车【寻迹+避障+跟随】【更新ing】

一.需求分析 1.主控:STM32C8T6(没什么好说的哈哈) 2.电机:JAG25-370电机 【问】为什么要用直流减速电机?? PID控制器需要依靠精确的反馈信号来调整其输出,确保电机按照预定的速度和位置运行…

独立游戏之路:Tap篇 -- Unity 集成 TapTap 广告详细步骤

Unity 集成 TapADN 广告详细步骤 前言一、TapTap 广告介绍二、集成 TapTap 广告的步骤2.1 进入广告后台2.2 创建广告计划2.3 选择广告类型三、代码集成3.1 下载SDK3.2 工程配置3.3 源码分享四、常见问题4.1 有展现量没有预估收益 /eCPM 波动大?4.2 新建正式媒体找不到预约游戏…

介绍Linux

目录 1.什么是操作系统 2.现实生活中的操作系统 3.操作系统的发展史 4.操作系统的发展 Linux的不同版本以及应用领域 1.Linux内核及发行版介绍 <1>Linux内核版本 <2>Linux发行版本 2.应用领域 个⼈桌⾯领域的应⽤ 服务器领域 嵌⼊式领域 3.文件和目录 …

HDFS 读写数据流程

优质博文&#xff1a;IT-BLOG-CN 一、HDFS 写数据流程 HDFS 文件写入流程图如下&#xff1a;三个模块&#xff08;客户端、NameNode、DataNode&#xff09; 【1】校验&#xff1a; 客户端通过 DistributedFileSystem 模块向 NameNode 请求上传文件&#xff0c;NameNode 会检…

Vue 面试通杀秘籍

理论篇&#xff1a; 1. 说说对 Vue 渐进式框架的理解&#xff08;腾讯医典&#xff09; a) 渐进式的含义&#xff1a; 主张最少, 没有多做职责之外的事 b) Vue 有些方面是不如 React&#xff0c;不如 Angular.但它是渐进的&#xff0c;没有强主张&#xff0c; 你可以在原有…

Java面向对象-Object类的toString方法、equals方法

Java面向对象-Object类的toString方法、equals方法 一、toString二、equals三、总结 一、toString Object的toString方法。 方法的原理&#xff1a; 现在使用toString方法的时候&#xff0c;打印出来的内容不友好。 现在想要知道对象的信息。 出现的问题&#xff1a;子类Stu…

SAP Build 2 PDF数据提取与决策树(未完成)

0. 安装desktop agent 在后续过程中发现要预先安装desktop agent&#xff0c;否则没法运行自动化流程… 0.1 agent下载 参考官方文档说明 https://help.sap.com/docs/build-process-automation/sap-build-process-automation/create-user-in-rbsc-download-repository?loca…

AI办公自动化:用Kimi批量在Excel文件名中加入日期

工作任务&#xff1a;在一个文件夹中所有的Excel文件后面加上一个日期 在Kimi中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;写一个Python脚本&#xff0c;具体步骤如下&#xff1a; 打开文件夹&#xff1a;F:\AI自媒体内容\AI行业数据分析\投融资 读取里面所…

18.2 HTTP服务器-处理函数、响应404错误

1. 处理函数 处理来自客户端的请求&#xff0c;并回之以特定的响应&#xff0c;这是处理函数的主要任务。在处理函数中&#xff0c;我们通常会完成如下工作&#xff1a; 验证请求路径 http.Request.URL.Pathhttp.NotFound(...) 当请求没有对应的处理函数时&#xff0c;返回4…

机器学习笔记:label smoothing

在传统的分类任务中&#xff0c;我们通常使用硬标签&#xff08;hard labels&#xff09; 即如果一个样本属于某个类别&#xff0c;其对应的标签就是一个全0的向量&#xff0c;除了表示这个类别的位置为1。例如&#xff0c;在一个3类分类任务中&#xff0c;某个样本的标签可能是…

【Vue】购物车案例-构建项目

脚手架新建项目 (注意&#xff1a;勾选vuex) 版本说明&#xff1a; vue2 vue-router3 vuex3 vue3 vue-router4 vuex4/pinia vue create vue-cart-demo需要勾选上vuex&#xff0c;由于这个项目只有一个页面&#xff0c;vuex可勾可不勾 将原本src内容清空&#xff0c;替换成教学…

缓存更新策略中级总结

背景 看到好些人在写更新缓存数据代码时&#xff0c;先删除缓存&#xff0c;然后再更新数据库&#xff0c;而后续的操作会把数据再装载的缓存中。然而&#xff0c;这个是逻辑是错误的。试想&#xff0c;两个并发操作&#xff0c;一个是更新操作&#xff0c;另一个是查询操作…