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 ...
随机推荐
- 由浅入深了解EventBus:(五)
事件分发 EventBus3.0的事件的分发时通过EventBus类中的post(粘性事件为postSticky)方法,post与postSticky的唯一区别就是,在postSticky内部首先会向 ...
- 让nodejs在iis上运行
node在IIS上运行的好处: Tomasz的回答是我见过最棒的: 使用iisnode模块在IIS中托管node.js应用程序来取代自托管node.exe进程的优势在于: · 进程管理. Iisnod ...
- ES6入门之对象扩展
ES5对象(超类)原有: 属性:construct构造函数 方法: object.hasOwnProperty( propertyName ) //检测是否有一个本地的属性而不是继承的,返回boole ...
- asp.net button浏览器端事件和服务器端事件
OnClientClick:触发浏览器端的响应,OnClick触发服务器端响应; 在服务器aspx.cs脚本中设置按钮属性: this.btnTest.Attributes["OnClick ...
- Java基础拾遗(二)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76358523冷血之心的博客) 马上就要秋招了,新的一轮笔试面试马上 ...
- iOS怎么来实现关闭自动锁屏
怎么来设置[UIApplication sharedApplication] idleTimerDisabled 属性来控制自动锁屏的效果 // 把设置idleTimerDisabled的代码放到 ...
- [QT]数据库SQLITE使用错误记录
1.仿照创建数据库的例程编写代码,出现以下问题: ① 创建QSqlQuery query; 注意:这里没有将 query 与 QSqlSatabase db, 关联,正确的应该是 : QSqlQu ...
- HDU2037 今年暑假不AC
解题思路:贪心问题,关键突破口是,先将节目的结束时间 从小到大排个序,然后依次判断后面一个节目的开始时间 是否大于或等于前一个符合条件的节目的结束时间.见代码: #include<cstdio& ...
- Ubuntu下使用openssl为apache2配置ssl
安装apache2 sudo apt-get install apache2 安装openssl 一般系统自带,可以通过openssl version查看,如果没有, sudo apt-get ins ...
- 流畅设计 Fluent Design System 中的光照效果 RevealBrush,WPF 也能模拟实现啦!
UWP 才能使用的流畅设计效果好惊艳,写新的 UWP 程序可以做出更漂亮的 UI 啦!然而古老的 WPF 项目也想解解馋怎么办? 于是我动手实现了一个! 迫不及待看效果 ▲ 是不是很像 UWP 中 ...