分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了


Posted in Redis onMay 21, 2021

在分布式的应用中,为了防止单点故障,保障高可用,通常会采用主从结构,当主节点挂掉后,从节点可以代替主节点提供服务。

Redis通过复制 + sentinel哨兵来实现主从模式。

Zookeeper通过replicated mode复制模式来实现主从模式。

单从结构上看,Redis和Zookeeper都是主从架构,那Zookeeper的优势是什么?为什么要选择Zookeeper?难道只是因为Zookeeper是目录结构,Redis是K-V结构吗?

同步机制的不同

Redis

Redis在给从节点同步数据时,正常情况是增量同步,也就是主节点的数据修改语句(DML)会异步的同步给从节点。Redis的数据同步没有保障数据一致性的机制,也就是说,一条DML在主节点执行成功时,不能保障其他从节点成功执行了这条数据,这就会造成一个问题,如果在数据没有同步到从节点时,主节点挂掉,就会产生数据丢失的情况。

Zookeeper

Zookeeper使用类paxos算法来保障数据的一致性。简单的讲,当一个DML语句发送给主节点时,Zookeeper需要保证一半以上的节点接收到数据,才会返回成功。并且当主节点挂掉,从节点重新选举时,同步到最新的数据的节点会有优先选举权。

举个例子:

一个4节点Zookeeper(A、B、C、D),A是主节点,当执行一个create语句成功时,至少有3台节点执行成功(一半以上),例如A、C、D成功。此时如果A节点挂了,B、C、D进行选举,由于C、D都执行成功了create语句,B没有执行,C、D的数据更加新,具有优先选举权,再根据名称排序,选择C做为主节点。在整个选举过程中,服务不可用,选举完成后,C节点和A节点数据一致,不会出现丢失的情况。

分布式锁

要实现分布式锁,需要满足一些要求:

  • 只能有一个服务的一个线程能获取锁
  • 一个持有锁的线程挂掉后,锁应该被释放,用来给其他线程用
  • 一个持有锁的线程没执行完,锁不能释放
  • 锁释放后,其他等待者可以继续争抢
  • 管理锁的主节点(Redis或Zookeeper)挂了,重新选举后,不影响锁的持有情况

Redis解决方案

问题1、问题2:使用“SET key value EX seconds NX”语句获取锁并设置过期时间

问题3:另开一个监控线程,监控主线程执行情况,用来延长过期时间

问题4:等待线程定时检查锁的持有情况

问题5:暂无或者解决成本很高,需要自己实现类paxos的算法

Zookeeper解决方案

通过创建临时节点可以解决问题1,2,3

watch机制可以解决问题4,并且相比定时检查,watch可以做到更高实时性

zookeeper的paxos同步机制保障了节点间数据一致性,即使主节点挂掉,也可以保障数据不丢,可以解决问题5

对比可以发现:

Zookeeper的机制可以保证分布式锁实现业务代码简单,成本低。

Redis如果要解决分布式锁的问题,对于一些复杂的情况,很难解决,成本较高。

以上就是分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了的详细内容,更多关于分布式锁Zookeeper Redis的资料请关注三水点靠木其它相关文章!

Redis 相关文章推荐
Redis5之后版本的高可用集群搭建的实现
Apr 27 Redis
使用Redis实现秒杀功能的简单方法
May 08 Redis
你真的了解redis为什么要提供pipeline功能
Jun 22 Redis
redis客户端实现高可用读写分离的方式详解
Jul 04 Redis
Redis性能监控的实现
Jul 09 Redis
源码分析Redis中 set 和 sorted set 的使用方法
Mar 22 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
Redis基本数据类型哈希Hash常用操作命令
Jun 01 Redis
Redis keys命令的具体使用
Jun 05 Redis
redis lua限流算法实现示例
Jul 15 Redis
Redis主从复制操作和配置详情
Sep 23 Redis
Redis 配置文件重要属性的具体使用
May 20 #Redis
浅谈redis缓存在项目中的使用
May 20 #Redis
详解Redis主从复制实践
详解redis分布式锁的这些坑
为Java项目添加Redis缓存的方法
redis内存空间效率问题的深入探究
深入浅析Redis 集群伸缩原理
You might like
Google Voice 短信发送接口PHP开源版(2010.5更新)
2010/07/22 PHP
解析PHP缓存函数的使用说明
2013/05/10 PHP
PHP数组排序函数合集 以及它们之间的联系分析
2013/06/27 PHP
PHP与jquery实时显示网站在线人数实例详解
2016/12/02 PHP
laravel Validator ajax返回错误信息的方法
2019/09/29 PHP
解决Laravel5.5下的toArray问题
2019/10/15 PHP
php生成随机数/生成随机字符串的方法小结【5种方法】
2020/05/27 PHP
让iframe框架网页在任何浏览器下自动伸缩
2006/08/18 Javascript
JS弹出对话框返回值代码(asp.net后台)
2010/12/28 Javascript
JavaScript中为什么null==0为false而null大于=0为true(个人研究)
2013/09/16 Javascript
JavaScript数据结构与算法之集合(Set)
2016/01/29 Javascript
AngularJS数据源的多种获取方式汇总
2016/02/02 Javascript
深入理解事件冒泡(Bubble)和事件捕捉(capture)
2016/05/28 Javascript
JavaScript中利用构造器函数模拟类的方法
2017/02/16 Javascript
bootstrap fileinput 插件使用项目总结(经验)
2017/02/22 Javascript
正则验证小数点后面只能有两位数的方法
2017/02/28 Javascript
Javascript ES6中对象类型Sets的介绍与使用详解
2017/07/17 Javascript
微信小程序利用canvas 绘制幸运大转盘功能
2018/07/06 Javascript
浅谈Vue中render中的h箭头函数
2019/11/07 Javascript
Vue组件通信入门之Provide和Inject机制
2019/12/29 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
python实现机器学习之多元线性回归
2018/09/06 Python
python文字和unicode/ascll相互转换函数及简单加密解密实现代码
2019/08/12 Python
27个经典Linux面试题及答案,你知道几个?
2013/01/10 面试题
小学生演讲稿
2014/01/12 职场文书
英语感恩演讲稿
2014/01/14 职场文书
十八届三中全会感言
2014/03/10 职场文书
1亿有多大教学反思
2014/05/01 职场文书
小学五年级语文上册教学计划
2015/01/22 职场文书
2016年寒假家长评语
2015/10/10 职场文书
2016年先进班集体事迹材料
2016/02/26 职场文书
幼儿园2016年圣诞活动总结
2016/03/31 职场文书
nginx配置ssl实现https的方法示例
2021/03/31 Servers
Pytest之测试命名规则的使用
2021/04/16 Python
漫画「你在春天醒来」第10卷封面公开
2022/03/21 日漫
MySQL外键约束(Foreign Key)案例详解
2022/06/28 MySQL