后端调优——分布式锁选型——入门

news2024/11/13 22:37:09

文章目录

    • 引言
    • 正文
      • 分布式锁的定义
      • 分布式锁的具体应用场景
      • 如何实现分布式锁
        • 主动轮询型分布式锁
          • 实现思路
          • 一、MySQL分布式锁
          • 二、Redis分布式锁
        • 监听回调型分布式锁
          • Etcd分布式锁
          • Zookeeper分布式锁
      • 锁的对比
    • 总结

引言

  • 最近面试,一直被问到分布式锁,然后仅仅只知道redis,了解的不够深刻,这里做一个深入的总结

正文

分布式锁的定义

  • 在Java多线程编程中,使用Synchronized来实现多个线程之间有序地访问共享资源。相似地定义,分布式锁针对多个机器而言的,控制他们有序访问共享的资源节点。

  • 一般是通过第三方组件,控制多个机器有序访问,常见的有

    • MySQL
    • Redis
    • Etcd
    • Zookeeper
  • 基于redis中的分布式锁的命令“setnx key value px expire_time”,分布式锁具有如下性质

    • 独占性:同一把锁,某一个时刻只能被一个机器占用。
    • 健壮性:不会轻易死锁,如果持有锁的机器偶然死机了,也能够通过过期时间进行兜底,顺利解锁,其他机器持有锁
    • 对称性:谁加锁,谁解锁,就像redis中的value是每一个线程的uuid一样。

分布式锁的具体应用场景

多任务调度场景

  • 多个任务调度器在不同节点上运行,从任务队列中取出任务执行
    • 分布式锁能够保证每一个任务都只会被调用一次

电子商务场景

  • 电子商务系统中,创建订单的操作会涉及检查库存、支付服务以及物流服务等多个阶段,通过分布式锁,保证这些服务按照指定的顺序执行,保证数据的一致性。

如何实现分布式锁

  • 分布式锁的实现模型主要分为两种
    • 主动轮询型
      • 取锁方会持续地向分布式锁服务发出获取锁的动作,如果锁已经被占用了,会不断发起轮询请求,直到取到锁为主
      • 常见类型
        • MySQL、Redis
    • 监听回调型
      • 在取锁方发现锁已经被其他对象占用时,会创建watcher(监听器)来订阅锁的释放事件,随后不主动获取锁
      • 当锁被释放的时候,取锁方能通过之前创建的watcher监听到这一变化,发起竞争锁的尝试动作。
      • 常见类型
        • Etcd、Zookeeper
主动轮询型分布式锁
实现思路

使用一个数据变量来表示锁,redis中类似一个String对象,具体流程如下

  • 创建一个变量lock表示一把锁,lock是锁的名称,lock的内容是持有锁的具体对象

    • 加锁,创建lock对象,并将自身的标识写入到lock中
    • 解锁,删除lock对象
    • 轮询锁,如果锁已经被其他人获取,就持续性轮询,判定这个变量还存不存在,直到自己持有锁
  • 常见的有两种方式

    • redis
    • MySQL
一、MySQL分布式锁
  • MySQL加入数据时,需要满足唯一性约束,如果满足插入成功,不满足插入不成功。基于此,可以尝试将限定访问的方法设置为具有唯一性约束的数据

    • 加锁:插入名称为方法名的记录
    • 解锁:删除名称为方法名的记录
    • 轮询锁: 检查对应字段是否存在
  • 具体实现方法如下

CREATE TABLE 'LOCK_INFO'(
	'ID' INT(11) UNSINGNED NOT NULL AUTO_INCREMENT,
	'METHOD_NAME' VARCHAR(64) NOT NULL ,
	PRIMARY KEY('ID'),
	UNIQUE KEY 'METHOD_NAME'   // 这个最关键,指明访问的互斥资源对应字段是独一无二的
)
	
  • 竞争锁的方式如下
INSERT INTO LOCK_INFO (NAME) VALUES('LOCKMETHODS');
	

缺点

  • 运行缓慢

    • 数据库操作的是磁盘,是通过磁盘IO来实现数据的读写,在高并发的情况下,运行缓慢
  • 容易死锁

    • 并不能像redis一样,有px,可以给每一个锁设置一个过期时间进行兜底。如果持有锁的线程挂掉了,没有删除数据库中的锁记录,就会导致死锁
  • 单点依赖性

    • 数据库是单点,非常依赖数据库的可用性

基本上不用,运行慢而且死锁难以解决,还是会用基于内存存储的组件来实现分布式锁

二、Redis分布式锁
  • 不同于MySQL,redi是基于内存的存储系统,轻便高效,并且redis是使用单线程模型来完成主要工作的。
  • redis的setnx命令
    • ex:可以设置过期时间,以及自身也有过期键删除策略,所以能够有效避免死锁问题
    • nx:nx仅仅是目标不存在时,才会设置对象,所以轻松实现分布式锁

具体实现流程

  • 每一把锁,使用同一数据来标识,key就是锁的名字
  • 加锁:向redis中插入一条key为锁的名字的数据,表示加锁成功
  • 解锁:删除名称为key的记录,表示解锁成功
  • 轮询:在加锁的时候,发现数据已经存在,就轮询等待,直到持有锁的一方释放锁
    • 正常情况下,会间隔一段时间在尝试获取锁

健壮性的实现——锁能够顺利传下去

  • 工作站崩溃,无限期持有锁

    • 使用ex指令,超过了过期时间,会自动释放锁,防止线程因为持有锁而陷入死锁状态
  • 工作没干完就过期了

    • 看门狗机制
      • 单独创建一个线程,定时向redis进行续期操作,防止业务完成之前,锁就过期了
      • 某一个线程长期持有锁,会让其他工作站拿不到锁

对称性的实现——谁加锁谁释放

  • Lua脚本
    • 使用Lua脚本保证,判断锁的归属权 + 删除锁 操作的原子性
      在这里插入图片描述

高可用保障——RedLock

  • redis 本身单点执行的,为了应对单点故障,redis支持主从复制,但是redis的主从复制是异步的,这就会导致锁的独占性问题。

    • 多个对象同时获得一把锁情况
      • 对象A在Master中获得了lock锁,但在之后Master立刻崩溃,但是Slave还没来的及将锁同步过去
      • slave提升为Master,但是其中并没有对象A关于lock锁的获取情况,所以对象B在申请lock,也会成功
      • 使得对象A和对象B同时获得了lock
  • RedLock多个节点的锁

    • 客户端会和多个独立的Redis实例依次请求加锁,只要获得半数一样的锁,就算是加锁成功,这样不用担心崩溃问题了。
    • 只要多数redis节点正常工作,分布式锁就能正常工作,提升分布式锁的可靠性。
  • 锁获取失败

    • 锁获取失败之后,会释放已经获得的部分锁,并等待一段随机时间后,在重试获得锁
监听回调型分布式锁
  • 不用轮询的,相当于给管理员一个通知方式,有锁可以竞争,就直接通知需要竞争锁的对象来竞争锁。
  • 加锁解锁和之前轮询的差不多,唯一的区别就是不用一直轮询,具体流程如下
    • 定义锁:一把锁,用一个数据来标识
    • 加锁:在存储组件里面插入一条数据,这条数据之前不存在,插入成功,加锁成功
    • 解锁:将该条数据从存储组件中删除的行为是解锁操作

最大的区别

  • 加锁失败监听
    • 锁的竞争者回去监听锁的删除事件
    • 当发生锁的删除事件之后,锁的竞争者会继续尝试获取锁。

常见应用

  • Etcd分布式锁
  • ZooKeeper
Etcd分布式锁

Etcd是一种key-value的基于内存的分布式存储仓库,其实分布式锁的方式如下。

健壮性——锁能够顺利流转

  • 租约机制

    • 可以为保存锁的key-value设置租约,即使持有锁的对象出现故障,也能够到期自动释放锁,删除键值对
    • 支持续约,相当于redis中专门实现的一个看门狗续期线程
  • watch机制

    • 支持watch某个固定的key或者watch一个范围的key
    • 一旦某一个key或者范围发生变化,客户端会收到通知

总结

  • Etcd是基于Raft协议实现的高可靠、强一致性的存储组件,正常情况下不会像Redis主从异步复制一样导致出现所数据丢失的情况
  • Etcd是监听回调型分布式锁,基于Watch机制,能够感知锁的释放,再去拿锁,不会像redis一样轮询
Zookeeper分布式锁
  • 用于提供分布式引用程序协调服务的组件
  • Zookeeper是一种树型结构,具有固定的根节点/,只能在根节点下创建子节点,并在子节点下继续创建节点,只能用绝对路径查询Zookeeper节点。
  • 总共有4种类型的节点
    • 持久节点:
      • 一直存在于Zookeeper中的节点,默认的接待你
    • 持久顺序节点:
      • 创建节点时,按照创建节点的顺序对节点进行编号
    • 临时节点(分布式锁实现)
      • 客户端和ZooKeeper连接时临时创建的节点,客户端断开俩节后,进程创建的临时节点就会被删除
      • 依赖定期的心跳检测来实现
    • 临时顺序节点
      • 按时间顺序编号创建的临时节点

在这里插入图片描述

具体实现流程

  • 加锁

    • 创建临时顺序节点,不用担心续期的问题,会有心跳检测,直到客户端完成任务才会断开
    • 当客户机宕机后,临时节点就会随之消亡
  • 解锁

    • 客户机完成任务后,主动断开链接,临时节点会消亡。
  • 监听

    • 监听上一个节点的删除事件

锁的对比

在这里插入图片描述

总结

  • 这里再说分布式锁的选型的时候,就可以大概从性能和可靠性的角度介绍一下,然后在选择redis,因为我的项目确实对于性能的要求更高,对于可靠性的要求并不高,而且占据任务这个唯一需要分布式锁控制访问的接口,访问时间也很快,不会出现执行时间过长,分布式锁过期的情况。
  • 两个角度
    • 业务本身:执行时间很短、对于安全性和可靠性的要求并不高(任务本身是幂等的),对于性能要求的高,
    • 分布式锁的特性:redis是上述四种锁中性能最高的,而且比较熟悉

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

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

相关文章

基于Martin实现MapboxGL自定义底图

概述 本文分享基于Martin实现MapboxGL底图的自定义。 实现后效果 Martin简介 Martin 是一个瓦片服务器,它能够从 PostGIS 数据库、PMTiles(本地或远程)以及 [MBTiles] (https://github.com/mapbox/mbtiles-spec) 文件中快速生成并提供矢量瓦…

七人共享拼团:社交电商的裂变新引擎

在当今电商市场中,七人共享拼团模式以其独特的社交属性和裂变机制,正成为一股不可忽视的力量。这一模式巧妙融合了社交电商的互动性与拼购的实惠性,通过平台利润回馈用户的方式,构建了一个既人性化又高效的奖励体系,旨…

QT 添加程序图标

1. 使用免费网站将其他图片格式转化成ico格式 Ico转换器 : https://cn.free-converter.com/ico-converter 2.qmake项目添加程序图标 在.pro文件内添加语句,如下图 RC_ICONS favicon.ico2.1 程序图标文件添加到项目目录内 2.2 通过windeployqt xxx.exe构建生成的…

动手研发实时口译系统

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

一文通晓 AI 框架

首先深度学习是机器学习研究领域中的一种范式,而深度学习的概念源于对人工神经网络的研究,很多深度学习算法都使用神经网络进行表示,因为神经网络的性能精度和通用效果都非常好,于是业界习惯性地把深度学习算法等同于 AI。 深度学…

GNSS位移监测站:高精度、高稳定性、高安全性

在现代工程与自然灾害监测领域,GNSS位移监测站以其卓越的功能优势,正逐步成为守护安全、预防灾害的重要工具。其采用的直径114mm加强型立杆,不仅坚固耐用,更严格遵循《地质灾害专群结合监测领警技术指南(试行&#xff…

企业建设零信任体系的核心思路

根据安全牛的调查研究发现,零信任安全理念已经较广泛得到国内各类型企业用户的认可,组织对应用零信任进行网络安全建设已经初具信心,零信任理念对网络安全防护工作的价值开始多方面的展现。 企业开展零信任网络建设的需求和驱动因素 本次调…

86.SAP ME工艺路线打开错误

目录 1.SAP ME工艺路线维护界面 2.错误情况 3.解决方法 1.SAP ME工艺路线维护界面 这个功能设计采用jnlp的方式打开,JNLP(Java Network Launching Protocol )是java提供的一种可以通过浏览器直接执行java应用程序的途径,它使你…

图论------如何使用矩阵来存储图的信息(邻接矩阵表示法)。

文章概述: 刚开始图论我们先不急于解决实际的问题,先去搞明白如何存储图的信息。实际上我们早就接触过类似的内容,比如上一篇文章的开灯关灯游戏中,我们使用一维数组来表示一排灯的状态,但是如果要表示更加复杂的内容怎…

【STM32】ADC模拟数字转换(规则组单通道)

本篇博客重点在于标准库函数的理解与使用,搭建一个框架便于快速开发 目录 ADC简介 ADC时钟配置 引脚模拟输入模式 规则组通道选择 ADC初始化 工作模式 数据对齐 触发转换方式 连续与单次转换模式 扫描模式 组内的通道个数 ADC初始化框架 ADC上电 ADC校…

高质量翻译对高质量内容和用户体验的影响

在当今全球化的数字环境中,高质量翻译在塑造高质量内容和用户体验方面的重要性怎么强调都不为过。随着公司和开发人员在不同地区和文化中扩大影响力,有效地翻译成为确保内容与不同受众产生共鸣的关键因素。高质量的翻译不仅保留了原始内容的完整性&#…

【网络层】上

目录 一. 网络层功能概述二. SDN的基本功能2.1 数据平面2.2 控制平面(传统方法/每路由器法)2.3 控制平面(SDN方法) 三. 路由算法与路由协议四. IP数据报4.1 IP数据报格式4.2 IP数据报分片4.3 IP地址 (IPV4)…

2024年华为认证H12-811题库(超级好用的刷题软件)

某个ACL规则如下:则下列哪些IP地址可以被permit规则匹配: rule 5 permit ip source 10.0.2.0 0.0.254.255 A、10.0.4.5 B、10.0.5.6 C、10.0.6.7 D、10.0.2.1 试题答案:A;C;D 试题解析: 10.0.2.000001010.00000000.00000010.0000000…

php 匿名类

https://andi.cn/page/621667.html

TMGM原油返佣是多少

在全球金融市场中,原油交易一直是投资者的重要选择之一。其中,交易平台的选择更是关系到投资者盈利的关键因素。TMGM,作为一家全球领先的在线交易提供商,以其公正、透明的交易环境和优质的服务赢得了广大投资者的信赖。那么&#…

【python小脚本】摄像头rtsp流转hls m3u8 格式web端播放

写在前面 工作需要,简单整理实际上这种方式延迟太高了,后来前端直接接的海康的的插件博文内容为 摄像头 rtsp 实时流转 hls m3u8 的一个 Python 脚本理解不足小伙伴帮忙指正 😃,生活加油 99%的焦虑都来自于虚度时间和没有好好做事&#xff0c…

【TiDB】07-tiup工具安装及使用

目录 1、在线安装 1.2、脚本代码如下 2、离线安装 2.1、下载安装包 2.2、安装脚本 3、卸载 4、常用命令 TiDB 提供了丰富的工具,可以帮助你进行部署运维、数据管理(例如,数据迁移、备份恢复、数据校验)、在 TiKV 上运行 S…

意大利Panel触摸屏维修显示屏EBP419 EMBEDDED

意大利Panel触摸屏维修显示屏维修EBP400系列EMBEDDED PC EBP419 panel维修产品主要包括:操作面板,触摸屏,终端机,触摸面板等。应用于包装、食品饮料、纺织与各种工业自动化领域。 panel触摸屏无论是机械工程、装置或单个应用,HMI几乎都可以简化操作,并且通过HMI,还…

大数据技术——DolphinScheduler的集群部署

目录 第1章 DolphinScheduler简介 1.1 DolphinScheduler概述 1.2 DolphinScheduler核心架构 第2章 DolphinScheduler部署说明 2.1 软硬件环境要求 2.1.1 操作系统版本要求 2.1.2 服务器硬件要求 2.2 部署模式 2.2.1 单机模式 2.2.2 伪集群模式 2.2.3 集群模式 第3章…

语音转文字例会纪要有什么好?一分钟掌握5款语音转文字软件

你是否曾在紧张的会议现场,因笔记跟不上发言者语速而焦虑不已?亦或是在采访结束后,面对一堆录音文件感到头大,不知如何迅速整理成可用的文本? 别急,科技的进步总能给我们惊喜。今天,我要为你带…