Zookeeper--集群管理
Zookeeper--集群管理
在多台服务器组成的集群中,需要监控每台服务器的状态,一旦某台服务器挂掉了或有新的机器加入集群,集群都要感知到,从而采取相应的措施。一个主动的集群可以自动感知节点的死亡和新节点的加入,它才对更高效的提供服务。通常的做法是有台主机器定时的去获取其他机器的心跳,或其他机器定时主动汇报自己的状态,这种方式存在一定的延时,并且主机器成为单点,一旦挂掉便影响整个集群。
使用Zookeeper可以方便的实现集群管理的功能。思路如下,每个服务器启动时都向zk服务器提出创建临时节点的请求,并且使用getChildren设置父节点的观察,当该服务器挂掉之后,它创建的临时节点也被Zookeeper服务器删除,然后会触发监视器,其他服务器便得到通知。创建新节点也是同理。
并且利用Zookeeper的Leader选举功能可以选出服务中的一台作为Leader,在比如任务调度类似的场景中有用。
下面是一个简单的模拟:
ServerUnit模拟在不同机器上启动的服务,启动时向Zookeeper服务器注册自己,并保存自己的IP和端口;实现CallBack接口:在其他节点发生变化时执行的逻辑
public class ServerUnit { public static final String SER_NAME = "ServerUnit"; public static void main(String[] args) throws InterruptedException, IOException, KeeperException { System.out.println("begin register to Zookeeper.."); String address = IPUtil.getLoaclIP() + ":" + new Random().nextInt(255); ServiceMng mng = new ServiceMng(SER_NAME); String serverId = mng.register(address, new CallBack<ServiceMng.ChildrenChangedResult>() {
@Override
public void callback(ServiceMng.ChildrenChangedResult cn) throws KeeperException, InterruptedException {
for (String str : cn.getUp()) {
System.out.println("检测到服务加入: " + mng.queryAddress(str));
}
for (String str : cn.getDown()) {
System.out.println("检测到服务退出: " + mng.queryAddress(str));
}
}
}); System.out.println("ServerUnit started at: " + address);
TimeUnit.HOURS.sleep(1);
}
}
---
CallBack接口:
public interface CallBack<T> { void callback(T t) throws Exception; }
---
ServerMng 提供向Zookeeper注册服务和获取服务等方法,被服务单元依赖
public class ServiceMng { private static final String APPS_PATH = "/__apps__";
private String serviceName;
private ZooKeeper zk;
private CountDownLatch latch = new CountDownLatch(1);
private List<String> serList;
private Map<String, String> serMap = new HashMap<>(); ServiceMng(String serviceName) {
this.serviceName = serviceName;
} public String register(String address, CallBack callback) throws KeeperException, InterruptedException, IOException {
if (zk != null) {
throw new IllegalArgumentException("method should not invoke twice.");
} zk = new ZooKeeper("localhost", 30000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
latch.countDown();
}
if (watchedEvent.getType() == Watcher.Event.EventType.NodeChildrenChanged) {
try {
List list = zk.getChildren(APPS_PATH + "/" + serviceName, true);
refresh(list);
callback.callback(new ChildrenChangedResult(list, serList));
serList = list;
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}); latch.await();
if (zk.exists(APPS_PATH, false) == null) {
zk.create(APPS_PATH, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
if (zk.exists(APPS_PATH + "/" + serviceName, false) == null) {
zk.create(APPS_PATH + "/" + serviceName, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} String path = zk.create(APPS_PATH + "/" + serviceName + "/", address.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
List list = zk.getChildren(APPS_PATH + "/" + serviceName, true);
refresh(list);
serList = list;
return path;
} private void refresh(List<String> paths) throws KeeperException, InterruptedException {
for (String path : paths) {
byte[] b = zk.getData(APPS_PATH + "/" + serviceName + "/" + path, false, null);
serMap.put(path, new String(b));
}
} public String queryLeaderIp(String serviceName) throws KeeperException, InterruptedException {
List<String> apps = zk.getChildren(APPS_PATH + "/" + serviceName, false);
if (apps.isEmpty()) {
return null;
}
Collections.sort(apps);
byte[] data = zk.getData(apps.get(0), false, null);
return new String(data);
} public String queryRandomServerIp(String serviceName) throws KeeperException, InterruptedException {
List<String> apps = zk.getChildren(APPS_PATH + "/" + serviceName, false);
if (apps.isEmpty()) {
return null;
}
Random r = new Random();
byte[] data = zk.getData(apps.get(r.nextInt(apps.size())), false, null);
return new String(data);
} public String queryAddress(String path) {
return serMap.get(path);
} public static class ChildrenChangedResult {
List<String> up = null;
List<String> down = null; ChildrenChangedResult(List now, List last) {
up = new LinkedList(now);
up.removeAll(last);
down = new LinkedList(last);
down.removeAll(now);
} public List<String> getUp() {
return up;
} public List<String> getDown() {
return down;
}
} }
---
依次启动3个ServerUnit,查看控制台:
依次关闭2个ServerUnit,查看控制台:
从关闭ServerUnit到控制台打印退出大概延迟8s左右,配置zk的tickTime=1000,比预期的要慢一些。
end
Zookeeper--集群管理的更多相关文章
- 【拆分版】Docker-compose构建Zookeeper集群管理Kafka集群
写在前边 在搭建Logstash多节点之前,想到就算先搭好Logstash启动会因为日志无法连接到Kafka Brokers而无限重试,所以这里先构建下Zookeeper集群管理的Kafka集群. 众 ...
- solr集群搭建,zookeeper集群管理
1. 第一步 把solrhome中的配置文件上传到zookeeper集群.使用zookeeper的客户端上传. 客户端命令位置:/root/solr-4.10.3/example/scripts/cl ...
- 大数据学习路线:Zookeeper集群管理与选举
大数据技术的学习,逐渐成为很多程序员的必修课,因为趋势也是因为自己的职业生涯.在各个技术社区分享交流成为很多人学习的方式,今天很荣幸给我们分享一些大数据基础知识,大家可以一起学习! 1.集群机器监控 ...
- zookeeper集群管理配置优化总结
1:默认jvm没有配置Xmx.Xms等信息,可以在conf目录下创建java.env文件 export JVMFLAGS="-Xms512m -Xmx512m $JVMFLAGS" ...
- zookeeper安装和应用场合(名字,配置,锁,队列,集群管理)
安装和配置详解 本文介绍的 Zookeeper 是以 3.2.2 这个稳定版本为基础,最新的版本可以通过官网http://hadoop.apache.org/zookeeper/ 来获取,Zookee ...
- 2 weekend110的zookeeper的原理、特性、数据模型、节点、角色、顺序号、读写机制、保证、API接口、ACL、选举、 + 应用场景:统一命名服务、配置管理、集群管理、共享锁、队列管理
在hadoop生态圈里,很多地方都需zookeeper. 启动的时候,都是普通的server,但在启动过程中,通过一个特定的选举机制,选出一个leader. 只运行在一台服务器上,适合测试环境:Zoo ...
- 一步到位分布式开发Zookeeper实现集群管理
说到分布式开发Zookeeper是必须了解和掌握的,分布式消息服务kafka .hbase 到hadoop等分布式大数据处理都会用到Zookeeper,所以在此将Zookeeper作为基础来讲解. Z ...
- zookeeper配置管理+集群管理实战
引言 之前就了解过kafka,看的似懂非懂,最近项目组中引入了kafka,刚好接着这个机会再次学习下. Kafka在很多公司被用作分布式高性能消息队列,kafka之前我只用过redis的list来做简 ...
- 基于zookeeper+mesos+marathon的docker集群管理平台
参考文档: mesos:http://mesos.apache.org/ mesosphere社区版:https://github.com/mesosphere/open-docs mesospher ...
- 搞懂分布式技术5:Zookeeper的配置与集群管理实战
搞懂分布式技术5:Zookeeper的配置与集群管理实战 4.1 配置文件 ZooKeeper安装好之后,在安装目录的conf文件夹下可以找到一个名为“zoo_sample.cfg”的文件,是ZooK ...
随机推荐
- jquery基础 笔记一
一. 1. vsdoc: 在Visual Studio中需要引入此版本的jquery类库才能启用智能感知.如:jquery-1.3.2-vsdoc2.js<body> <div id ...
- java程序设计基础篇 复习笔记 第七单元&&第八单元
7.1 int[][] triArray{ {1}, {1,2}, {1,2,3}, }; 7.2 array[2].length 8.1 Unified Modeling Language:UML ...
- SSM整合RocketMQ
前言 RocketMQ是一个由阿里巴巴开源的消息中间件,脱胎于阿里内部使用的MetaQ,本文主要是写个小例子演示一下消息从生产到消费的过程. RocketMQ下载和安装 下载地址 http://roc ...
- tsl/ssl 证书制作记录
生成自签名证书 生成服务端秘钥 $ openssl genrsa -out server.key 1024 生成证书请求文件 编写配置文件openssl.cnf $ vi openssl.cnf [r ...
- About libcurl and cURL in PHP
今天在学习php时遇到要调用curl 库函数对特定url字符串进行访问操作,需要自己写一个方法进行调用,之前在linux系统中也有用到cURL 命令行工具执行对相关资源的获取,在wiki上找到了如下的 ...
- 初识jQuery(2)
1.DOM模型 1.1以对象描述文档的方式就是DOM 节点对象就是被称为DOM对象(标签对象) 1.2节点 元素节点(标签) 文本节点(标签内容) 属性节点(标签属性) 2.Jquery语法结构 $( ...
- Lua的清屏快捷方式
1. Lua (Command Line) 这里清屏的方式是: os.execute("cls") 就是执行了DOS中的清屏命令! 2.SciTE中的清屏方式: -----(1)第 ...
- 细说并发4:Java 阻塞队列源码分析(上)
上篇文章 趣谈并发3:线程池的使用与执行流程 中我们了解到,线程池中需要使用阻塞队列来保存待执行的任务.这篇文章我们来详细了解下 Java 中的阻塞队列究竟是什么. 读完你将了解: 什么是阻塞队列 七 ...
- ss-libev 源码解析udp篇 (2)
UDP relay的代码基本都在udprelay.c中,无论ss-local还是ss-server的代码都在一起,使用宏MODULE_LOCAL,MODULE_REMOTE等区分开.代码虽然不是很多, ...
- 【剑指offer】顺时针打印矩阵,C++实现
原创文章,转载请注明出处! 博客文章索引地址 1.题目 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵,则依次打印出数字1,2,3,4,8,12,16,15,14 ...