Zookeeper动态更新服务器列表
--------------------------------------------------------------------------------------
[版权申明:本文系作者原创,转载请注明出处]
文章出处:http://www.cnblogs.com/sdksdk0/p/5585192.html
作者: 朱培 ID:sdksdk0
-----------------------------------------------------------------------------------
今天分享的是大数据实践的zookeeper。
zookeeper内部就是一个集群,主节点是选举出来的,外部看起来就像只有一台一样,保存的是一份状态数据。 做分布式应用协调的时候,可以降低开发难度。
具有高可用性,松耦合交互方式。
关于zookeeper的配置可以查看我的文章:http://blog.csdn.net/sdksdk0/article/details/51517460,在这里不再重复讲解安装配置。
一、zookeeper的API接口
String create(String path, byte[] data, List<ACL> acl, CreateMode createMode)
Stat exists(String path, boolean watch)
void delete(String path, int version)
List<String> getChildren(String path, boolean watch)
List<String> getChildren(String path, boolean watch)
Stat setData(String path, byte[] data, int version)
byte[] getData(String path, boolean watch, Stat stat)
void addAuthInfo(String scheme, byte[] auth)
Stat setACL(String path, List<ACL> acl, int version)
List<ACL> getACL(String path, Stat stat)
zookeeper一般来说保管的数据不超过1M.主要是保存一些配置信息,主要特点是监听数据实时更新。
二、主要应用
1、集群管理:规定编号最小的为master,所以当我们对SERVERS节点做监控的时候,得到服务器列表,只要所有集群机器逻辑认为最小编号节点为master,那么master就被选出,而这个master宕机的时候,相应的znode会消失,然后新的服务器列表就被推送到客户端,然后每个节点逻辑认为最小编号节点为master,这样就做到动态master选举。
2、配置的管理:在分布式应用环境中很常见,例如同一个应用系统需要多台 PC Server 运行,但是它们运行的应用系统的某些配置项是相同的,如果要修改这些相同的配置项,那么就必须同时修改每台运行这个应用系统的 PC Server,这样非常麻烦而且容易出错。 将配置信息保存在 Zookeeper 的某个目录节点中,然后将所有需要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中。
3、共享锁:在同一个进程中很容易实现,但是在跨进程或者在不同 Server 之间就不好实现了。Zookeeper 却很容易实现这个功能,实现方式也是需要获得锁的 Server 创建一个 EPHEMERAL_SEQUENTIAL 目录节点,然后调用 getChildren方法获取当前的目录节点列表中最小的目录节点是不是就是自己创建的目录节点,如果正是自己创建的,那么它就获得了这个锁,如果不是那么它就调用 exists(String path, boolean watch) 方法并监控 Zookeeper 上目录节点列表的变化,一直到自己创建的节点是列表中最小编号的目录节点,从而获得锁,释放锁很简单,只要删除前面它自己所创建的目录节点就行了。
4、队列管理:Zookeeper 可以处理两种类型的队列:当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达,这种是同步队列;队列按照 FIFO 方式进行入队和出队操作,例如实现生产者和消费者模型
三、使用eclipse连接zookeeper
在eclipse中,我们可以导入需要的包,然后对节点进行增删改查操作。 当连接的时候可以这样,这里我是采用了3台zookeeper来进行操作的。ubuntu1,2,3都分别是主机名
ZooKeeper zk = null; @Before
public void init() throws Exception{ zk = new ZooKeeper("ubuntu2:2181,ubuntu1:2181,ubuntu3:2181", 5000, new Watcher() { //监听事件发生时的回调方法
@Override
public void process(WatchedEvent event) {
System.out.println(event.getPath());
System.out.println(event.getType());
}
}); }
创建节点: 这里我是采用创建一个永久节点,在zookeeper节点中有临时节点和永久节点之分。在跟目录下创建一个eclipse节点,内容的编码格式是utf-8,Ids是指权限控制,我这里采用的是开放ACL权限控制。最后需要把流关闭。
@Test
public void testZkNode() throws Exception { String path = zk.create("/eclipse", "指令汇科技".getBytes("utf-8"), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("创建了一个永久节点: " + path);
zk.close(); }
然后是注册监听器,毕竟zookeeper有一个很重要的功能就是是用来监听整个服务的状态。
@Test
public void testGet() throws Exception { //监听器的注册只能生效一次
byte[] data = zk.getData("/eclipse", true, new Stat());
System.out.println(new String(data,"utf-8"));
Thread.sleep(Long.MAX_VALUE); }
在main方法中调用执行。
@Test
public void testSet() throws UnsupportedEncodingException, KeeperException, InterruptedException{ zk.setData("/eclipse", "谁是英雄".getBytes("utf-8"), -1);
zk.close(); }
四、动态服务器
因为我主要分享的是如何在客户端上动态的监听服务器的上线和离线,所以我们先来写一个服务器的进程。
首先我们需要把后面需要的节点信息定义一下,先去zookeeper的客户端上面运行一下,创建一个grpnode节点,以便我们的后续操作。
private ZooKeeper zk;
private String groupNode = "grpnode";
private String subNode = "sub"; // 向zookeeper注册信息
public void connectZK(String name) throws KeeperException, InterruptedException, IOException {
zk = new ZooKeeper("ubuntu2:2181,ubuntu1:2181,ubuntu3:2181", 5000, new Watcher() { //监听事件发生时的回调方法
@Override
public void process(WatchedEvent event) { }
});
String path = zk.create("/" + groupNode + "/" + subNode, name.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("服务器上线,创建了一个子节点: " + path); }
接下来就是zookeeper默认的业务逻辑的处理,最后在主方法中调用。当然也可以把这个打成一个jar包放到hadoop上面去运行。
// 业务处理逻辑
public void handle() throws Exception { Thread.sleep(Long.MAX_VALUE); } public static void main(String[] args) throws Exception { if(args.length==0){
System.err.println("参数个数不对,请附加服务器名作为参数来启动.....");
System.exit(1);
}
// 去向zookeeper注册本服务器信息
AppServer server = new AppServer();
server.connectZK(args[0]);
server.handle(); }
五、动态客户端
服务器写好之后,我们就需要一个客户端来监听这个服务器的上下线操作了。同样使用一个zookeeper的监听回调方法。一旦服务器发生变化,这里就可以动态监听到。主要是监听父子节点的变化情况。
private volatile List<String> servers;
private ZooKeeper zk;
//使用zk的监听器功能触发服务器更新的动作
public void connectZK() throws IOException, KeeperException, InterruptedException{ zk = new ZooKeeper("ubuntu2:2181,ubuntu1:2181,ubuntu3:2181", 5000, new Watcher() { //监听事件发生时的回调方法
@Override
public void process(WatchedEvent event) { if("/grpnode".equals(event.getPath()) && event.getType()==EventType.NodeChildrenChanged ){
//触发更新服务器列表的动作
try {
updateServerList();
} catch (Exception e) {
e.printStackTrace();
} }
}
});
updateServerList();
}
动态获取服务器列表,这里主要就是监听父子节点的变化。
//动态获取服务器列表
public void updateServerList() throws KeeperException, InterruptedException, UnsupportedEncodingException{
ArrayList<String> serverList=new ArrayList<String>(); //监听子节点,并且对父节点注册监听器
List<String> childer=zk.getChildren("/grpnode", true); //遍历子节点
for(String child:childer){
byte[] data=zk.getData("/grpnode/"+child,false, new Stat());
String server=new String(data,"utf-8");
//将获取到的服务器名称存入list
serverList.add(server);
}
//把暂存的list放到全局的list中
servers=serverList;
System.out.println("最新的在线服务器是:"+serverList);
}
最后就是我们最熟悉的main方法了
//客户端的业务功能
public void handle() throws InterruptedException{ Thread.sleep(Long.MAX_VALUE);
} public static void main(String[] args) throws IOException, InterruptedException, KeeperException{ AppClient client=new AppClient();
client.connectZK();
client.handle(); }
在hadoop中运行结果如下:
总结:Zookeeper 作为 Hadoop 项目中的一个子项目,是 Hadoop 集群管理的一个必不可少的模块,它主要用来控制集群中的数据,如它管理 Hadoop 集群中的 NameNode,还有 Hbase 中 Master Election、Server 之间状态同步等。 Zoopkeeper 提供了一套很好的分布式集群管理的机制,就是它这种基于层次型的目录树的数据结构,并对树中的节点进行有效管理,从而可以设计出多种多样的分布式的数据管理模型。
Zookeeper动态更新服务器列表的更多相关文章
- EAV/ESS 8.x 自定义服务器正确方法+更新服务器列表
下面用64位的ESET Smart Security 8.0.319.1进行设置自定义更新服务器说明(注:修改方法32位和64位通用) 1. 让我们先看一下ESET Smart Security 8 ...
- 从CMDB动态获取服务器列表,按照Ansible的约定
目标效果: [root@ansible ~]# python query.py --list{ "test": [ "10.1.2.1", "10.1 ...
- zookeeper实现动态感知服务器上下线
在实际的生产环境中我们一般都是集群环境部署的,同一个程序我们会部署在相同的几台服务器中,这时我们可以通过负载均衡服务器去调度,但是我们并不能很快速的获知哪台服务器挂掉了,这时我们就可以使用zook ...
- [原创]一种简单的cocos2d-x动态更新方案
介绍一个曾经在cocos2d-x项目中使用过的动态更新方案,这个方案简单易行,针对小的项目非常有用. 这个方案有两个核心的关键词:JSON,MD5. 原理可以简单地概括为:服务端持有所有动态更新资源文 ...
- 转 基于Quick-cocos2dx 2.2.3 的动态更新实现完整篇。(打包,服务器接口,模块自更新
1,如何设计更新服务器接口. 2,不改变原框架的代码的情况下如何实现更新,并且可以实现精确的进度. 3,如何按照版本打包. 4,如何跨n个小版本更新. 5,版本回滚. 6,如何更新你的自动更新模块和f ...
- centos DNS服务搭建 DNS原理 使用bind搭建DNS服务器 配置DNS转发 配置主从 安装dig工具 DHCP dhclient 各种域名解析记录 mydns DNS动态更新 第三十节课
centos DNS服务搭建 DNS原理 使用bind搭建DNS服务器 配置DNS转发 配置主从 安装dig工具 DHCP dhclient 各种域名解析记录 mydns DNS动态更 ...
- ZooKeeper动态增加Server(动态增加节点)的研究(待实践)
说明:是动态增加Server,不是动态增加连接到ZK Server的Client. 场景如下(转自外文): 1.在t=t_1->[peer-1(Leader),peer-2],peer-1是主节 ...
- zookeeper作为soa服务器集群的协调调度服务器
zookeeper作为soa服务器集群的协调调度服务器,当然自身也支持集群. ZooKeeper搭建系列集 ZooKeeper系列之一:ZooKeeper简介 ZooKeeper系列之二:ZooKee ...
- 仿百度壁纸客户端(五)——实现搜索动画GestureDetector手势识别,动态更新搜索关键字
仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键字 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Frag ...
随机推荐
- getgpc($k, $t='GP'),怎么返回的是 NULL?
<?php /** * 实用小代码 * 获得GET POST COOKIS */ $html=<<<WORD <form method="post"& ...
- 20 个 Laravel Eloquent 必备的实用技巧
Eloquent ORM 看起来是一个简单的机制,但是在底层,有很多半隐藏的函数和鲜为人知的方式来实现更多功能.在这篇文章中,我将演示几个小技巧. 1. 递增和递减 要代替以下实现: $article ...
- [LeetCode] Optimal Division 最优分隔
Given a list of positive integers, the adjacent integers will perform the float division. For exampl ...
- 使用springcloud zuul构建接口网关
一 微服务网关背景及简介 不同的微服务一般有不同的网络地址,而外部的客户端可能需要调用多个服务的接口才能完成一个业务需求.比如一个电影购票的收集APP,可能回调用电影分类微服务,用户微服务,支付微服 ...
- Python 字符串常见的27个操作
有字符串 mystr = "hello world itcast and itcastcpp",以下是常见的操作: 1. mystr.find(str, start=0, end= ...
- python基础面试
1 请用自己的算法, 按升序合并如下两个list, 并去除重复的元素: list1 = [2, 3, 8, 4, 9, 5, 6]list2 = [5, 6, 10, 17, 11, 2] 答案: ...
- [NOI 2014]起床困难综合症
Description 21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm 一直坚持与起床困难综合症作斗争.通过研究相关文献,他找 ...
- hdu 5340 (manacher)
Sample Input 2 abc abaadada Sample Output Yes No 判断是否能成为3个非空回文子串 manacher算法求出个点回文长度,在找出第一个和最后一个保存下 ...
- hdu 2254(矩阵)
题意:指定v1,v2,要求计算出在t1,t2天内从v1->v2的走法 思路:可以知道由矩阵求,即将其建图A,求矩阵A^t1 + ...... + A^t2. A^n后,/*A.xmap[v1 ...
- bzoj 1407: [Noi2002]Savage
Description 解题报告: 因为给定答案范围,暴力枚举时间,然后再两两枚举野人,判断是否有可能在某一年相遇,我们设这一年为\(x\),那么显然相交的条件是: \(x*(p[i]-p[j])+y ...