zookeeper(3)分布式锁

在一个分布式系统中,如何保证一个操作,同一时间只有一个线程可以执行,这就是分布式锁的使用场景,同一时间,只有一个线程可以获得锁的使用权。

如何实现一个分布式锁?

实现一个分布式锁,可以有以下3种方法。

一、基于数据库实现分布式锁。

1、在MySQL中,使用悲观锁"select from t where id = for update"可以对行数据进行加锁,来实现分布式锁。
2、同一个时间内,只会有一个线程加锁成功,其他线程必须等待。
3、数据库要保证是全局的,每一把锁所对应的行数据也是唯一的。

优点:

1、实现简单,方便。

缺点:

1、基于数据库的悲观锁,性能比较差。
2、等待中的线程是自旋的或者等待状态,需要等待持有锁的线程处理完,多个线程再一起去竞争同一把锁。
3、异常无法处理,当持有锁的线程还没有释放锁,意外退出,锁资源将无法释放,应用程序将无法继续进行。

二、基于redis实现的分布式锁。

1、使用redis的setnx命令,可以模拟分布式锁,setnx保证操作一个key值,如果没有则返回true,如果存在则返回false。
2、为了解决程序意外退出导致无法释放锁资源,需要给key增加一个超时时间。
3、redis提供了带参数的命令,可以保证设置key值和设置超时时间这2个操作的原子性

SET key value [EX seconds] [PX milliseconds] [NX|XX]

4、假如有如下情况:

A获取了锁,设置了超时时间为10秒,但是A执行了15秒,在10秒的时候锁失效了。
B在11秒的时候获取了锁,执行了5秒,那么A在15秒的时候会误删掉B的锁。

为了解决以上问题,每个加锁的线程都需要设置自己的value值,当删除的时候也要校验是自己的锁,才可以删除。

优点:

1、实现简单,方便。
2、基于redis的高性能,效率高。

缺点:

1、无法解决超时锁失效问题,逻辑处理的时间超过了设置的超时时间,那么这个时候就会导致,另一个也可以拿到锁继续执行。

为了解决这个问题,一般的方法是启动一个守护线程,时刻监控失效时间,当锁时间超过一定的执行时间比例之后,自动续约一定的时间,当然这个总时间是有最大阈值限制的。

2、等待中的线程是自旋的后者等待状态,需要等待持有锁的线程处理完,多个线程再一起去竞争同一把锁。

三、zookeeper实现分布式锁

方式1:悲观锁

1、使用临时节点实现分布式锁,第一个创建临时节点成功的线程,获取锁成功。
2、其他创建临时节点的线程会失败,那么监听锁的临时节点。
3、当锁释放的时候,删除临时节点,会通知到监听的线程,收到通知的线程继续尝试创建临时锁节点,谁创建成功谁获得锁。

优点:

解决了锁失效问题,通知机制可以完美解决,即使创建临时节点的线程挂掉,临时节点会自动删除。

缺点:

1、当有大量线程,等待锁资源的时候,锁资源释放会涉及到大量的通知,并且大量的线程需要一起竞争锁资源。

方式2:乐观锁

1、在一个目录下,各个线程创建顺序的临时节点,节点编号1、2、3、4、5等。
2、目录下创建的节点最小的线程获取锁。
3、等待锁资源的线程,不再一起全部监听锁节点,而是只监听比自己小的上一个节点。
4、当监听的比自己小的锁节点被删除后,继续改为监听上一个比自己小的节点。
4、当锁释放的时候,只需要通知监听锁节点的一个获几个线程,避免了大量的通知。

zookeeper实现的乐观锁,是比较合理的分布式锁方式,感兴趣的朋友可以用代码实现一下。

原文地址:https://blog.51cto.com/janephp/2438552

时间: 2024-10-16 22:08:52

zookeeper(3)分布式锁的相关文章

[ZooKeeper.net] 3 ZooKeeper的分布式锁

基于ZooKeeper的分布式锁  源码分享:http://pan.baidu.com/s/1miQCDKk ZooKeeper 里实现分布式锁的基本逻辑: 1.zookeeper中创建一个根节点(Locks),用于后续各个客户端的锁操作. 2.想要获取锁的client都在Locks中创建一个自增序的子节点,每个client得到一个序号,如果自己的序号是最小的则获得锁. 3.如果没有得到锁,就监控排在自己前面的序号节点,并且设置默认时间,等待它的释放. 4.业务操作后释放锁,然后监控自己的节点的

基于zookeeper实现分布式锁

一.分布式锁介绍 分布式锁主要用于在分布式环境中保护跨进程.跨主机.跨网络的共享资源实现互斥访问,以达到保证数据的一致性. 线程锁:大家都不陌生,主要用来给方法.代码块加锁.当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一个线程在执行该段代码.当有多个线程访问同一对象的加锁方法/代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段.但是,其余线程是可以访问该对象中的非加锁代码块的. 进程锁:也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为

基于redis和zookeeper的分布式锁实现方式

先来说说什么是分布式锁,简单来说,分布式锁就是在分布式并发场景中,能够实现多节点的代码同步的一种机制.从实现角度来看,主要有两种方式:基于redis的方式和基于zookeeper的方式,下面分别简单介绍下这两种方式: 一.基于redis的分布式锁实现 1.获取锁 redis是一种key-value形式的NOSQL数据库,常用于作服务器的缓存.从redis v2.6.12开始,set命令开始变成如下格式: SET key value [EX seconds] [PX milliseconds] [

利用Zookeeper实现分布式锁及服务注册中心

原文:利用Zookeeper实现分布式锁及服务注册中心 对于Zookeeper的定义以及原理,网上已经有很多的优秀文章对其进行了详细的介绍,所以本文不再进行这方面的阐述. 本文主要介绍一些基本的准备工作以及zookeeper.net的使用. 本文源代码github地址:https://github.com/Mike-Zrw/ZookeeperHelper zookeeper下载地址:https://archive.apache.org/dist/zookeeper/ ZooInspector下载

zookeeper实现分布式锁优于redis的分布式锁

redis的分布式锁,基于while循环不停的尝试,可以回导致占用cpu,能减缓的方法就是通过sleep一段时间 再去尝试,其实并不ok zookeeper做分布式锁, 是通过在zk上新建一个根node 通过client下面新建临时的node 把这些Node的id的序号设置成有序的,当前client判断这个id是否是最小的,如果是最小的,就执行逻辑,然后断开连接,放掉锁,zk会自动删除这个临时节点,然后这时候发生了变化,会调用client的watcher方法,client判断自己的id是否是最小

Redis实现分布式锁与Zookeeper实现分布式锁区别

Redis实现分布式锁与Zookeeper实现分布式锁区别 **前言: 在学习过程中,简单的整理了一些redis跟zookeeper实现分布式锁的区别,有需要改正跟补充的地方,希望各位大佬及时指出**Redis实现分布式锁思路 基于Redis实现分布式锁(setnx)setnx也可以存入key,如果存入key成功返回1,如果存入的key已经存在了,返回0. Zookeeper实现分布式锁思路 基于Zookeeper实现分布式锁 Zookeeper是一个分布式协调工具,在分布式解决方案中. 多个客

SpringBoot电商项目实战 — Zookeeper的分布式锁实现

上一篇演示了基于Redis的Redisson分布式锁实现,那今天我要再来说说基于Zookeeper的分布式现实. Zookeeper分布式锁实现 要用Zookeeper实现分布式锁,我就不得不说说zookeeper的数据存储.首先zookeeper的核心保存结构是一个DataTree数据结构,其实内部是一个Map<String, DataNode> nodes的数据结构,其中key是path,DataNode才是真正保存数据的核心数据结构,DataNode核心字段包括byte data[]用于

【Zookeeper】分布式锁

一.概述 实现原理 实现代码 一.概述 分布式锁解决方案(目的:为了保证在分布式领域中共享数据安全问题) 数据库实现分布式锁(不推荐.效率特别低) 基于Redis实现分布式锁setNx (非常麻烦考虑死锁.释放问题) .redission分布式锁 基于Zookeeper实现分布式锁(强烈推荐) SpringCloud内置实现全局锁(冷门)实现起来非常简单,使用临时节点释放锁(效率最高).失效时间容易控制 分布式锁(产生的原因:因为服务器产生集群) 在单台服务器上如何生成订号( 保证唯一) UUI

ZooKeeper学习(二)ZooKeeper实现分布式锁

一.简介 在日常开发过程中,大型的项目一般都会采用分布式架构,那么在分布式架构中若需要同时对一个变量进行操作时,可以采用分布式锁来解决变量访问冲突的问题,最典型的案例就是防止库存超卖,当然还有其他很多的控制方式,这篇文章我们讨论一下怎么使用ZooKeeper来实现分布式锁. 二.Curator 前面提到的分布式锁,在ZooKeeper中可以通过Curator来实现. 定义:Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开

基于zookeeper的分布式锁实现 【转】

工作中需要写一个定时任务,由于是集群环境,自然而然想到需要通过分布式锁来保证单台执行..相信大家都会想到使用zk来实现对应的分布式锁.下面就简单介绍一下几种实现 准备工作 有几个帮助类,先把代码放上来 ZKClient 对zk的操作做了一个简单的封装 Java代码 ZKUtil 针对zk路径的一个工具类 Java代码 NetworkUtil 获取本机IP的工具方法 Java代码 --------------------------- 正文开始  -------------------------