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 ...
随机推荐
- C# 打开文件夹和保存文件夹
OpenFileDialog sfd = new OpenFileDialog(); sfd.ShowDialog(); this.textBox1.Text = sfd.FileName; Save ...
- Spring-cloud(四)服务发现与消费:ribbon的使用
说明: ribbon是spring-cloud中作为服务消费者的一种角色,客户端可以通过它来对服务提供者的服务进行消费, 比如本例中是服务提供者注册到注册中心,服务提供者提供了一个服务接口,返回一个h ...
- C#之Winform跨线程访问控件
C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...
- [LeetCode] Reverse Words in a String III 翻转字符串中的单词之三
Given a string, you need to reverse the order of characters in each word within a sentence while sti ...
- 在脚本中使用source命令不生效
问题描述 1. 一次写自动化安装脚本,要安装java,需要将JAVA_HOME写到/etc/profile中,然后使用source命令,但是发现profile文件中确实有JAVA_HOME,使用 ...
- Java多线程之生产者消费者
生产者和消费者的实例: 商品类:/** * 商品类 * */public class Goods { final int MAX_NUMBER = 30; // 最大数量 final in ...
- python学习记录 - python3.x中如何实现print不换行
python3.x中如何实现print不换行 大家应该知道python中print之后是默认换行的, 那如何我们不想换行,且不想讲输出内容用一个print函数输出时,就需要改变print默认换行的 ...
- hdu 4812 DTree (点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total S ...
- 【Codeforces 851D Arpa and a list of numbers】
Arpa的数列要根据GCD变成好数列. ·英文题,述大意: 给出一个长度为n(n<=5000000)的序列,其中的元素a[i]<=106,然后输入两个数x,y(x,y<=1 ...
- 【The Time Traveller's Wife】
After reading The Time Traveller's Wife: It's a tragedy,I think.But it's mixed with hope.Henry ...