分布式锁的几种实现原理

分布式锁主流有三种模式:

实现方式 功能要求 实现难度 学习成本 运维成本
MySQL 的方案借助表锁/行锁实现 满足基本要求 不难 熟悉 小量OK、大量影响现有业务、1主多从架构,不方便扩容
通过 ZK 创建数据节点的方式实现 满足要求 熟悉 ZK API 即可 需要学习 重,需要堆机器,有跨机房请求
Redis 使用 setnxex 基本要求 不难 熟悉 扩容方便、现有服务

MySQL 单主架构,写都会到 master,有瓶颈。ZK 的方式需要自己搭建、运维,而且需要堆机器,利用率不高。最终采用了 Redis 来实现,流量/存储都可以扩容,运维也不需要自己。

一、基于Mysql实现分布式锁 (乐观锁)

Mysql实现分布式锁 主要是基于数据库的排他锁(也叫行级排他锁), 采用乐观锁的方式去做。
我们可以通过一个update语句是否成功来判断线程抢占锁是否成功,比如如下sql语句:

CREATE TABLE `t_schedule_cluster` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '@cname:主键',`execute` int(1) NOT NULL COMMENT '@cname:执行状态',`version` int(11) NOT NULL COMMENT '@cname:版本号 ',`task_name` varchar(128) NOT NULL COMMENT '@cname:任务名称',`execute_ip` varchar(32) DEFAULT NULL COMMENT '@cname:执行ip ',`update_time` datetime DEFAULT NULL COMMENT '@cname:修改时间',PRIMARY KEY (`id`),KEY `Index_series_id` (`execute`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COMMENT='@cname:多机定时任务调度';

争抢锁的sql语句:
update t_schedule_cluster set execute = 1 version = ?, execute_ip = ?, update_time = ? where task_name = ? and version = ?

实现原理入下图:
2f738bd4b31c8701f38133612a7f9e2f0708ff06.jpg

但是数据库的性能有限,如果在高并发的情况下会频发的访问数据库,对数据库会造成较大的压力。

二,基于redis的分布式锁实现

基于Redis实现的分布式锁其实很简单,底层就是使用redis的setnx指令来实现的加锁,我们来看看官方对setnx的定义:
SETNX key value
将 key 的值设为 value ,当且仅当 key 不存在。
若给定的 key 已经存在,则 SETNX 不做任何动作。
SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。
返回值:
设置成功,返回 1 。
设置失败,返回 0 。

redis> EXISTS job # job 不存在
(integer) 0
redis> SETNX job "programmer" # job 设置成功
(integer) 1
redis> SETNX job "code-farmer" # 尝试覆盖 job ,失败
(integer) 0
redis> GET job # 没有被覆盖
"programmer"

以上内容来自于:http://redisdoc.com/string/setnx.html

既然setnx这么强大,那么我们是不是可以高枕无忧直接使用了? 当然了,我们还要考虑一些极端场景。

2.1 死锁问题

既然设置了value值,那么我们肯定会想到过期时间,那么就需要再使用setnx指令后继续使用expire指令。但是这两部操作必定不是原子性的,如果执行expire失败怎么办?
其实Redis官方也考虑到了这个问题,在Redis2.8 之后,官方执行setnx 和 expire命令一起使用了。如下:
SET lock_key lock_value NX PX 30000
其中:
1.lock_key:即锁名称,这个名称应是公开的,在分布式环境中,对于某一确定的公共资源,所有争用方(客户端)都应该知道对应锁的名字。对于 Redis 而言,lock_name 就是 key-value 中的 key,具有唯一性。

  1. lock_value:是由客户端生成的一个随机字符串,它要保证在足够长的一段时间内在所有客户端的所有获取锁的请求中都是唯一的,用于唯一标识锁的持有者。
  2. NX 表示只有当 lock_key(key) 不存在的时候才能 SET 成功,从而保证只有一个客户端能获得锁,而其它客户端在锁被释放之前都无法获得锁。
  3. PX 30000 表示这个锁节点有一个 30 秒的自动过期时间(目的是为了防止持有锁的客户端故障后,无法主动释放锁而导致死锁,因此要求锁的持有者必须在过期时间之内执行完相关操作并释放锁)。
    具体操作如下图:
    80cb39dbb6fd5266d905cf93a618972bd407360e.jpg

2.2 锁自动过期存在的隐患

例如我们有两个线程A、B,此时线程A抢到了锁,且设置自动过期时间为10s钟,因为系统其他原因导致系统A发生阻塞。而此刻10s钟后锁自动过期,线程C获取到了同一个资源的锁,线程A从阻塞中恢复,认为自己仍然持有锁,继续操作同一资源。这样就使得加锁的互斥性失效了。

解决方案:
我们在上面set lock_key lock_value 时讲过,lock_value是一个随机生成的字符串,在每次获取锁的时候都会重新生成。那么我们在执行真正的业务逻辑(类似于和db进行交互的操作,同一时刻只能一个线程操作的情况)时,判断当前生成的随机字符串和lock_value是否一致,如果不一致则说明redis中的lock_value被修改过,也就说明此刻锁已经被其他线程所占有。

具体操作流程如下图:
08f790529822720e6ce3057d76cb0a46f21fab0c.jpg

主要使用的就是这两种方案,在这里只是做个简单总结,其实还有其他一些可以实现分布式锁,根据自己项目本身情况选择最合适的。
另外 已经Redis也有开源的框架可以很好地支持基于Redis的分布式锁,这里推荐一个:Redission https://github.com/redisson/redisson

PS:2019 继续努力加油学习更多知识,让自己在技术这条道路上越走越远!

转载于:https://www.cnblogs.com/wang-meng/p/10226618.html

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

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

相关文章

如何破解您忘记的Windows密码

Here at How-To Geek, we’ve covered many different ways to reset your password for Windows—but what if you can’t reset your password? Or what if you’re using drive encryption that would wipe out your files if you changed the password? It’s time to cr…

sql语句练习50题(Mysql版)

表名和字段–1.学生表Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别–2.课程表Course(c_id,c_name,t_id) – –课程编号, 课程名称, 教师编号–3.教师表Teacher(t_id,t_name) –教师编号,教师姓名–4.成绩表Score(s_id,c_id,s_score) –学生编号…

OpenCV3 识别图中表格-JAVA 实现

2019独角兽企业重金招聘Python工程师标准>>> 关于 JAVA 学习 OpenCV 的内容,函数讲解。内容我均整理在 GitHubd的OpenCV3-Study-JAVA OpenCV 3 识别图中表格-Java 实现 1. 说明 网上大部分资料,都是针对 C的,python、java 的例子太…

内存泄露 体现在哪个数字上_Microsoft刚刚泄漏了一个新的开始菜单。 你喜欢哪个?...

内存泄露 体现在哪个数字上NTAuthority on TwitterTwitter上的NTAuthorityMicrosoft messed up today, releasing an internal build of Windows 10 to Windows Insiders. This build was never meant to see the light of day, but it features a new Start menu design—with…

简述 Spring Cloud 是什么

很多同学都了解了Spring ,了解了 Spring Boot, 但对于 Spring Cloud 是什么还是比较懵逼的。 本文带你简单的了解下,什么是Spring Cloud。 Spring Cloud 是什么 从字面理解,Spring Cloud 就是致力于分布式系统、云服务的框架。 Spring Cloud …

python web scraping

2019独角兽企业重金招聘Python工程师标准>>> 最近在看《Web Scraping with Python》,借此来熟悉Python2.7如何开始编程。 发现书上主要使用的 http://example.webscraping.com/ 网站有部分变化,书中的代码有点无法对照使用,因此稍…

傅里叶变换的物理意义

用三角函数表示周期函数 傅里叶的相关理论始于下面假设:对于周期为1的信号$f(t)$,可以由不同频率的三角函数组成, $f(t) \frac{a_0}{2}\displaystyle{\sum^{\infty}_{k1}}(a_kcos(2\pi kt)b_ksin(2\pi kt))$ 组成的基础波形为一个信号对&…

天猫年度总结

2019独角兽企业重金招聘Python工程师标准>>> 鲁大师天猫工作总结 时间:2017年10月22日-1月30日 1、对代理商进行6大区域的划分管理,有专门的客服指导。 2、加班费申请和车费报销制度。 3、简化了特权订金2阶段改成1阶段,极大的方便…

因特网使用期限_Internet死亡时使用PC的其他方式

因特网使用期限Nothing is more annoying than getting your Internet connection shut down, due to weather, or perhaps forgetting to pay your bill. Let’s take a look at some ways you can be productive and entertained without the Internet. 没有什么比由于天气原…

节省大量教科书的三种潜在风险方法

Photo by Sultry 摄影: Sultry You can always save money on textbooks by buying online, going ebook, or renting what you need. But there are riskier ways to save a buck that just may yield even greater payoff, such as getting the international or …

解决内网搭建本地yum仓库。

2019独角兽企业重金招聘Python工程师标准>>> 一、使用iso镜像搭建本地yum仓库; 1、挂载镜像到/mnt目录下: [rootDasoncheng ~]# mount /dev/cdrom /mnt mount: /dev/sr0 is write-protected, mounting read-only2、备份配置文件,并…

通过用 .NET 生成自定义窗体设计器来定制应用程序

本文讨论: ? 设计时环境基本原理 ? 窗体设计器体系结构 ? Visual Studio .NET 中窗体设计器的实现 ? 为自己的应用程序编写窗体设计器而需要实现的服务 在很多年中,MFC 一直是生成基于 Windows? 的应用程序的流行框架。MFC 包含一个可以使窗体生成、…

airdrop 是 蓝牙吗_您可以在Windows PC或Android手机上使用AirDrop吗?

airdrop 是 蓝牙吗Aleksey Khilko/Shutterstock.comAleksey Khilko / Shutterstock.comApple’s AirDrop is a convenient way to send photos, files, links, and other data between devices. AirDrop only works on Macs, iPhones, and iPads, but similar solutions are av…

如何将Rant变成生产力电动工具

Ranting doesn’t have to be a waste of breathe and time. You can turn a rant into a powerful tool for productivity. Learn how to transform your sense of victim hood and irritability to self-empowerment and mental clarity. 狂欢不必浪费呼吸和时间。 您可以将r…

2019-1-92.4G射频芯片培训资料

2019-1-92.4G射频芯片培训资料 培训 RF 小书匠 欢迎走进zozo的学习之旅。 2.4G芯片选型2.4G芯片开发Q&A2.4G芯片选型 芯片类型 soc防盗标签2.4G无线芯片选型发射器收发器LSD2RF-1600-V1.1 调制方式射频基础 2.4G芯片开发 原理图 发射优先收发均衡PCB topbottomlayout规…

在Outlook 2010中使用对话视图

One of the new features in Outlook 2010 is the ability to use Conversation View for easier management of your email conversations. Here we will take a quick look at how to use the new feature. Outlook 2010中的新功能之一是可以使用“对话视图”来更轻松地管理电…

Day10:html和css

Day10:html和css <html> <body> <h1>标题</h1> <p>段落</p> </body> </html>HTML 是用来描述网页的一种语言&#xff0c;超文本标记语言&#xff0c;不是一种编程语言&#xff0c;而是一种标记语言&#xff0c;是一套标记标签…

如何在PowerPoint演示文稿中使用iTunes音乐

One of PowerPoint’s charms is its ability to play music during the presentation. Adding music to your presentation is simple, but using a song from your iTunes library requires a few extra steps. Here’s how to use iTunes music in PowerPoint. PowerPoint的…

hotmail_在新的Hotmail Wave 4中禁用Messenger

hotmailAre you annoyed by having Messenger automatically sign in when you’re reading your emails in the new Hotmail? Here’s how you can disable the Web Messenger in Hotmail and other Windows Live online apps. 当您在新的Hotmail中阅读电子邮件时&#xff0…

mac无法关机_Mac无法关机时该怎么办

mac无法关机Razvan Franco Nitoi/Shutterstock.com拉兹万佛朗哥尼托伊/Shutterstock.comMacs are like any other computer. Sometimes they won’t start up, and sometimes they won’t shut down. If your Mac is refusing to shut off, here’s how to shut it down anyway…