百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

[分布式管理] 分布式锁 分布式锁是用来干嘛的

yuyutoo 2024-10-16 15:46 9 浏览 0 评论

我们知道,在多线程情况下访问一些共享资源需要加锁,不然就会出现数据被写乱的问题。在分布式系统下,这样的问题也是一样的。只不过,我们需要一个分布式的锁服务。对于分布式的锁服务,一般可以用数据库 DB、Redis 和 ZooKeeper 等实现。不管怎么样,分布式的锁服务需要有以下几个特点

安全性(Safety):在任意时刻,只有一个客户端可以获得锁(排他性)。

避免死锁:客户端最终一定可以获得锁,即使锁住某个资源的客户端在释放锁之前崩溃或者网络不可达。

容错性:只要锁服务集群中的大部分节点存活,Client 就可以进行加锁解锁操作。

Redis 的分布式锁服务

我们通过以下命令对资源加锁。

SET resource_name my_random_value NX PX 30000

解释一下:SET NX 命令只会在 key 不存在的时候给 key 赋值,PX 命令通知 Redis 保存这个 key 30000ms。my_random_value 必须是全局唯一的值。这个随机数在释放锁时保证释放锁操作的安全性。PX 操作后面的参数代表的是这个 key 的存活时间,称作锁过期时间。当资源被锁定超过这个时间时,锁将自动释放。获得锁的客户端如果没有在这个时间窗口内完成操作,就可能会有其他客户端获得锁,引起争用问题。

这里的原理是,只有在某个 key 不存在的情况下才能设置(set)成功该 key。于是,这就可以让多个进程并发去设置同一个 key,只有一个进程能设置成功。而其它的进程因为之前有人把 key 设置成功了,而导致失败(也就是获得锁失败)。

我们通过下面的脚本为申请成功的锁解锁:

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

如果 key 对应的 value 一致,则删除这个 key。通过这个方式释放锁是为了避免 Client 释放了其他 Client 申请的锁。例如,下面的例子演示了不区分 Client 会出现的一种问题。

注意,虽然 Redis 文档里说他们的分布式锁是没有问题的,但其实还是很有问题的。尤其是上面那个为了避免 Client 端把锁占住不释放,然后,Redis 在超时后把其释放掉。不知道你怎么想,但我觉得这事儿听起来就有点不靠谱。

一般情况下,我们可以使用数据库、Redis 或 ZooKeeper 来做分布式锁服务,这几种方式都可以用于实现分布式锁。

分布式锁的特点是,保证在一个集群中,同一个方法在同一时间只能被一台机器上的一个线程执行。这就是所谓的分布式互斥。所以,大家在做某个事的时候,要去一个服务上请求一个标识。如果请求到了,我们就可以操作,操作完后,把这个标识还回去,这样别的进程就可以请求到了。

所以,需要分清楚:我是用来修改某个共享源的,还是用来不同进程间的同步或是互斥的。如果使用 CAS 这样的方式(无锁方式)来更新数据,那么我们是不需要使用分布式锁服务的,而后者可能是需要的。所以,这是我们在决定使用分布式锁服务前需要考虑的第一个问题——我们是否需要?

如果确定要分布式锁服务,你需要考虑下面几个设计。

需要给一个锁被释放的方式,以避免请求者不把锁还回来,导致死锁的问题。

Redis 使用超时时间,ZooKeeper 可以依靠自身的 sessionTimeout 来删除节点。

分布式锁服务应该是高可用的,而且是需要持久化的。对此,你可以看一下 Redis 的文档 RedLock 看看它是怎么做到高可用的。

要提供非阻塞方式的锁服务。还要考虑锁的可重入性。

我认为,Redis 也是不错的,ZooKeeper 在使用起来需要有一些变通的方式,好在 Apache 有 Curator 帮我们封装了各种分布式锁的玩法。

相关推荐

MyBatis的SQL执行流程不清楚?看完这一篇就够了

推荐学习真香警告!Alibaba珍藏版mybatis手写文档,刷起来...

SpringBoot开发必备!49个内置工具类,让你的代码效率翻倍!

作为一名Java开发者,你是否经常为字符串处理、文件操作、数据验证等重复性代码头疼?SpringBoot的武器库里藏着...

C# 基于命名管道(Named Pipes) 的进程间通信(IPC)

基于命名管道(NamedPipes)的进程间通信(IPC),用于在同一台机器不同进程之间进行高效、可靠的数据传输,是一种基于消息或流的通信机制。管道有一个唯一的名称,客户端和服务器端通过名称连接到...

十年之重修MyBatis原理(mybatis方法重载)

弱小和无知并不是生存的障碍,傲慢才是。--------面试者...

C#串口通信(c#串口通信界面)

串口通信(SerialCommunications)是指外设和计算机间通过数据信号线、地线等按位(bit)进行传输数据的一种通信方式,属于串行通信方式,能够实现远距离通信,长度可达1200米。尽管比...

C#中使用命名管道进行进程通信的实例

1新建解决方案NamedPipeExample...

继GitHub之后 OpenAI为ChatGPT推出OneDrive和SharePoint连接器

上周,OpenAI宣布推出ChatGPT的GitHub连接器,允许用户对其源代码库进行深入研究。将GitHub与ChatGPT连接后,用户可以提出问题,深度研究代理将读取和搜索存储库的...

Power BI:如何在SharePoint中嵌入Power BI报告?

问题描述:今天业务同事来询问如何才能将自己开发的PowerBI报告嵌入团队使用的SharePoint页面中,以更直观地和团队成员分享可视化报告。(SharePoint是微软推出的可以用来存储、整理、...

O365(世纪互联)SharePoint 之调查列表简单介绍

前言SharePoint中为了提供了很多开箱即用的应用程序,比如调查列表就是其中之一,同样,在O365版本里(国际版和世纪互联版本均可),也有这样的调查列表可以供我们使用,而使用起来非常方便和快速,就...

制作Excel电子表格必备的:Excel 2021 mac中文版

MicrosoftExcel2021forMac是一款运行在Mac平台上的办公软件,OfficeExcel2021forMac中文版是办公必不可少的软件,主要用于制作电子表格等,这里带...

微软SharePoint新特性:能以邮件方式向目标发送新闻内容

IT之家8月30日消息,微软今天发布新闻稿,宣布为SharePoint服务引入新特性,允许企业将新闻动态转换为电子邮件,并以时事通讯、安全公告、警告等主题发送给感兴趣的用户。微软在新闻稿中...

在Access中创建Sharepoint列表的链接表

在Access中提供了一个DoCmd.TransferSharePointList方法,一行代码就可以搞定。使用TransferSharePointList方法从SharePointFoun...

BBC推荐:12月最值得一看的5部电影 Five films to watch in December

年终岁末,还有哪些精彩电影在等着我们呢?迪士尼的《欢乐满人间2》绝对是合家欢电影的首选,超级英雄迷们将能看到索尼动画《蜘蛛侠:平行宇宙》,福尔摩斯的粉丝们千万别错过《福尔摩斯与华生》。还有朱莉亚·罗伯...

基于锂离子电池的电池荷电状态 (SOC) 和运行健康状态 (SOH) 估计技术

简介基于锂离子(Li-ion)电池单元的电池组广泛用于各种应用,例如:混合动力汽车(HEV)、电动汽车(EV)、可供日后使用的再生能源储存以及用于各种目的(电网稳定性、调峰和再生能源时移等)的...

深入解析电池充电状态 (SOC) 和运行状态 (SOH) 估计技术

基于锂离子(Li-ion)电池单元的电池组广泛用于各种应用,例如:混合动力汽车(HEV)、电动汽车(EV)、可供日后使用的再生能源储存以及用于各种目的(电网稳定性、调峰和再生能源时移等)的电网...

取消回复欢迎 发表评论: