Apache Curator之分布式锁原理(二)

本文主要讲解如下内容:

  • 为什么要使用分布式锁?
  • 分布式锁特性!
  • 分布式锁的实现方式有哪些?
  • Curator分布式锁原理
  • Curator分布式锁实现类UML及相关类的介绍
  • 基于Redis,数据库实现分布式锁

为什么要使用分布式锁?

在传统的单机应用中,我们使用JAVA提供的synchronized、ReentrantLock、Semaphore、AtomicInteger等解决多线程并发问题,达到同步目的。单机应用所有的请求都会分配到当前服务器的JVM内部,线程间是可以共享某一个变量的。当随着业务的发展,单机演变成集群,一个JVM扩展到多个甚至数十个JVM的时候,就不能共享同一变量了。如下图所示:

上图中同样的业务部署在多台服务器上,但是又要操作同一个数据的时候,JAVA的synchronized等关键字也就无力回天了,这是分布式锁正式登场。

 

分布式锁特性!

1、在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行; 
2、高可用的获取锁与释放锁; 
3、高性能的获取锁与释放锁; 
4、具备可重入特性; 
5、具备锁失效机制,防止死锁; 
6、具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败。

 

分布式锁的实现方式有哪些?

目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。”所以,很多系统在设计之初就要对这三者做出取舍。在互联网领域的绝大多数的场景中,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证“最终一致性”,只要这个最终时间是在用户可以接受的范围内即可。

在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等。有的时候,我们需要保证一个方法在同一时间内只能被同一个线程执行。

基于数据库实现分布式锁; 
基于缓存(Redis等)实现分布式锁; 
基于Zookeeper实现分布式锁;

这三种方案之间没有最好只有更适合,具体要看业务场景

Curator分布式锁原理

注意:判断自己是否是locks目录下序号最小的节点,只会和比自己序号小的那个相邻节点进行比较,这样大大提高了效率。比如N节点只会和N-1几点比较,不会和N+1,N-2节点比较。

另外zookeeper有效解决了下面的问题(重点重点重点):

锁释放:

使用Zookeeper可以有效的解决锁无法释放的问题,因为在创建锁的时候,客户端会在ZK中创建一个临时节点,一旦客户端获取到锁之后突然挂掉(Session连接断开),那么这个临时节点就会自动删除掉。其他客户端就可以再次获得锁。

阻塞锁

使用Zookeeper可以实现阻塞的锁,客户端可以通过在ZK中创建顺序节点,并且在节点上绑定监听器,一旦节点有变化,Zookeeper会通知客户端,客户端可以检查自己创建的节点是不是当前所有节点中序号最小的,如果是,那么自己就获取到锁,便可以执行业务逻辑了。

可重入锁

使用Zookeeper也可以有效的解决不可重入的问题,客户端在创建节点的时候,把当前客户端的主机信息和线程信息直接写入到节点中,下次想要获取锁的时候和当前最小的节点中的数据比对一下就可以了。如果和自己的信息一样,那么自己直接获取到锁,如果不一样就再创建一个临时的顺序节点,参与排队。

单点问题

使用Zookeeper可以有效的解决单点问题,ZK是集群部署的,只要集群中有半数以上的机器存活,就可以对外提供服务。

 

Curator分布式锁实现类UML及相关类的介绍

接口InterProcessLock作为神一般的存在,其它类均实现了这个接口。

看一下这个接口定义

接口中定义了四个方法:

public void acquire();//获取锁
public boolean acquire(long time, TimeUnit unit);//获取锁,可以指定阻塞时间
public void release();//释放锁
boolean isAcquiredInThisProcess();//判断当前是否持有锁,实际使用中,如果持有锁,可以进行锁的释放。

实现类:

InterProcessMultiLock 将多个锁作为单个实体管理的容器
InterProcessMutex 分布式可重入排它锁
InterProcessReadWriteLock 分布式读写锁
InterProcessSemaphoreMutex 分布式排它锁
InterProcessSemaphoreV2 信号量
 

基于Redis,数据库实现分布式锁

基于redis和数据库实现的分布式锁大家可以参考以下文章:

分布式锁的实现

分布式锁的几种实现方式

转载于:https://www.cnblogs.com/shileibrave/p/9850637.html

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

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

相关文章

阿里云服务器发送邮件失败?连接超时?25端口被封?

大家好,我是烤鸭: 之前用阿里云服务器的时候发送126企业邮箱,用的smtp方式,但是一直超时。百思不得其解。因为在本地环境是可以的。 原来是阿里云服务器限制了25端口。问了126邮箱那边的技术客服,只支持25端口。 问了…

[css] 举例说明css有哪些简写的属性和属性值?

[css] 举例说明css有哪些简写的属性和属性值? border: solid 1px red;border-style: solid; border-width: 1px; border-color: red;animation: fadeIn .5s forward ease-in .2s infinite;animation-name: fadeIn; animation-duration: 0.5s; animation-fill-mode:…

JS重写Alert方法

var _alert window.alert; window.alert function(){ console.log(arguments); _alert(arguments); }

Pat乙级1011题:A+B和C

题目:给定区间[-2的31次方, 2的31次方]内的3个整数A、B和C,请判断AB是否大于C。我写的代码: del abc(self,a,b,c,i):if ab>c: print("Case #X: true"%i)else:print("Case #X: false"%i)return 0if __name__"__ma…

springboot版的微信公众号,订阅号

大家好,我是烤鸭: 这是一篇微信公众号入门的文章,如果是个人的话,只能申请未认证的订阅号。如果是公司的话,想申请啥都是可以的。 这篇文章说的就是个人订阅号。 环境: centos 7.3 springboot 1.5 需要&#xff…

[css] 请说说颜色中#F00的每一位分别表示什么?为什么会有三位和六位的表示呢?

[css] 请说说颜色中#F00的每一位分别表示什么?为什么会有三位和六位的表示呢? 颜色可以使用红-绿-蓝(red-green-blue (RGB))模式的两种方式被定义:十六进制符号 #RRGGBB 和 #RGB "#" 后跟6位十六进制字符&a…

[css] 请使用css写一个多级的下拉菜单

[css] 请使用css写一个多级的下拉菜单 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"…

Javascript报错Failed to execute ‘querySelectorAll‘ on ‘Document‘: ‘#123456‘ is not a valid sele

Javascript报错&#xff1a;Failed to execute ‘querySelectorAll’ on ‘Document’: ‘#123456’ is not a valid selector 解决方式(除开特殊符号,第一个字符必须是字母)&#xff1a; 第一种&#xff1a; 将ID前面加字母&#xff0c;例如&#xff1a;document.querySelect…

pycharm创建django项目linux部署

大家好&#xff0c;我是烤鸭&#xff1a; pytho部署web项目比java简单一点&#xff0c;虽然springboot内置了tomcat。 环境&#xff1a; pycharm专业版python3.6 1.安装python python下载&#xff1a;https://www.python.org/downloads/ 我使用的3.6版本 2.配置环境变量 path目…

【USACO15DEC】最大流Max Flow

题面 FJ给他的牛棚的N(2≤N≤50,000)个隔间之间安装了N-1根管道&#xff0c;隔间编号从1到N。所有隔间都被管道连通了。 FJ有K(1≤K≤100,000)条运输牛奶的路线&#xff0c;第i条路线从隔间si运输到隔间ti。一条运输路线会给它的两个端点处的隔间以及中间途径的所有隔间带来一个…

[css] 用css给一个元素加边框有哪些方法?

[css] 用css给一个元素加边框有哪些方法&#xff1f; :scope {border: 3px solid black;box-shadow: 0 0 0 1px black; /*不影响布局,无限叠加*/outline: 1px solid black; /*不支持圆角*/background-image: url("data:image/svgxml,%3Csvg xmlnshttp://www.w3.org/2000/…

java格式化html代码

/*** 格式化html代码* param model* param html* return*/RequestMapping("/formatHtml.dhtml")ResponseBodypublic M formatHtml(Model model,String html) {if(StringUtils.isNotBlank(html)) {try {Document doc Jsoup.parseBodyFragment(html);html doc.body()…

利用Android Studio快速搭建App

大家好&#xff0c;我是烤鸭: 给大家分享一个简单的用Android Studio快速搭建app 工具&#xff1a;Android Studio 64位 专业版 插件:Datepicker Timepicker okhttp 实现需求&#xff1a;界面上选择时间&#xff0c;发get/post请求到后台&#xff0c;获取选择的时间。1.修改And…

[css] 相邻兄弟选择器、后代选择器和子选择器三者有什么区别?

[css] 相邻兄弟选择器、后代选择器和子选择器三者有什么区别&#xff1f; 后代选择器与子选择的关系&#xff1a;后代选择器>子选择器。 后代选择器&#xff1a;包括父元素的子元素以及孙子元素&#xff08;代表符号&#xff1a;空格&#xff09;子选择器&#xff1a;包括父…

CompletableFuture的多线程和异步监听实现

大家好,我是烤鸭&#xff1a;今天给大家说的是多线程并发的异步监听的情况。这里不得不说一下CompletableFuture这个类&#xff0c;普通我们执行多线程的时候只需要另外启动一条线程。 说一下线程的3种方式&#xff1a;extends Thread&#xff0c;implements Runnable&#xff…

DCF:A Dataflow-Based Collaborative Filtering Trainging Algorithm

Abstratct:描述了当前协同过滤算法两大技术alternating least square(ALS,最小二乘法)和gradient descent(GD)的确定&#xff1a;原文&#xff1a;Existing collaborative filtering techniques are implemented with either alternating least square algorithm or gradient d…

[css] 举例说明你对相邻兄弟选择器的理解

[css] 举例说明你对相邻兄弟选择器的理解 divp{ //相邻兄弟选择器 background: red; } 符合两个条件就会被选中&#xff1a; 1.紧邻在另一个元素后面 2.两者父元素相同个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢…

HashMap jdk1.7和1.8概述

大家好&#xff0c;我是烤鸭&#xff1a;这是一篇关于HashMap的概述和底层原理的介绍。算是网上很多帖子的综合和我自己的一点想法。HashMap在jdk1.8以前是数组链表。在jdk1.8以后是数组链表红黑树。一点点分析数据结构。1. Map中的entry对象: static class Node<K,V> im…

springboot整合redis修改分区

转载的地址&#xff1a;https://blog.csdn.net/m0_37659871/article/details/81024068#commentBox springboot整合redis修改分区 问题由来 最近使用springboot整合redis&#xff0c;一个系统动态数据源连接不同数据库&#xff0c;缓存使用的redis&#xff0c;那么就需要将不同…

[css] 你是怎么设计css sprites(精灵图)的?有哪些技巧?

[css] 你是怎么设计css sprites&#xff08;精灵图&#xff09;的&#xff1f;有哪些技巧&#xff1f; 首先肯定不会去用PS量&#xff0c;那太费时间了~ 没有webpack以前&#xff0c;用Gulp的gulp.spritesmith插件&#xff0c;这里附上配置源码/* gulpfile.js */ const gulp …