Zookeeper 概念
Zookeeper:
Zookeeper是一个高可用的分布式管理与协调框架,基于ZAB算法(原子消息广播协议)的实现。该框架能够很好的保证分布式环境中数据的一致性。也只是基于这样的特性,使得Zookeeper成为了解决分布式一致性问题的利器。
Zookeeper的特性:
①顺序一致性:从一个客户端发起的事务请求,最终将会严格的按照其发起的顺序被应用到zookeeper中去。
②原子性:所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,也就是说,要么整个集群所有的机器都成功应用了某一事务,要么没有应用,一定不会出现部分机器应用了该事务,而另一部分没有应用的情况。
③单一视图:无论客户端连接的是哪一个zookeeper服务器,其看到的服务器端数据模型都是一致的。
④可靠性:一旦服务器成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务器端状态将会被一直保留,除非有另一个事务对其更改。
⑤实时性:通常所说的实时性就是指一旦事务被成功应用,那么客户端就能立刻从服务器上获取变更后的新数据,zookeeper仅仅能保证在一段时间内,客户端最终能从服务器端读取最新的数据状态。
Zookeeper原生api操作:
package com.qhong.zookeeper; import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids; import java.util.concurrent.CountDownLatch; public class ZookeeperBase { /** zookeeper地址 */
//static final String CONNECT_ADDR = "192.168.80.88:2181,192.168.80.87:2181,192.168.80.86:2181";
static final String CONNECT_ADDR="192.168.1.108:2181";
/** session超时时间 */
static final int SESSION_OUTTIME = ;//ms
/** 信号量,阻塞程序执行,用于等待zookeeper连接成功,发送成功信号 */
static final CountDownLatch connectedSemaphore = new CountDownLatch(); public static void main(String[] args) throws Exception{ ZooKeeper zk = new ZooKeeper(CONNECT_ADDR, SESSION_OUTTIME, new Watcher(){
@Override
public void process(WatchedEvent event) {
//获取事件的状态
KeeperState keeperState = event.getState();
EventType eventType = event.getType();
//如果是建立连接
if(KeeperState.SyncConnected == keeperState){
if(EventType.None == eventType){
//如果建立连接成功,则发送信号量,让后续阻塞程序向下执行
connectedSemaphore.countDown();
System.out.println("zk 建立连接");
}
}
}
}); //进行阻塞
connectedSemaphore.await(); System.out.println("..");
//创建父节点
zk.create("/testRoot", "testRoot".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); //创建子节点,使用EPHEMERAL,主程序执行完成后该节点被删除,只在本次会话内有效,可以用作分布式锁。
zk.create("/testRoot/children", "children data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); //获取节点信息
byte[] data = zk.getData("/testRoot", false, null);
System.out.println(new String(data));
System.out.println(zk.getChildren("/testRoot", false)); //修改节点的值,-1表示跳过版本检查,其他正数表示如果传入的版本号与当前版本号不一致,则修改不成功,删除是同样的道理。
zk.setData("/testRoot", "modify data root".getBytes(), -);
byte[] data2 = zk.getData("/testRoot", false, null);
System.out.println(new String(data2));
System.out.println("zk children is exists");
//判断节点是否存在
System.out.println(zk.exists("/testRoot/children", false));
System.out.println("delete children");
//删除节点
zk.delete("/testRoot/children", -);
System.out.println(zk.exists("/testRoot/children", false)); zk.close();
}
}
Output:
zk 建立连接
..
testRoot
[children]
modify data root
zk children is exists
,,,,,,,,,, delete children
null
Curator版本问题:
Curator .x.x - compatible with both ZooKeeper 3.4.x and ZooKeeper 3.5.x
Curator .x.x - compatible only with ZooKeeper 3.5.x and includes support for new features such as dynamic reconfiguration, etc.
Curator 2.x.x-兼容两个zk 3.4.x 和zk 3.5.x,Curator 3.x.x-兼容兼容zk 3.5。
应用场景:
1.统一服务器名称
命名服务器事一个比较常用的应用场景,客户端通过制定名字来获取服务器资源获或提供者信息等,被命名的可以服务器地址,远程对象。通过zk提供的创建节点的api,很容易创建一个全局唯一的path,这个path就可以做一个名称,
dubbo使用zk就是用来做服务器名称。维护全局的服务地址列表。
服务提供者在启动的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。
服务消费者启动的时候,订阅/dubbo/${serviceName}/providers目录下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目录下写入自己的URL地址。
注意,所有向ZK上注册的地址都是临时节点,这样就能够保证服务提供者和消费者能够自动感应资源的变化。 另外,Dubbo还有针对服务粒度的监控,方法是订阅/dubbo/${serviceName}目录下所有提供者和消费者的信息
2.统一配置管理
zk客户端api提供了操作znode数据的功能。再分布式环境中我们可以配置文件存放在znode上,不同的服务需要使用到哪些配置的时候可以直接从znode上去获取。而且通过zk 的心跳极值,我们的配置文件是可以做到动态配置的。一般的配置中心的做法是在系统启动之后加载我们的内存当中,一但配置文件需要做响应的调整的时候,需要重启服务进行load配置操作,但是很多的场景事我们只需要更改一点点的内容就去重启服务,代价不可谓不大。但zk就可以避免这问题的发生,当配置文件发生改变的时候,watch为通知到我们的服务对其修改操作。
3.分布式通知/协调
ZooKeeper中特有watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。使用方法通常是不同系统都对ZK上同一个znode进行注册,监听znode的变化(包括znode本身内容及子节点的),其中一个系统update了znode,那么另一个系统能够收到通知,并作出相应处理
1. 另一种心跳检测机制:检测系统和被检测系统之间并不直接关联起来,而是通过zk上某个节点关联,大大减少系统耦合。
2.另一种系统调度模式:某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作,实际上是修改了ZK上某些节点的状态,而ZK就把这些变化通知给他们注册Watcher的客户端,即推送系统,于是,作出相应的推送任务。
3. 另一种工作汇报模式:一些类似于任务分发系统,子任务启动后,到zk来注册一个临时节点,并且定时将自己的进度进行汇报(将进度写回这个临时节点),这样任务管理者就能够实时知道任务进度。
总之,使用zookeeper来进行分布式通知和协调能够大大降低系统之间的耦合
4.共享锁
分布式锁,这个主要得益于ZooKeeper为我们保证了数据的强一致性。锁服务可以分为两类,一个是 保持独占,另一个是 控制时序。
1. 所谓保持独占,就是所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁。通常的做法是把zk上的一个znode看作是一把锁,通过create znode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。
2. 控制时序,就是所有视图来获取这个锁的客户端,最终都是会被安排执行,只是有个全局时序了。做法和上面基本类似,只是这里 /distribute_lock 已经预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)。Zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。
5.队列管理
队列方面,简单地讲有两种,一种是常规的先进先出队列,另一种是要等到队列成员聚齐之后的才统一按序执行。对于第一种先进先出队列,和分布式锁服务中的控制时序场景基本原理一致,这里不再赘述。 第二种队列其实是在FIFO队列的基础上作了一个增强。通常可以在 /queue 这个znode下预先建立一个/queue/num 节点,并且赋值为n(或者直接给/queue赋值n),表示队列大小,之后每次有队列成员加入后,就判断下是否已经到达队列大小,决定是否可以开始执行了。这种用法的典型场景是,分布式环境中,一个大任务Task A,需要在很多子任务完成(或条件就绪)情况下才能进行。这个时候,凡是其中一个子任务完成(就绪),那么就去 /taskList 下建立自己的临时时序节点(CreateMode.EPHEMERAL_SEQUENTIAL),当 /taskList 发现自己下面的子节点满足指定个数,就可以进行下一步按序进行处理了。
6.master选举 在分布式环境中,相同的业务应用分布在不同的机器上,有些业务逻辑(例如一些耗时的计算,网络I/O处理),往往只需要让整个集群中的某一台机器进行执行,其余机器可以共享这个结果,这样可以大大减少重复劳动,提高性能,于是这个master选举便是这种场景下的碰到的主要问题。 利用ZooKeeper的强一致性,能够保证在分布式高并发情况下节点创建的全局唯一性,即:同时有多个客户端请求创建 /currentMaster 节点,最终一定只有一个客户端请求能够创建成功。利用这个特性,就能很轻易的在分布式环境中进行集群选取了。 另外,这种场景演化一下,就是动态Master选举。这就要用到EPHEMERAL_SEQUENTIAL类型节点的特性了。 上文中提到,所有客户端创建请求,最终只有一个能够创建成功。在这里稍微变化下,就是允许所有请求都能够创建成功,但是得有个创建顺序,于是所有的请求最终在ZK上创建结果的一种可能情况是这样: /currentMaster/{sessionId}-1 ,/currentMaster/{sessionId}-2,/currentMaster/{sessionId}-3 ….. 每次选取序列号最小的那个机器作为Master,如果这个机器挂了,由于他创建的节点会马上小时,那么之后最小的那个机器就是Master了。
1.在搜索系统中,如果集群中每个机器都生成一份全量索引,不仅耗时,而且不能保证彼此之间索引数据一致。因此让集群中的Master来进行全量索引的生成,然后同步到集群中其它机器。另外,Master选举的容灾措施是,可以随时进行手动指定master,就是说应用在zk在无法获取master信息时,可以通过比如http方式,向一个地方获取master。
2.在Hbase中,也是使用ZooKeeper来实现动态HMaster的选举。在Hbase实现中,会在ZK上存储一些ROOT表的地址和HMaster的地址,HRegionServer也会把自己以临时节点(Ephemeral)的方式注册到Zookeeper中,使得HMaster可以随时感知到各个HRegionServer的存活状态,同时,一旦HMaster出现问题,会重新选举出一个HMaster来运行,从而避免了HMaster的单点问题
选举问题:
新集群启动时候的选举过程,启动的时候就是根据zoo.cfg里的配置,向各个节点广播投票,一般都是选投自己。然后收到投票后就会进行进行判断。如果某个节点收到的投票数超过一半,那么它就是leader了。
一个问题:
一个集群有3台机器,挂了一台后的影响是什么?挂了两台呢?
挂了一台:挂了一台后就是收不到其中一台的投票,但是有两台可以参与投票,按照上面的逻辑,它们开始都投给自己,后来按照选举的原则,两个人都投票给其中一个,那么就有一个节点获得的票等于2,2 > (3/2)=1 的,超过了半数,这个时候是能选出leader的。
挂了两台: 挂了两台后,怎么弄也只能获得一张票, 1 不大于 (3/2)=1的,这样就无法选出一个leader了。
图片:
http://blog.csdn.net/haoyuyang/article/details/53414484
http://www.cnblogs.com/qiuyong/p/7081893.html
http://coolxing.iteye.com/blog/1871328
http://colobu.com/tags/Curator/
http://blog.csdn.net/wsong_14/article/details/77524331
https://www.cnblogs.com/huane/p/6399502.html
http://cailin.iteye.com/blog/2014486/
http://blog.jobbole.com/104833/?utm_source=blog.jobbole.com&utm_medium=relatedPosts
http://agapple.iteye.com/blog/1292129
https://www.cnblogs.com/leesf456/p/6012777.html
Zookeeper 概念的更多相关文章
- ZooKeeper概念
这可能是把ZooKeeper概念讲的最清楚的一篇文章 相信大家对 ZooKeeper 应该不算陌生,但是你真的了解 ZooKeeper 是什么吗?如果别人/面试官让你讲讲 ZooKeeper 是什么, ...
- 这可能是把ZooKeeper概念讲的最清楚的一篇文章
我本人曾经使用过 ZooKeeper 作为 Dubbo 的注册中心,另外在搭建 Solr 集群的时候,我使用到了 ZooKeeper 作为 Solr 集群的管理工具. 前几天,总结项目经验的时候,我突 ...
- ZooKeeper原理 --------这可能是把ZooKeeper概念讲的最清楚的一篇文章
相信大家对 ZooKeeper 应该不算陌生,但是你真的了解 ZooKeeper 是什么吗?如果别人/面试官让你讲讲 ZooKeeper 是什么,你能回答到哪个地步呢? 我本人曾经使用过 ZooKee ...
- zookeeper概念与原理
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等. 1 Zookeeper的基本概念 1.1 角色 ...
- 可能是把 ZooKeeper 概念讲的最清楚的一篇文章
转载自:https://github.com/Snailclimb/JavaGuide/blob/master/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6/ZooKeep ...
- ZooKeeper概念与应用
Zookeeper是开源的分布式协调服务,提供了分布式数据一致性的解决方案. Zookeeper 可用作配置中心和分布式锁服务,在 Dubbo.Kafka.Spark等分布式集群上得到广泛应用. ZN ...
- 8.1.Zookeeper概念简介
1.分布式系统概述 理解1: 分布式系统:分布式系统是针对一个大系统而言,将一个大系统分成多个子系统,即多个工程系统. 我们先看下传统的系统模式: 传统的系统模式将多个功能模块全部在一个工程中写 ...
- Zookeeper与Kafka基础概念和原理
1.zookeeper概念介绍 在介绍ZooKeeper之前,先来介绍一下分布式协调技术,所谓分布式协调技术主要是用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种共享资源,防止造成 ...
- zookeeper基本概念及原理
zookeeper是一个分布式的,开源的分布式应用程序,该程序主要用于管理其他分布式应用程序.其他分布式应用程序可以基于zookeeper实现数据同步,配置维护和命名服务等等.zookeeper是Ha ...
随机推荐
- 14nm或于6月量产,中芯首次披露12nm及第二代FinFET "N+1"计划(详细数据)
日前中芯国际公布2018年度第四季度业绩,实现营收7.88亿美元,14nm工艺进入客户验证阶段,可望于今年6月份量产,且12nm工艺开发取得突破. 根据中芯国际披露的财报,2018年第四季度实现营业收 ...
- 通过PyPI镜像安装Python包
有时,我们直接用pip install package_name安装包时,下载很慢,我们可以尝试从PyPI镜像下载包. 这里是镜像列表和目前的状态: http://www.pypi-mirrors.o ...
- IO流(3)删除文件或文件夹
删除功能:public boolean delete() * * 注意: * A:如果你创建文件或者文件夹忘了写盘符路径,那么,默认在项目路径下. * B:Java中的删除不走回收站. * C:要删除 ...
- linux,centOS,用LNMP搭建wordpress,更新固定连接--全流程
下午到晚上的时间,买了个linux服务器,用的centOS系统,遇到各种问题! 1.用putty,ssh到vps后,根据网上命令,一步步下载并安装,具体步骤可以看一下网上教程,LNMP.org站上的教 ...
- react-native 完整实现登录功能
react native实现登录功能,包括ui的封装.网络请求的封装.导航器的实现.点击事件. demo下载:react-native 完整实现登录功能 后台如果是springmvc实现的需要配置上如 ...
- <转>MySQL临时表的简单用法
当工作在非常大的表上时,你可能偶尔需要运行很多查询获得一个大量数据的小的子集,不是对整个表运行这些查询,而是让MySQL每次找出所需的少数记录,将记录选择到一个临时表可能更快些,然后在这些表运行查询. ...
- [py]python的继承体系-源码目录结构
python3安装目录 pip install virtualenv pip install virtualenvwrapper pip install virtualenvwrapper-win m ...
- MySQL IFNULL()函数用法MySQL
用法说明:IFNULL(expr1,expr2) 如果 expr1 不是 NULL,IFNULL() 返回 expr1,否则它返回 expr2. IFNULL()返回一个数字或字符串值,取决于它被使用 ...
- Qt 布局管理器
在一个颜值当道的今天,无论买衣服,买车还是追星,颜值的高低已经变成了大家最看重的(不管男性女性都一样,千万别和我说你不是):而对于程序猿来说,开发一款软件,不再只注重逻辑和稳定性,美观和用户友好性也是 ...
- UVM中的regmodel建模(一)
UVM中的regmodel继承自VMM的RAL(Register Abstract Layer),现在可以先将寄存器模型进行XML建模,再通过Synopsys 家的工具ralgen来直接生成regmo ...