ZK和Redis两种分布式锁对比
一、Redis分布式锁
1、setnx + lua脚本
优点:redis基于内存,读写性能很高,因此基于redis的分布式锁效率比较高
缺点:分布式环境下可能会有节点数据同步问题,可靠性有一定的影响。比如现在有一个3主3丛的Redis集群, 客户端发生的命令写入了机器1的master
节点,数据正准备主丛同步的时候,master
结点挂了,slave
结点没有接收到最新的数据,此时 slave
结点竞选为master
, 导致之前加的分布式锁失效。
2、Redission
优点:解决了Redis集群的同步可用性问题
缺点:网上是说:发布时间短,稳定性和可靠性有待验证。个人觉得,目前市面上已经稳定了,算是比较成熟的比较完善的分布式锁了。
3、Redis分布式锁的缺点
如果你对某个redis master实例,写入了myLock这种锁key的value,此时会异步复制给对应的master slave实例。
但是这个过程中一旦发生redis master宕机,主备切换,redis slave变为了redis master。接着就会导致,客户端2来尝试加锁的时候,在新的redis master上完成了加锁,而客户端1也以为自己成功加了锁。
此时就会导致多个客户端对一个分布式锁完成了加锁。这时系统在业务语义上一定会出现问题,导致各种脏数据的产生。
所以这个就是redis cluster,或者是redis master-slave架构的主从异步复制导致的redis分布式锁的最大缺陷:在redis master实例宕机的时候,可能导致多个客户端同时完成加锁。
二、ZK分布式锁
优点:不存在redis的数据同步(zookeeper是同步完以后才返回)、主从切换(zookeeper主从切换的过程中服务是不可用的)的问题,可靠性很高
缺点:保证了可靠性的同时牺牲了一部分效率(但是依然很高)。性能不如redis。
1、排他锁
排他锁(Exclusive Locks),又被称为写锁或独占锁,如果事务T1对数据对象O1加上排他锁,那么整个加锁期间,只允许事务T1对O1进行读取和更新操作,其他任何事务都不能进行读或写。
定义锁:/exclusive_lock/lock
实现方式:
利用 zookeeper 的同级节点的唯一性特性,在需要获取排他锁时,所有的客户端试图通过调用 create() 接口,在 /exclusive_lock 节点下创建临时子节点 /exclusive_lock/lock,最终只有一个客户端能创建成功,那么此客户端就获得了分布式锁。同时,所有没有获取到锁的客户端可以在 /exclusive_lock 节点上注册一个子节点变更的 watcher 监听事件,以便重新争取获得锁。
2、共享锁
共享锁(Shared Locks),又称读锁。如果事务T1对数据对象O1加上了共享锁,那么当前事务只能对O1进行读取操作,其他事务也只能对这个数据对象加共享锁,直到该数据对象上的所有共享锁都释放。
定义锁: /shared_lock/[hostname]-请求类型W/R-序号
实现方式:
1、客户端调用 create 方法创建类似定义锁方式的临时顺序节点。
2、客户端调用 getChildren 接口来获取所有已创建的子节点列表。
3、判断是否获得锁,对于读请求如果所有比自己小的子节点都是读请求或者没有比自己序号小的子节点,表明已经成功获取共享锁,同时开始执行度逻辑。对于写请求,如果自己不是序号最小的子节点,那么就进入等待。
4、如果没有获取到共享锁,读请求向比自己序号小的最后一个写请求节点注册 watcher 监听,写请求向比自己序号小的最后一个节点注册watcher 监听。
3、curator 的几种锁方案
实际开发过程中,可以 curator 工具包封装的API帮助我们实现分布式锁。
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.0.1</version>
</dependency>
- 1、InterProcessMutex:分布式可重入排它锁
- 2、InterProcessSemaphoreMutex:分布式排它锁
- 3、InterProcessReadWriteLock:分布式读写锁
下面例子模拟 50 个线程使用重入排它锁 InterProcessMutex 同时争抢锁:
public class InterprocessLock {public static void main(String[] args) {CuratorFramework zkClient = getZkClient();String lockPath = "/lock";InterProcessMutex lock = new InterProcessMutex(zkClient, lockPath);//模拟50个线程抢锁for (int i = 0; i < 50; i++) {new Thread(new TestThread(i, lock)).start();}}static class TestThread implements Runnable {private Integer threadFlag;private InterProcessMutex lock;public TestThread(Integer threadFlag, InterProcessMutex lock) {this.threadFlag = threadFlag;this.lock = lock;}@Overridepublic void run() {try {lock.acquire();System.out.println("第"+threadFlag+"线程获取到了锁");//等到1秒后释放锁Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}finally {try {lock.release();} catch (Exception e) {e.printStackTrace();}}}}private static CuratorFramework getZkClient() {String zkServerAddress = "192.168.3.39:2181";ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3, 5000);CuratorFramework zkClient = CuratorFrameworkFactory.builder().connectString(zkServerAddress).sessionTimeoutMs(5000).connectionTimeoutMs(5000).retryPolicy(retryPolicy).build();zkClient.start();return zkClient;}
}
秒杀、红包源码参考:
spring-boot-seckill: 从0到1构建分布式秒杀系统,脱离案例讲架构都是耍流氓,交流群:933593697https://gitee.com/xiaxinyu3_admin/spring-boot-seckill.git
ZK和Redis两种分布式锁对比相关推荐
- java 通过redis实现倒计时_突破Java面试(42) - Redis amp; ZooKeeper两种分布式锁实现的优劣...
0 Github 1 面试题 一般实现分布式锁都有哪些方式?使用redis如何设计分布式锁?使用zk来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高? 2 考点分析 一般先问问你zk,然后 ...
- zookeeper快速入门——应用(两种分布式锁)
在<zookeeper快速入门--简介>一文中,我们介绍了zookeeper的机制.但是还是比较抽象,没有直观感受到它在分布式系统中的应用.本文我们使用一个例子,三次迭代演进,来说明Zoo ...
- 阿里JAVA面试题剖析:一般实现分布式锁都有哪些方式?使用 Redis 如何设计分布式锁?...
面试原题 一般实现分布式锁都有哪些方式?使用 redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高? 面试官心理分析 其实一般问问题,都是这么问的,先 ...
- redis ,redisson 分布式锁深入剖析
目录 为什么要用分布式锁? 分布式锁所遵循的原则? redis 分布式锁 redis 原始分布式锁实现 加锁 释放锁 redis 分布式锁存在的问题 redisson 实现分布式锁 redisson ...
- 什么是分布式锁?几种分布式锁分别是怎么实现的?
一.什么是分布式锁: 1.什么是分布式锁: 分布式锁,即分布式系统中的锁.在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题.与单体应用不同 ...
- 【分布式锁】三种分布式锁的实现【原创】
分布式锁 0x00 概述 0x02 实现方式 0x03 分布式锁:基于数据库 1. 实现思想 A. 悲观锁(排他锁) B. 乐观锁 2. 优缺点 0x04 分布式锁:基于Zookeeper 1. 实现 ...
- Redlock——Redis集群分布式锁
欢迎关注方志朋的博客,回复"666"获面试宝典 前言 分布式锁是一种非常有用的技术手段.实现高效的分布式锁有三个属性需要考虑: 安全属性:互斥,不管什么时候,只有一个客户端持有锁 ...
- Redis 集群分布式锁与 API 网关分布式限流
https://www.infoq.cn/article/FoQGIk*BzdQWJJ0tKqrJ Redis 集群的历史 Redis 在 3.0 前一般有两种集群方案,一是 proxy(Twempr ...
- 基于 Redis 实现的分布式锁
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:我的大学到研究生自学 Java 之路,过程艰辛,不放弃,保持热情,最终发现我是这样拿到大厂 offer 的! 作 ...
最新文章
- r 语言计算欧氏距离_一文搞懂常用R语言统计值计算:打倒描述性统计拦路虎
- 网易云课堂计算机体系,计算机系统结构 (三) CPU及其结构分析
- 当模板方法遇到了委托函数,你的代码又可以精简了
- 计算机科学与技术的感性认识,对计算机科学与技术学科的简单认识
- bzoj3214 [Zjoi2013]丽洁体 dp
- ★LeetCode(182)——查找重复的电子邮箱(MySQL)
- 华为出售荣耀为不实消息,赵明曾在内部否认;迅雷前CEO陈磊涉嫌职务侵占罪被调查 ;Python 3.9发布|极客头条...
- PHP中ob系列函数讲解(浏览器缓存技术)
- 读《卓有成效的管理者》笔记(二)
- 笔记本系统恢复连载之十:系统恢复并不难
- 勒让德多项式学习笔记
- MFC Windows程序设计源代码免费下载
- [ERP/鼎捷E10][销售分销]发出商品余额表取数逻辑及SQL
- 如何将npy导入matlab,如何在Matlab中读取.npy文件(How to read .npy files in Matlab)
- 无需格式化 移动硬盘/U盘上装WinPE、Win7PE图解
- Win11此应用无法在你的电脑上运行怎么解决
- 十年测试老鸟聊聊移动端兼容性测试
- 第4章 计算机网络自顶向下——网络层:数据平面
- 神州战神笔记本开启/关闭键盘背光灯的方法,control center使用配置,控制风扇转速,减少噪音
- 分享个梦塔防辅助工具,自动化控制刷图升级脚本
热门文章
- SLF4J-bridge
- 2017 山东理工第九届校赛 C 康纳的表情包
- Java SQLSyntaxErrorException: Key column ‘xxx‘ doesn‘t exist in table问题解决
- Landsat 8(二)
- IIS Url Rewrite重写不生效
- 全面了解什么是等离子显示器?【mfxp】
- NPN三极管 Sentaurus vs SILVACO TCAD 模拟比较----Gumml 曲线与输出特性曲线Ic-Uce
- vss中如何从其他目录将文件拷至项目目录下
- gojs给线添加鼠标移上去显示内容的事件,类似title属性
- 渗透测试必不可少的浏览器插件