zookeeper入门系列讲解
zookeeper可谓是目前使用最广泛的分布式组件了。其功能和职责单一,但却非常重要。
在现今这个年代,介绍zookeeper的书和文章可谓多如牛毛,本人不才,试图通过自己的理解来介绍zookeeper,希望通过一个初学者的视角来学习zookeeper,以期让人更加深入和平稳的理解zookeeper。其中参考了不少教程和书,相关书目列在文末,也感谢这些作者。
学习新的框架,先让我们搞清楚他是什么,这是它的内涵。然后再介绍它能做什么,这是它的外延,内涵和外延共同来定义框架本身,会对框架有较为深刻的理解,在应用层面上知道如何用。其次再搞清楚zookeeper相关的理论基础,其目的是知道zookeeper是如何被发明的,是否能够借鉴以便今后自己能够用到其他地方。最后搞清楚zookeeper中一些设计的原理和细节,目的也是搞清来龙去脉,学会“术”从而应用到别的地方。当然了,加深的理解同样能够帮助认识zookeeper本身,在使用时才知道为什么这样用。
一:首先,zookeeper到底是什么?
zookeeper实际上是yahoo开发的,用于分布式中一致性处理的框架。最初其作为研发Hadoop时的副产品。由于分布式系统中一致性处理较为困难,其他的分布式系统没有必要 费劲重复造轮子,故随后的分布式系统中大量应用了zookeeper,以至于zookeeper成为了各种分布式系统的基础组件,其地位之重要,可想而知。著名的hadoop、kafka、dubbo 都是基于zookeeper而构建。
要想理解zookeeper到底是做啥的,那首先得理解清楚,什么是一致性。
所谓的一致性,实际上就是围绕着“看见”来的。谁能看见?能否看见?什么时候看见?举个例子:淘宝后台卖家,在后台上架一件大促的商品,通过服务器A提交到主数据库,假设刚提交后立马就有用户去通过应用服务器B去从数据库查询该商品,就会出现一个现象,卖家已经更新成功了,然而买家却看不到;而经过一段时间后,主数据库的数据同步到了从数据库,买家就能查到了。
假设卖家更新成功之后买家立马就能看到卖家的更新,则称为强一致性;
如果卖家更新成功后买家不能看到卖家更新的内容,则称为弱一致性;
而卖家更新成功后,买家经过一段时间最终能看到卖家的更新,则称为最终一致性。
如何保证在分布式环境下数据的最终一致,这个就是zookeeper需要解决的问题。对于这些问题,有哪些挑战,zookeeper又是如何解决这些挑战的。

二:一些常见的解决一致性问题的方式:
1.查询重试补偿。对于分布式应用中不确定的情况,先使用查询接口查询到当前状态,如果当前状态不一致则采用补偿接口对状态进行重试推进,或者回滚接口对业务做回滚。典型的场景如银行跟支付宝之间的交互。支付宝发送一个转账请求到银行,如一直未收到响应,则可以通过银行的查询接口查询该笔交易的状态,如该笔交易对方未收到,则采取补偿的模式进行推送。
2.定时任务推送。对于上面的情况,有可能一次推送搞不定,于是需要2次,3次推送。不要怀疑,支付宝内最初掉单率很高,全靠后续不断的定时任务推送增加成功率。
3.TCC。try-confirm-cancel。实际上是两阶段协议,第二阶段的可以实现提交操作或是逆操作。
三:zookeeper到底能做什么?
在业界的实际应用是什么?了解这些应用,会对zookeeper能够做的事有更直观的认识。
1.hadoop
始祖级应用,ResourceManager在整个hadoop中算是单点,为了实现其高可用,分为主备ResourceManager,zookeeper在其中管理整个ResourceManager。
可以想象,主备ResourceManager最初是主RM提供服务,如果一切安好,则zookeeper无用武之地。然而,总归会出现主RM提供不了服务的情况。于是会出现主备切换的情况,而zookeeper正是为主备切换保驾护航。
先来推理一下,主备切换会出现什么问题。传统的主备切换,可以让主备之间维持心跳连接,一旦备机发现主机心跳检测不到了,则自己切换为主机,原来的主机等待救援。这种方式有两个问题,一是由于网络抖动,负载过大等问题,备机检测不到心跳并不能说明主机一定挂了,有可能一定时间后主机或网络恢复,这时候主机并不知道备机已经切换为主机,2台主机互相争用,可能造成脑裂;二是如果一些数据集中在主机上面,则备机切换时由于同步延时势必会损失掉一部分的数据。
如何解决这些问题?早期的方式提供了不少解决方案,比如备机一旦切换为主机,则通过电源控制直接切断主机电源,简单粗暴,但是此刻备机已经是单点,如果主机是因为量撑不住而挂,那备机有可能会重蹈覆辙,最终导致整个服务不可用。
四:zookeeper又是如何解决这个问题的呢?
zookeeper作为第三方集群参与到主备节点中去,当主备启动时会在zookeeper上竞争创建一个临时锁节点,争用成功者则充当主机,其余备机;
所有备机会监听该临时锁节点,一旦主机与zookeeper间session失效,则临时节点被删除;
一旦临时节点被删除,备机开始重新申请创建临时锁节点,重新争用为主机;
用zookeeper如何解决脑裂?实际上主机争用到节点后通过对根节点做一个ACL权限控制,则其他抢占的机器由于无法更新临时锁节点,只有放弃成为备机。
zookeeper使用了非常简单又现成的方式来解决的这个问题,比起其他方案方便不少,这也是为啥zookeeper流行的原因。说白了,就是把复杂操作封装化精简化。
1.dubbo
作为业界知名的分布式SOA框架,dubbo的主要的服务注册发现功能便是由zookeeper来提供的。
对于一个服务框架,注册中心是其核心中的核心,虽然暂时挂掉并不会导致整个服务出问题,但是一旦挂掉,整体风险就很高?悸且话闱榭?注册中心就是单台机器的时候,其实现很容易,所有机器起来都去注册服务给它,并且所有调用方都跟它保持长连接,一旦服务有变,即通过长连接来通知到调用方。但是当服务集群规模扩大时,这事情就不简单了,单机保持连接数有限,而且容易故障。
作为一个稳定的服务化框架,dubbo可以选择并推荐zookeeper作为注册中心。其底层将zookeeper常用的客户端zkclient和curator封装成为ZookeeperClient。
当服务提供者服务启动时,向zookeeper注册一个节点;
服务消费者则订阅其父节点的变化,诸如启动停止都能够通过节点创建删除得知,异常情况比如被调用方掉线也可以通过临时节点session 断开自动删除得知;
服务消费方同时也会将自己订阅的服务以节点创建的方式放到zookeeper;
于是可以得到映射关系,诸如谁提供了服务,谁订阅了谁提供的服务,基于这层关系再做监控,就能轻易得知整个系统情况。
五:zookeeper的基本数据模型
一句话,类似Linux文件系统的节点模型

其节点有如下有趣而又重要的特性:
1.同一时刻多台机器创建同一个节点,只有一个会争抢成功。利用这个特性可以做分布式锁。
2.临时节点的生命周期与会话一致,会话关闭则临时节点删除。这个特性经常用来做心跳,动态监控,负载等动作。
3.顺序节点保证节点名全局唯一。这个特性可以用来生成分布式环境下的全局自增长id。
通过zookeeper提供的原语服务,可以对zookeeper能做的事情有个精确和直观的认识。
六:zookeeper提供的原语服务
1.创建节点
2.删除节点
3.更新节点
4.获取节点信息
5.权限控制
6.事件监听
实际上,就是对节点的增删查改加上权限控制与事件监听,但是通过对这些原语的组合以及不同场景的使用,可以实现很多用法。
1.数据发布订阅。即注册中心,见上面dubbo用法。主要通过对节点管理做到发布以及事件监听做到订阅。
2.负载均衡。见上面kafka用法。
3.命名服务。zookeeper的节点结构天然支持命名服务,即把信息集中存储,并以树状管理,方便统一查阅。
4.分布式协调通知。协调通知实际上与发布订阅类似,由于引入的第三方的zookeeper,实际上对很多种协调通知做了解耦,比如参考文献4中提到的消息推送,心跳检测等。
5.集群管理与master选举。通过上面的第二点特性,可以轻易得知集群机器存活状况,从而轻松管理集群;通过上面第一点特性,可以做出master争抢。
6.分布式锁。实际上就是第一点特性的应用。
7.分布式队列。实际上就是第三点特性的应用。
8.分布式的并发等待。类似于多线程的join问题,主任务的执行依赖于其他子任务全部执行完毕,在单机多线程里可以用join,但是分布式环境下如何实现呢。利用zookeeper,可以创建一个主任务节点,旗下子任务一旦执行完毕,则在主任务节点下挂一个子任务节点,等节点数量足够,则认为主任务可以开始执行。
可以发现,所有的原语就是zookeeper的基础,而其他的用法总结无非是将原语放到不同场景下的归类罢了。
相信到这里你对zookeeper应该有个初步的了解和大致的印象了。
zookeeper入门系列讲解的更多相关文章
- zookeeper入门系列:概述
zookeeper可谓是目前使用最广泛的分布式组件了.其功能和职责单一,但却非常重要. 在现今这个年代,介绍zookeeper的书和文章可谓多如牛毛,本人不才,试图通过自己的理解来介绍zookeepe ...
- zookeeper 入门系列-理论基础 – zab 协议
上一章讨论了paxos算法,把paxos推到一个很高的位置.但是,paxos有没有什么问题呢?实际上,paxos还是有其自身的缺点的: 1. 活锁问题.在base-paxos算法中,不存在leader ...
- zookeeper入门系列 : 分布式事务
上一章我们了解了zookeeper到底是什么,这一章重点来看zookeeper当初到底面临什么问题?而zookeeper又是如何解决这些问题的? 实际上zookeeper主要就是解决分布式环境下的一致 ...
- zookeeper入门系列:paxos协议
上一章讨论了一种强一致性的情况,即需要分布式事务来解决,本章我们来讨论一种最终一致的算法,paxos算法. paxos算法是由大牛lamport发明的,关于paxos算法有很多趣事.比如lamport ...
- zookeeper编程入门系列之zookeeper实现分布式进程监控和分布式共享锁(图文详解)
本博文的主要内容有 一.zookeeper编程入门系列之利用zookeeper的临时节点的特性来监控程序是否还在运行 二.zookeeper编程入门系列之zookeeper实现分布式进程监控 三. ...
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数
上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...
- Angular2入门系列教程4-服务
上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...
- ABP入门系列(6)——展现层实现增删改查
这一章节将通过完善Controller.View.ViewModel,来实现展现层的增删改查.最终实现效果如下图: 一.定义Controller ABP对ASP.NET MVC Controllers ...
随机推荐
- 减少存储过程封装业务逻辑-web开发与传统软件开发的思维模式不同
本篇文章讨论并不是:不要使用存储过程,因为有些事情还是要存储过程来完成,不可能不用.而是关于:"业务逻辑是不是要封装在存储过程中实现,这样子php.java等就是调用存储过程". ...
- 【Unity Shader】三、漫反射Diffuse Shader例子
学习目标: 漫反射Diffuse Shader,逐顶点计算和逐像素计算. 半兰伯特(HalfLambert)光照模型. 结合材质自身的色彩(Material Color)及环境光(Ambient). ...
- C语言 · x的x次幂结果为10
如果x的x次幂结果为10(参见[图1.png]),你能计算出x的近似值吗? 显然,这个值是介于2和3之间的一个数字. 请把x的值计算到小数后6位(四舍五入),并填写这个小数值. 注意:只填写一个小数, ...
- C语言 · C++中map的用法详解
转载自:http://blog.csdn.net/sunquana/article/details/12576729 一.定义 (1) map<string, int> Map ...
- jpegtran图片压缩工具
首先下载 jpegtran 下载地址为 http://jpegclub.org/jpegtran.exe jpegtran -copy none -optimize -perfect aa.jp ...
- jquery easyui toolbar 分割线问题
http://bbs.csdn.net/topics/390507228 —————————————————————————————————— 将“<div class="datagr ...
- js学习(一)-动态添加、修改、删除对象的属性和方法
//-----------------------js代码--------------------------- function class1(){ } //-------------------- ...
- Java学习路线图,Java学习计划建议
怎么学习Java,这是很多新手经常遇到的问题,现在我简单描述下一个Java初学者到就业要学到的一些东西: 首先要明白Java体系设计到得三个方面:J2SE,J2EE,J2ME(KJAVA).J ...
- 在R中运行Shell命令脚本(Call shell commands from R)
aaa.R Args <- commandArgs()cat("Args[1]=",Args[1],"\n")cat("Args[2]=&quo ...
- linux刻录iso到u盘
需要的工具:Linux系统.U盘.ISO镜像文件.首先在Linux系统中打开终端,使用dd命令,格式如下:sudo dd if=xxx.iso of=/dev/sdb命令中xxx.iso是你的ISO镜 ...