一文带你精通分布式锁

一文来了解关于分布式锁的那些事儿 什么是分布式锁 通过互斥性质,来保证线程对分布式系统中共享资源的有序访问 说人话:一把锁,挨个进 分布式锁的特性 互斥(线程独享):即同一时刻只有一个线程能够获取锁 避免死锁:获得锁的线程崩溃后,不会影响后续线程获取锁,操作共享资源 隔离性:A获取的锁,不能让B去解锁(解铃还须系铃人) 原子性:加锁和解锁必须保证为原子操作 文章相关视频 C++后台开发架构师学习视频 Redis实现分布式锁以及数据库锁 必备技能—锁;原子操作 CAS 分布式锁的实现方式 阅读详情

在单机环境下,由于使用环境简单和通信可靠,锁的可见性和原子性很容易可以保证,可以简单和可靠地实现锁功能。到了分布式的环境下,由于公共资源和使用方之间的分离,以及使用方和使用方之间的分离,相互之间的通信由线程间的内存通信变为网络通信。网络通信的时延和不可靠,加上分布式环境中各种故障的常态化发生,导致实现一个可靠的分布式锁服务需要考虑更多更复杂的问题。

锁,核心是协调各个使用方对公共资源使用的一种机制。当存在多个使用方互斥地使用某一个公共资源时,为了避免并行使用导致的修改结果不可控,需要在某个地方记录一个标记,这个标记能够被所有使用方看到,当标记不存在时,可以设置标记并且获得公共资源的使用权,其余使用者发现标记已经存在时,只能等待标记拥有方释放后,再去尝试设置标记。这个标记即可以理解为锁。

在单机多线程的环境下,由于使用环境简单和通信可靠,锁的可见性和原子性很容易可以保证,所以使用系统提供的互斥锁等方案,可以简单和可靠地实现锁功能。到了分布式的环境下,由于公共资源和使用方之间的分离,以及使用方和使用方之间的分离,相互之间的通信由线程间的内存通信变为网络通信。网络通信的时延和不可靠,加上分布式环境中各种故障的常态化发生,导致实现一个可靠的分布式锁服务需要考虑更多更复杂的问题。

目前常见的分布式锁服务,可以分为以下三大类:

  • 基于数据库实现的锁服务:典型代表是 mysql。
  • 基于分布式缓存实现的锁服务及其变种:典型代表是使用 Redis 实现的锁服务和基于 Redis 实现的 RedLock 方案;
  • 基于分布式一致性算法实现的锁服务:典型代表为 Zookeeper、etcd 和 Chubby 等。

本文从上述三大类常见的分布式锁服务实现方案入手,从分布式锁服务的各个核心问题(核心架构、锁数据一致性、锁服务可用性、死锁预防机制、易用性、性能)展开,尝试对比分析各个实现方案的优劣和特点。

基于数据库实现的锁服务

基于数据库的实现方式的核心思想是:在数据库中创建一个表,表中包含方法名等字段,并在方法名字段上创建唯一索引,想要执行某个方法,就使用这个方法名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁。

加解锁流程

(1)创建一个表:

DROP TABLE IF EXISTS `method_lock`;
CREATE TABLE `method_lock` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `method_name` varchar(64) NOT NULL COMMENT '锁定的方法名',
  `desc` varchar(255) NOT NULL COMMENT '备注信息',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uidx_method_name` (`method_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='锁定中的方法';

(2)想要执行某个方法,就使用这个方法名向表中插入数据:

INSERT INTO method_lock (method_name, desc) VALUES ('methodName', '测试的methodName');

因为我们对method_name做了唯一性约束,这里如果有多个请求同时提交到数据库的话,数据库会保证只有一个操作可以成功,那么我们就可以认为操作成功的那个线程获得了该方法的锁,可以执行方法体内容。

(3)成功插入则获取锁,执行完成后删除对应的行数据释放锁:

delete from method_lock where method_name ='methodName';

注意: 这只是使用基于数据库的一种方法,使用数据库实现分布式锁还有很多其他的方法。

锁安全性分析

1、数据库的可用性和性能将直接影响分布式锁的可用性及性能,当数据库发生故障时,锁就会失效,当然也可以通过数据库双机部署、数据同步、主备切换来提高可用性。

2、锁没有失效机制,如果客户端1获取锁后,服务器宕机了,对应的锁没有释放,当服务恢复后一直获取不到锁,可以在表中新增一列,用于记录失效时间,并且需要有定时任务清除这些失效的数据。

总结

1、 锁服务性能
由于锁数据基于数据库,且实现一个安全的锁机制需要应用层编写大量的代码。在并发度不高,且不想引入其他组件的情况下可以使用这种方法。

2、 数据一致性和可用性
如果是单点的数据库,当数据库挂掉之后锁就不可以了。

基于分布式缓存实现的锁服务

基于单 Redis 节点的分布式锁

基于分布式缓存实现的锁服务,思路最为简单和直观。和单机环境的锁一样,我们把锁数据存放在分布式环境中的一个唯一结点,所有需要获取锁的调用方,都去此结点访问,从而实现对调用方的互斥,而存放锁数据的结点,使用各类分布式缓存产品充当。

加解锁流程

加锁操作:

 SET resource_name my_random_value NX PX 30000

  • my_random_value 是由客户端生成的一个随机字符串,它要保证在足够长的一段时间内在所有客户端的所有获取锁的请求中都是唯一的,用于唯一标识锁持有方。
  • NX 表示只有当 resource_name 对应的 key 值不存在的时候才能 SET 成功。这保证了只有第一个请求的客户端才能获得锁,而其它客户端在锁被释放之前都无法获得锁。
  • PX 30000 表示这个锁结点有一个30秒的自动过期时间。(自动过期时间,目的是为了防止持有锁的客户端故障后,锁无法被释放导致死锁而设置,从而要求锁拥有者必须在过期时间之内执行完相关操作并释放锁)。

解锁操作:

if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

释放锁的操作必须使用Lua脚本来实现,释放锁其实包含三步操作:'GET'、判断和'DEL',用Lua脚本来实现能保证这三步的原子性。

锁安全性分析

1、Redis 结点故障后,由于 Redis 的主从复制(replication)是异步的,这可能导致在 failover 过程中没有备份到锁数据,从而破坏锁的安全性。 2、程序执行耗时大于锁过期时间。可以考虑以下情景:

  • 客户端1获取锁成功
  • 客户端1在某个操作上执行了很长时间
  • 过期时间到,锁自动释放
  • 客户端2获取到了对应同一个资源的锁
  • 客户端1从阻塞中恢复过来,认为自己依旧持有锁,继续操作同一个资源,导致互斥性失效

     

这种就需要客户端实现锁续期的机制。在程序执行的过程定时检查锁是否快过期,如果快过期就延长锁的过期时间。

在上例中客户端1如果阻塞了很长时间(例如 Java 执行了长时间的 GC)导致客户端假死无法进行锁续期,还是会破坏锁的安全性。

image.png

总结

1、 锁服务性能
由于锁数据基于 Redis 等分布式缓存保存,基于内存的数据操作特性使得这类锁服务拥有着非常好的性能表现。同时锁服务调用方和锁服务本身只有一次RTT就可以完成交互,使得加锁延迟也很低。所以,高性能、低延迟是基于分布式缓存实现锁服务的一大优势。因此,在对性能要求较高,但是可以容忍极端情况下丢失锁数据安全性的场景下,非常适用。

2、 数据一致性和可用性
锁数据一致性基于上述的分析,基于分布式缓存的锁服务受限于通用分布式缓存的定位,无法完全保证锁数据的安全性,核心的问题为:

  • 锁数据写入的时候,没有保证同时写成功多份:任何事后的同步在机制上都是不够安全的,因此在故障时,锁数据存在丢失的可能。

基于多 Redis 节点的分布式锁

基于分布式缓存实现锁服务,在业界还存在各类变种的方案,其核心是利用不同分布式缓存产品的额外特性,来改善基础方案的各类缺点,各类变种方案能提供的安全性和可用性也不尽相同。此处介绍一种业界最出名,同时也是引起过最大争论的一个锁服务变种方案- RedLock。它基于 N 个完全独立的 Redis 节点(通常情况下 N 可以设置成5)

加解锁流程

运行Redlock算法的客户端依次执行下面各个步骤,来完成获取锁的操作:

  • 获取当前时间(毫秒数)
  • 按顺序依次向 N 个 Redis 节点执行获取锁的操作:这个获取操作跟前面基于单 Redis 节点的获取锁的过程相同,包含随机字符串 my_random_value,也包含过期时间(比如 PX 30000,即锁的有效时间)。为了保证在某个 Redis 节点不可用的时候算法能够继续运行,这个获取锁的操作还有一个超时时间(time out),它要远小于锁的有效时间(几十毫秒量级)。客户端在向某个 Redis 节点获取锁失败以后,应该立即尝试下一个 Redis 节点。这里的失败,应该包含任何类型的失败,比如该 Redis 节点不可用,或者该 Redis 节点上的锁已经被其它客户端持有。
  • 计算整个获取锁的过程总共消耗了多长时间:如果客户端从大多数 Redis 节点(>= N/2+1)成功获取到了锁,并且获取锁总共消耗的时间没有超过锁的有效时间(lock validity time),那么这时客户端才认为最终获取锁成功;否则,认为最终获取锁失败。
  • 如果最终获取锁成功了,那么这个锁的有效时间应该重新计算,它等于最初的锁的有效时间减去第3步计算出来的获取锁消耗的时间。
  • 如果最终获取锁失败了(可能由于获取到锁的 Redis 节点个数少于N/2+1,或者整个获取锁的过程消耗的时间超过了锁的最初有效时间),那么客户端应该立即向所有 Redis 节点发起释放锁的操作。

而释放锁的过程比较简单:客户端向所有 Redis 节点发起释放锁的操作,不管这些节点当时在获取锁的时候成功与否。

锁安全性分析

1、RedLock 的安全性依旧强依赖于系统时间,如果发生时钟跳跃就会出现问题,假设一共有5个 Redis 节点:A, B, C, D, E:

  • 客户端1成功锁住了 A, B, C,获取锁成功(但 D 和 E 没有锁住)。
  • 节点C时间异常,导致C上的锁数据提前到期,而被释放。
  • 客户端2此时尝试获取同一把锁:锁住了 C, D, E,获取锁成功。

2、缺乏锁数据丢失的识别机制和恢复机制,假设一共有5个 Redis 节点:A, B, C, D, E:

  • 客户端1成功锁住了 A, B, C,获取锁成功(但 D 和 E 没有锁住)。
  • 节点 C 崩溃重启了,但客户端1在 C 上加的锁没有持久化下来,丢失了。
  • 节点 C 重启后,客户端2锁住了 C, D, E,获取锁成功。

官方给出的解决方案是延迟重启,一个节点崩溃后,先不立即重启它,而是等待一段时间再重启,这段时间应该大于锁的有效时间。这样的话,这个节点在重启前所参与的锁都会过期,它在重启后就不会对现有的锁造成影响。这个方案,是在缺乏丢失数据识别的能力下,实现的较“悲观”的一个替代方案,首先其方案依旧依赖于时间,其次如何确定最大过期时间,也是一个麻烦的事情,因为最大过期时间很可能也一起丢失了(未持久化),再有延迟重启使得故障结点恢复的时间延长,增加了集群服务可用性的隐患。怎么来看,都不算一个优雅的方案。

3、仍未解决程序执行耗时大于锁过期时间的问题。

总结

1、锁服务性能

由于RedLock锁数据仍然基于Redis保存,所以和基于单点的Redis锁一样,具有高性能和低延迟的特性,不过由于引入多数派的思想,加锁和解锁时的并发写,所以在流量消耗来说,比基于单点的Redis锁消耗要大。从资源角度来说,是用流量换取了比单点Redis稍高的数据一致性和服务可用性。

2、数据一致性和可用性

RedLock的核心价值,在于多数派思想。不过根据上面的分析,它依然不是一个工程上可以完全保证锁数据一致性的锁服务。相比于基于单点Redis的锁服务,RedLock解决了锁数据写入时多份的问题,从而可以克服单点故障下的数据一致性问题,但是还是受限于通用存储的定位,其锁服务整体机制上的不完备,使得无法完全保证锁数据的安全性。在继承自基于单点的Redis锁服务缺陷(解锁不具备原子性;锁服务、调用方、资源方缺乏确认机制)的基础上,其核心的问题为:缺乏锁数据丢失的识别机制。

RedLock中的每台Redis,充当的仍旧只是存储锁数据的功能,每台Redis之间各自独立,单台Redis缺乏全局的信息,自然也不知道自己的锁数据是否是完整的。在单台Redis数据的不完整的前提下,没有识别机制,使得在各种分布式环境的典型场景下(结点故障、网络丢包、网络乱序),没有完整数据但参与决策,从而破坏数据一致性。

关于Redis分布式锁的安全性问题,在分布式系统专家Martin Kleppmann和Redis的作者antirez之间就发生过一场争论,感兴趣的可以看一下这篇文章。

基于分布式一致性算法实现的锁服务

加解锁流程

获取锁

客户端尝试创建一个 znode 节点,比如 /lock 。那么第一个客户端就创建成功了,相当于拿到了锁;而其它的 客户端会创建失败(znode 已存在),获取锁失败。znode 应该被创建成 ephemeral 的。这是znode的一个特性,它保证如果创建 znode 的那个客户端崩溃了,那么相应的 znode 会被自动删除。这保证了锁一定会被释放。这个特性避免了设置锁的过期时间。

释放锁

持有锁的客户端访问共享资源完成后,将 znode 删掉,这样其它客户端接下来就能来获取锁了。如上所述的基于ZooKeeper 的分布式锁的实现,并不是最优的,它会引发 “herd effect”(羊群效应),降低获取锁的性能。可以设置锁节点为顺序临时节点,后面的节点 watch 前面的节点,当前面的节点删除时唤醒后面的节点从而避免羊群效应。

锁安全性分析

看起来这个锁相当完美,没有 Redlock 过期时间的问题,而且能在需要的时候让锁自动释放。但是他还是有阻塞了很长时间导致客户端假死的情况,可以考虑这一种情况:

  • 客户端1创建了 znode 节点 /lock,获得了锁。
  • 客户端1进入了长时间的 GC pause。
  • 客户端1连接到 ZooKeeper 的 Session 过期了。znode 节点/lock被自动删除。
  • 客户端2创建了 znode 节点 /lock,从而获得了锁。
  • 客户端1从 GC pause 中恢复过来,它仍然认为自己持有锁。

看起来,用 ZooKeeper 实现的分布式锁也不一定就是安全的。该有的问题它还是有。但是,ZooKeeper 作为一个专门为分布式应用提供方案的框架,它提供了一些非常好的特性,是 Redis 之类的方案所没有的。像前面提到的 ephemeral 类型的 znode 自动删除的功能就是一个例子。

总结

本文通过分析三类分布式锁服务,基本涵盖了所有分布式锁服务中涉及到的关键技术,以及对应具体的工程实现方案。

基于分布式存储实现的锁服务,由于其内存数据存储的特性,所以具有结构简单,高性能和低延迟的优点。但是受限于通用存储的定位,其在锁数据一致性上缺乏严格保证,同时其在解锁验证、故障切换、死锁处理等方面,存在各种问题。所以其适用于在对性能要求较高,但是可以容忍极端情况下丢失锁数据安全性的场景下。

基于分布式一致性算法实现的锁服务,其使用类 Paxos 协议保证了锁数据的严格一致性,同时又具备高可用性。在要求锁数据严格一致的场景下,此类锁服务几乎是唯一的选择。但是由于其结构和分布式一致性协议的复杂性,其在性能和加锁延迟上,比基于分布式存储实现的锁服务要逊色。

所以实际应用场景下,需要根据具体需求出发,权衡各种考虑因素,选择合适的锁服务实现模型。无论选择哪一种模型,需要我们清楚地知道它在安全性上有哪些不足,以及它会带来什么后果。更特别的,如果是对于锁数据安全性要求十分严格的应用场景,那么需要更加慎之又慎。

基于结构的虚拟筛选模型 gnina 从源码编译 所需要的软件安装包: 安装 CUDA 装的时候看着点,第二个要你装驱动的选择,回答N,不装。 sudo sh cuda_10.0.130_410.48_linux.run sudo vim ~/.bashrc 在 ~/.bashrc 文件最后加上 export PATH=/usr/bin:/usr/local/cuda-10.0/bin${PATH} export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64:${LD_LIBRARY_PATH} source ~ 阅读详情

相关推荐

黑金ZYNQ7010开发板开箱实测:从接线到串口通信的保姆级指南

本文提供黑金ZYNQ7010开发板从开箱到串口通信的完整实操指南。详细介绍了硬件连接、驱动安装、启动模式设置及串口终端配置等关键步骤,并针对常见问题提供排查思路,帮助FPGA开发者快速上手ZYNQ平台,建立稳定的调试通道。

weixin_29266749的博客 466

一文带你实现分布式锁

一文带你实现分布式锁

weixin_45642975的博客 854

RLC电阻电容电感基础知识——电感篇

电感 等效电路 电感线圈由铜导线绕制,等效电路如图所示。 寄生电阻RS,包括了绕线电阻、引脚串联电阻以及磁芯损耗电阻三部分组成,其中绕线电阻与线径、长度、铜线电阻率有关;引脚电阻与引线长短、粗细有关;磁芯损耗电阻与磁芯材料特性有关,显然磁芯损耗电阻还与工作频率有关.寄生电容C主要是绕线圈与圈之间的杂散电容(为PF级),与绕线工艺有关。 等效导纳 显然: (1)当角频率ω(频率f)较小时,呈电感性. (2)当角频率ω等于ω0时,导纳Y虚部为0,呈现电阻性,即发生共振。令导纳Y虚部为0,即可求出共振角频率ω

azj2019的博客 1万+

一文精通ZooKeeper分布式锁,都是干货!

什么是分布式锁 一个很典型的秒杀场景,或者说并发量非常高的场景下,对商品库存的操作,我用一个SpringBoot小项目模拟一下。 用到的知识架构: SpringBoot Redis ZooKeeper 我提前将库存stock放在redis,初始值为288: 127.0.0.1:6379> set stock 288 OK 127.0.0.1:6379> get stock "288" 扣减库存的api: @RequestMapping("/v1/reduce") public String

hundred_li_journey的博客 396

Ubuntu20.04 安装 MATLAB R2023b 常见问题及解决方案

本文提供了Ubuntu20.04系统上安装MATLAB R2023b的完整指南,包括系统要求检查、依赖项安装、详细安装步骤及常见问题解决方案。特别针对GTK模块加载失败、OpenGL图形加速问题和中文显示乱码等常见问题提供了有效解决方法,帮助用户顺利完成安装并优化使用体验。

weixin_42619061的博客 483

Altium Designer差分走线实战:从规则设置到阻抗匹配的完整流程

本文详细讲解了在Altium Designer中进行差分走线的完整实战流程,涵盖从原理图定义差分对、PCB布局管理、关键设计规则设置,到利用阻抗计算工具确定线宽与间距,以及布线技巧与等长处理等核心步骤。文章旨在帮助工程师掌握高速PCB设计中差分信号传输的关键技术,确保信号完整性并实现精确的阻抗匹配。

weixin_29163857的博客 257

一文搞懂分布式锁及其业务场景

为什么用分布式锁? 在讨论这个问题之前,我们先来看一个业务场景: 系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单。 由于系统有一定的并发,所以会预先将商品的库存保存在redis中,用户下单的时...

chunqiu3351的博客 2万+

DeepSeek+Dify实战:零代码构建智能SQL生成器

本文详细介绍了如何利用DeepSeek和Dify零代码构建智能SQL生成器,帮助非技术人员通过自然语言查询数据库。文章涵盖从数据准备、知识库设计到Agent配置的全流程,并提供了优化技巧和实际应用案例,显著提升团队数据查询效率。

weixin_29311017的博客 419

一文带你搞懂分布式锁!

为了保证一个方法在高并发情况下的同一时间只能被同一个线程执行,在传统单体应用单机部署的情况下,可以使用Java并发处理相关的API(如ReentrantLcok或synchronized)进行互斥控制。但是,随着业务发展的需要,原单体单机部署的系统被演化成分布式系统后,由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题。补充:具备非阻塞锁特性,即没有获取到锁将直接返回获取锁

chenxuyuana的博客 427

高渗透率光伏接入配电网的电压越限与谐波治理:基于VSG构网型控制与SVG+APF联合补偿的Simulink仿真研究

本文针对高渗透率光伏接入配电网引发的电压越限和谐波畸变问题,提出了一种分层递进的综合治理方案。通过建立IEEE 33节点配电网的Simulink仿真模型,首先验证了传统跟网型控制下光伏渗透率提高导致的电压越上限(最高达1.08 p.u.)和系统谐波畸变严重(THD达8.72%)问题。进而提出:1)将部分光伏逆变器改造为构网型VSG控制,利用其无功调压能力与虚拟阻抗技术实现本地治理;2)在关键节点加装SVG+APF联合补偿装置进行全局动态无功补偿与谐波滤除。仿真结果表明,该方案能将节点电压控制在0.94-1.

huanghm88的专栏 579

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

一文了解分布式锁

一文了解分布式锁 大多数互联网系统都是分布式部署的,分布式部署确实能带来性能和效率上的提升,但为此,我们就需要多解决一个分布式环境下,数据一致性的问题。 当某个资源在多系统之间,具有共享性的时候,为了保证大家访问这个资源数据是一致的,那么就必须要求在同一时刻只能被一个客户端处理,不能并发的执行,否者就会出现同一时刻有人写有人读,大家访问到的数据就不一致了。 一、我们为什么需要分布式锁? 在单机时代...

thatkrisyang 394

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

一文彻底弄清楚分布式锁

关于实现强一致性的手段,可以使用多种方式来进行实现,有**分布式事务**,有**一致性算法**,还有**分布式锁**等等,那么这篇文章我们就围绕分布式锁这个话题来进行展开,首先,我们会先探究它的原理,然后结合实际应用,对目前较为常见的分布式锁实现方式及注意事项进行详细的分析。

weixin_43798841的博客 784

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

一文读懂分布式锁

​ 在单机系统中,当多线程访问数据时,为了保证数据的正确性,我们一般都会采用加锁的方式,比较常见的synchronized或者ReentrantLock。他们都是由Java为我们提供的锁实现,能够让多个线程之间只能串行化执行,从而保证数据的正确性。​ 但是一旦将服务器从单机部署升级为多机部署后,则会发现Java提供的原生锁机制在多机部署下失效了。这是因为Java本身提供的锁,他们只对属于自己JVM里面的线程有效,对于其他JVM的线程是无效的。

CODEING一场空的博客 555

一文读懂Redis分布式锁

分布式锁是一种跨多个分布式系统节点的锁机制,允许多个进程或线程对共享资源进行锁定和解锁。它的主要目标是在各个服务或进程之间协调对共享资源的访问,以确保在同一时刻只有一个实例能够对该资源进行操作。分布式锁通常依赖于第三方系统(如Redis、ZooKeeper等)来管理锁的状态和获取。在使用Redis实现分布式锁时,注意上述事项能够有效提升系统的稳定性和性能,确保资源的安全管理。合理的锁策略和实现将有助于有效解决并发问题,保障数据一致性。随着分布式系统的广泛应用,资源共享和并发控制成为了重要的技术挑战。

qq_32799165的博客 1166

一文搞定分布式锁

1.背景 对于锁大家肯定不会陌生,在Java中synchronized关键字和ReentrantLock可重入锁在我们的代码中是经常见的,一般我们用其在多线程环境中控制对资源的并发访问,但是随着分布式的快速发展,本地的加锁往往不能满足我们的需要,在我们的分布式环境中上面加锁的方法就会失去作用。于是人们为了在分布式环境中也能实现本地锁的效果,也是纷纷各出其招,今天让我们来聊一聊一般分布式锁实现的套...

南哥的博客 436

一文了解Zookeeper如何实现分布式锁

在Java中使用多线程编程,需要考虑多线程环境下程序执行结果的正确性,是否达到预期效果,因此需要在操作共享资源时引入锁,共享资源同一时刻只能由一个线程进行操作。 Java提供了多种本地线程锁。例如synchronized锁,JUC包下提供的可重入锁ReentrantLock、读写锁ReentrantReadWriteLock等; Java本地锁适用于单机环境。在分布式环境下,存在多台服务器同时操作同一共享资源的场景时,服务器之间无法感知到Java本地锁的加锁状态,因此需要通过分布式锁来保证集群环境下执行任.

GTH07399的博客 5359

【redis缓存】分布式锁的8大坑,一文带你了解其中解决方法

在分布式系统中,由于redis分布式锁相对于更简单和高效,成为了分布式锁的首先,被用到了很多业务场景当中。apollo、nocos等的出现,让zookeeper的地位越来越低了。zookeeper分布式锁复杂度更高,想把它使用好并不容易。所以我们还是好好使用redis分布式锁吧。不是说用了redis分布式锁,就可以高枕无忧了,如果没有用好,也会引来一些意想不到的麻烦。今天我们重点聊聊redis分布式锁的一些坑,给有需要的朋友一个参考。

程序源日志的博客 985

从认知到实现,一文读懂实现分布式锁的五种方案。

分布式锁是指在分布式系统中,多个进程或线程之间为了避免冲突而对某个共享资源加锁的机制。分布式锁通常用于保证在分布式系统中,只有一个进程或线程能访问某个共享资源。分布式锁可以分为两种:悲观锁和乐观锁。悲观锁是指在访问共享资源之前,先对共享资源加锁,然后再进行访问。如果其他进程或线程也尝试访问共享资源,那么它们将被阻塞,直到当前进程或线程释放锁。悲观锁保证了共享资源的互斥访问,但可能会导致其他进程或线程长时间等待。乐观锁是指在访问共享资源之前,先对共享资源进行版本控制,然后再进行访问。

m0_50308467的博客 5047

一文带你了解如何使用 Redis 实现分布式锁

锁是我们在设计和实现大多数系统时绕不过的话题。一旦有竞争条件出现,在没有保护的操作的前提下,可能会出现不可预知的问题。 而现代系统大多为分布式系统,这就引入了分布式锁,要求具有在分布各处的服务上保护资源的能力。 而实现分布式锁,目前大多有以下三种方式: 使用数据库实现。 使用 Redis 等缓存系统实现。 使用 Zookeeper 等分布式协调系统实现。 其中 Redis 简便灵活,高可用分布...

TIANTIAN_ZZ的博客 448

一文掌握Redisson分布式锁

Redisson 说白了就是redis的儿子,本质上还是对redis进行加锁,不过是对redis进行了很多封装,他不仅仅提供了一系列的分布式的Java常用对象,还提供了许多的分布式服务。

程序员伊成 2168

一文带你理解Zookeeper实现分布式锁的机制

提到锁,想必大家可能最先想到的是JavaJUC中的关键字或者可重入锁。它能够保证我们的代码在同一个时刻只有一个线程执行,保证数据的一致性和完整性。但是它仅限于单体项目,也就是说它们只能保证单个JVM应用内线程的顺序执行。如果你部署了多个节点,也就是分布式场景下如何保证不同节点在同一时刻只有一个线程执行呢?场景的业务场景比如秒杀、抢优惠券等,这就引入了我们的分布式锁,本文我们主要讲解利用Zookeeper的特性如何来实现我们的分布式锁。httpshttps。...

m0_71777195的博客 504

一文带你认识zookeeper并探究分布式锁实现原理

你了解zookeeper吗? 你真的了解zookeeper吗? 如果你非常理解,那么请划走,我怕你嘲笑我~ 如果你也一知半解,那就往下进行了。 先来看下概念 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。 ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提

mlh955的博客 2万+

一文道明Redis分布式锁的实现及原理

文章目录前言一、什么是分布式锁?二、Redis锁的实现三、Redisson的实战四、测试是否实现了分布式锁五、总结 前言 本文分享的是基于Redisson分布式锁的实战以及我们自己如何大致利用Redis实现分布式锁。 一、什么是分布式锁? 首先我们要搞清楚的就是什么是分布式锁,大家广而为知的可能是锁。像什么lock锁,synchronized锁等。那这些锁我们通常都称为JVM内部锁或者进程锁。我们知道java程序开发完成以后都是以jar或war包的形式运行,那可以这样理解,在服务器上运行一次jar或wa

qq_32403043的博客 1395
上一篇: 你敢信?终于有人能把数据结构与算法带源码、笔记给讲的明明白白
下一篇: 大批量分析下日志处理检索功能
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值