代码:https://github.com/xufeng79x/ZkClientTest

1. 简介

  zookeeper的特性决定他适用到某些场景非常合适,比如典型的应用场景:

  1.集群管理(Group Membership)

  2.统一命名服务(Name Service)

  3.配置管理(Configuration Management)

  4.共享锁(Locks)

  5.队列管理

2.集群管理

   在hadoop中主备节点的概念大家都应该不默认,比如HBase中,我们可以启动多个master节点,但是在某时刻只有一个主master,当这个主master节点退出后

其他的背master将会去争取成为主master。一般流程为:

  如上,一开始的时候多个master都会去zookeeper服务上创建相同的临时路径,其中某个master会节点会成功创建,那么这个节点就是主master了,其他创建不成功的将会观察这个临时路径。

当主master由于宕机或者网络原因失去和zookeeper的连接(session)那么这个临时节点就会被zookeeper删除,随后其他备master将会感知到,再去争抢这个临时路径的创建权。

  如下代码利用多线程来模拟多个master的场景:

public class Master implements Runnable {
// master节点路径
private String masterPath = null; // 当前master的信息
private MasterInfo myinfo = null; // 当前主master的信息
private MasterInfo activeMasterInfo = null; // 控制当前master的运行时间
private long runningTime = ; // 监控handler
private IZkDataListener masterPathListener = null; // 当前session
private ZkClient zc = new ZkClient("xufeng-1:2181,xufeng-2:2181,xufeng-3:2181", , , new SerializableSerializer());
public Master(MasterInfo info, long runningTime, String masterPath)
{
this.myinfo = info;
this.runningTime = runningTime;
this.masterPath = masterPath;
this.masterPathListener = new IZkDataListener() {
// 当节点被删除的时候触发此方法
public void handleDataDeleted(String dataPath) throws Exception {
attackMaster();
} public void handleDataChange(String dataPath, Object data) throws Exception {
// do nothing }
}; // 订阅节点
zc.subscribeDataChanges(masterPath, masterPathListener);
} public void run() {
attackMaster();
try {
Thread.sleep(runningTime);
} catch (InterruptedException e) {
// do nothing
}
} // 去争抢这个节点创建(注册)
private void attackMaster()
{
try {
// 注册节点
zc.create(masterPath, myinfo, CreateMode.EPHEMERAL);
// 如果当前注册成功了,那么他就是主master
activeMasterInfo = myinfo;
System.out.println("the active master is : " + activeMasterInfo);
}
catch (ZkNodeExistsException e)
{
// 当节点已经被其他master注册了
activeMasterInfo = zc.readData(masterPath);
// 当无法读取到节点信息则认为其他master可能宕机了,再去抢注
if (null == activeMasterInfo)
{
attackMaster();
}
else{
System.out.println(activeMasterInfo + " has become active! " + myinfo + " wait for next time to be active!");
}
}
catch (Exception e)
{
// 当发生其他错误的时候,不去例会
} }
}

  当我们建立多个线程去启动的时候,多个master就会去抢注/master节点:

the active master is : MasterInfo [id=C, name=masterC]
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=G, name=masterG] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=F, name=masterF] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=B, name=masterB] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=E, name=masterE] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=A, name=masterA] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=H, name=masterH] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=D, name=masterD] wait for next time to be active!

  这个时候我们模拟网络问题,手动地去删除/master节点多次的时候,各个master感知到节点删除会再次抢注:

the active master is : MasterInfo [id=C, name=masterC]
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=G, name=masterG] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=F, name=masterF] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=B, name=masterB] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=E, name=masterE] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=A, name=masterA] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=H, name=masterH] wait for next time to be active!
MasterInfo [id=C, name=masterC] has become active! MasterInfo [id=D, name=masterD] wait for next time to be active!
the active master is : MasterInfo [id=B, name=masterB]
MasterInfo [id=B, name=masterB] has become active! MasterInfo [id=F, name=masterF] wait for next time to be active!
MasterInfo [id=B, name=masterB] has become active! MasterInfo [id=H, name=masterH] wait for next time to be active!
MasterInfo [id=B, name=masterB] has become active! MasterInfo [id=G, name=masterG] wait for next time to be active!
MasterInfo [id=B, name=masterB] has become active! MasterInfo [id=E, name=masterE] wait for next time to be active!
MasterInfo [id=B, name=masterB] has become active! MasterInfo [id=C, name=masterC] wait for next time to be active!
MasterInfo [id=B, name=masterB] has become active! MasterInfo [id=A, name=masterA] wait for next time to be active!
MasterInfo [id=B, name=masterB] has become active! MasterInfo [id=D, name=masterD] wait for next time to be active!
the active master is : MasterInfo [id=E, name=masterE]
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=C, name=masterC] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=H, name=masterH] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=F, name=masterF] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=A, name=masterA] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=D, name=masterD] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=B, name=masterB] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=G, name=masterG] wait for next time to be active!

  我们可以看到每一次抢注成功的master都不一样,这样如果是由于网络问题而不是当前主master真的宕机了,那么会造成不必要的主备切换。所以说我们还可以进行如下的程序优化:  

  如上图,当由于网络原因原来的主master其实并没有宕机,那么为了减小由于主备切换带来的集群抖动,可以让其他备master延迟一定时间去争抢,而当前的主master则马上去争抢。所以说即使

成为了主master也要观察这个临时路径。

  所以在程序中我们可以在抢注的时候判断如果当前master并不是之前的主master,则延迟一定时间去抢注,使得当前主master能够再次成功的抢的节点,具体优化代码如下:

            // 当节点被删除的时候触发此方法
public void handleDataDeleted(String dataPath) throws Exception {
if (null != activeMasterInfo && activeMasterInfo.equals(myinfo))
{
// 如果当前master就是主master的时候,直接去抢注
attackMaster();
}
else
{
// 如果不是则延迟5秒去抢注,给原先的主master一个机会
delayExector.schedule(new Runnable() { public void run() {
attackMaster(); }
}, , TimeUnit.SECONDS);
} }

  手动的去删除/master节点,结果:masterE始终很稳定的抢注到了/master节点。

the active master is : MasterInfo [id=E, name=masterE]
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=H, name=masterH] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=C, name=masterC] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=A, name=masterA] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=B, name=masterB] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=D, name=masterD] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=F, name=masterF] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=G, name=masterG] wait for next time to be active!
the active master is : MasterInfo [id=E, name=masterE]
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=B, name=masterB] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=G, name=masterG] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=F, name=masterF] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=D, name=masterD] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=H, name=masterH] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=C, name=masterC] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=A, name=masterA] wait for next time to be active!
the active master is : MasterInfo [id=E, name=masterE]
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=F, name=masterF] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=H, name=masterH] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=C, name=masterC] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=A, name=masterA] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=D, name=masterD] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=B, name=masterB] wait for next time to be active!
MasterInfo [id=E, name=masterE] has become active! MasterInfo [id=G, name=masterG] wait for next time to be active!

小结:

  除了以上抢注某个临时节点的方式去进行主备切换实现外,我们也可以让每一个master在某个永久节点下各自注册自己的临时节点(CreateMode.EPHEMERAL_SEQUENTIAL)

方式,当观察到这个永久节点下znode有变动的时候,查看自己是不是后缀最小的一个,是,则将变成主master。

  除了主备切换场景外,集群管理中的节点发现,任务分发,也同样可以有zookeeper来处理,这种灵活的使用方式可以解决很多分布式场景的问题。

3.其他

// 略

[hadoop][基本原理]zookeeper场景使用的更多相关文章

  1. [hadoop][基本原理]zookeeper简单使用

    代码:https://github.com/xufeng79x/ZkClientTest 1.简介 zookeeper的基本原理和使用场景描述可参考:[hadoop][基本原理]zookeeper基本 ...

  2. [hadoop][基本原理]zookeeper基本原理

    1.简介 https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/ 2. 数据模型 Zookeeper 会维护一个具有层次关系 ...

  3. Hadoop生态圈-Zookeeper的工作原理分析

    Hadoop生态圈-Zookeeper的工作原理分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   无论是是Kafka集群,还是producer和consumer都依赖于Zoo ...

  4. 一步一步学习大数据:Hadoop 生态系统与场景

    Hadoop概要 到底是业务推动了技术的发展,还是技术推动了业务的发展,这个话题放在什么时候都会惹来一些争议. 随着互联网以及物联网的蓬勃发展,我们进入了大数据时代.IDC预测,到2020年,全球会有 ...

  5. Hadoop+Hbase+Zookeeper分布式存储构建

    目录: 软件准备 Hadoop安装配置 zookeeper安装配置 Hbase安装配置 Hadoop+Hbase+zookeeper分布式存储构建 前言* Hadoop是Apache开源组织的一个分布 ...

  6. [推荐]Hadoop+HBase+Zookeeper集群的配置

    [推荐]Hadoop+HBase+Zookeeper集群的配置 Hadoop+HBase+Zookeeper集群的配置  http://wenku.baidu.com/view/991258e881c ...

  7. Hadoop,HBase,Zookeeper源码编译并导入eclipse

    基本理念:尽可能的参考官方英文文档 Hadoop:  http://wiki.apache.org/hadoop/FrontPage HBase:  http://hbase.apache.org/b ...

  8. Hadoop加zookeeper构建高可靠集群

    事前准备 1.更改Linux主机名,每个人都有配置 vim /etc/sysconfig/network NETWORKING=yes HOSTNAME=hadoop-server1 2.改动IP / ...

  9. 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解

    引言 在之前的大数据学习系列中,搭建了Hadoop+Spark+HBase+Hive 环境以及一些测试.其实要说的话,我开始学习大数据的时候,搭建的就是集群,并不是单机模式和伪分布式.至于为什么先写单 ...

随机推荐

  1. Android SDK Manager下载,解决方案

    一.Windows 平台 在C:\Windows\System32\drivers\etc\hosts文件.添加一行:74.125.237.1       dl-ssl.google.com 二.Li ...

  2. kaptcha验证码在windows下正常,在linux下无法显示

    有几种情况,记录备忘: 1.两个环境字体不一样,linux环境下可能没有字体,重新安装字体即可. 2.tomcat等容器下没有temp目录,手动建立即可. 3.如果报找不到类的错误,检查JDK是否正确 ...

  3. BZOJ4514:[SDOI2016]数字配对——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4514 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj ...

  4. BZOJ2657:[ZJOI2012]旅游——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2657 https://www.luogu.org/problemnew/show/P2610 到了难 ...

  5. BZOJ1036:[ZJOI2008]树的统计——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来 ...

  6. HDOJ.1263 水果(map)

    水果 点我跳转到题面 点我一起学习STL-MAP 题意分析 给出多组测试数据,每组数据有多条信息.分别是水果种类,地点,和水果数目.每组信息要按照样例输出,并且输出要按照地点->水果种类的字典序 ...

  7. ios的hitTest方法以及不规则区域内触摸事件处理方法

    概述 在正常的使用场景中,我们处理了比较多的矩形区域内触摸事件,比如UIButton.UIControl.一般来说,这些控件的图形以及触摸区域都是矩形或者圆角矩形的.但是在一些特殊应用场景中我们有时不 ...

  8. JAVA对象的深度克隆

    有时候,我们需要把对象A的所有值复制给对象B(B = A),但是这样用等号给赋值你会发现,当B中的某个对象值改变时,同时也会修改到A中相应对象的值! 也许你会说,用clone()不就行了?!你的想法只 ...

  9. @Autowired @Resource @Qualifier的区别

    参考博文: http://www.cnblogs.com/happyyang/articles/3553687.html http://blog.csdn.net/revent/article/det ...

  10. Sublime Text 3 一些简单使用

    1.注释 选中需要注释的代码,“Ctrl+/”单行注释,“Ctrl+Shift+/”多行注释.同样操作,可以取消注释. 2.查找 “Ctrl+F”,在底部会出现快速搜索框,在搜索框中输入需要搜索的变量 ...