java实现zookeeper的领袖选举
来源:互联网 发布:图像分析软件 编辑:程序博客网 时间:2024/05/30 05:40
Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。而且也是诸如hbase,hadoop,dubbo等诸多分布式项目的基础技术,本篇主要介绍zookeeper中最常用的一个场景,领袖选举。
领袖选举,由于分布式环境往往是由多台server组成的集群,而集群环境下就需要一个"主管"来管理集群上的每台机器的服务状态,但是如果一个"主管"有一天宕机了,但是为了已有的机器能正常运行,如何能让集群自动选取一台机器成为新的"总管"呢?答案就是本篇要讲的领袖选举。
本篇假设读者已经基本了解zookeeper的基本安装及配置和使用方法,如果还不了解可以看这篇文章:http://www.cnblogs.com/wuxl360/p/5817405.html
领袖选举的基本原理是创建一个永久节点/leader,然后每台机器在启动的时候,创建一个/leader 下的临时顺序节点,如/leader/chiren-000000001,/leader/chiren-000000002... 由于临时节点会随着zookeeper客户端的过期而失效,所以每个机器启动的时候,打开一个zookeeper客户端并创建一个临时节点,当服务器宕机的时候,客户端会随着服务器宕机而失效,而临时节点也会因此失效,所以只要通过getChildren方法监听/leader节点,然后/leader下临时节点有变化,由于顺序节点是每次创建自动递增的,所以只要取临时节点中的最小值作为"领袖"即可。
以下是代码实现。
public class LeaderElectionTest{ public static void main(String[] args) throws IOException, KeeperException, InterruptedException { MyWatch myWatch = new MyWatch(); ZooKeeper zk = new ZooKeeper("localhost:" + 2181, 1000,myWatch); myWatch.setZooKeeper(zk); //先创建一个节点存储创建过的机器节点 try { zk.create("/leader", ("主机").getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); }catch (KeeperException.NodeExistsException e){ System.out.println("主机节点已创建"); } //模拟新加入一台机器 Random r = new Random(); String num = r.nextInt(100000)+""; String sequentialPath = zk.create("/leader/children",("运行server的ip:"+num).getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); System.out.println("同步创建临时顺序节点成功:" + sequentialPath); //注册监听事件 zk.getChildren("/leader",true); //此处模拟机器持续运行着 while(true){ } }}
首先程序会创建一个zookeeper客户端,然后尝试去创建一个/leader永久节点,如果别的服务器已经创建,就不必创建。然后用了一个随机数模拟本台机器的ip,并在/leader/children下创建一个临时顺序节点,然后zk客户端调用getChildren方法,注册监听事件(对zookeeper监听机制不是很了解的可以看这篇文章:https://www.cnblogs.com/programlearning/archive/2017/05/10/6834963.html)。然后用一个while循环防止程序终止。
public class MyWatch implements Watcher{ private ZooKeeper zk; private List<String> oldSlaveList; public void setZooKeeper(ZooKeeper zk){ this.zk = zk; } public void process(WatchedEvent event) { if (Watcher.Event.EventType.None == event.getType() && null == event.getPath()) { System.out.println("Zookeeper session established"); try { List<String> stringList = zk.getChildren("/leader",true); oldSlaveList = stringList; if(stringList.size()==0){ System.out.println("您现在是唯一一台机器,您就是领袖"); } else{ System.out.println("您的机器被创建,当前领袖为:"+findMaster(stringList)); } } catch (Exception e) { e.printStackTrace(); } } if (Event.EventType.NodeChildrenChanged == event.getType()) { try { List<String> stringList = zk.getChildren("/leader",true); //如果当前机器列表大于旧的机器列表说明增加了 if(stringList.size()>oldSlaveList.size()){ System.out.println("一台机器被创建,当前领袖为:"+findMaster(stringList)); oldSlaveList = stringList; } else{ System.out.println("一台机器被删除,当前领袖为:"+findMaster(stringList)); oldSlaveList = stringList; } } catch (Exception e) { e.printStackTrace(); } } } private String findMaster(List<String> stringList){ Integer min = Integer.MAX_VALUE; Integer index = 0; for(int i=0;i<stringList.size();i++){ Integer num = Integer.parseInt(stringList.get(i).substring(8)); if(num<=min){ min = num; index = i; } } return stringList.get(index); }}
然后MyWatcher中实现了Watcher接口,实现的process方法中,主要监听了自己zookeeper客户端创建的事件,和子节点改变的事件(main方法中已经注册了/leader节点的监听事件,不注册无法接收到消息),当自己zookeeper客户端创建的时候如果子节点列表为空说明当前只有一台机器,自己就是领袖。在子节点改变事件中,判断了节点是增加还是减少,并调用findMaster方法,找到当前节点中的最小值,也就是领袖。然后作为"领袖"的机器就可以由此管理其他机器的状态了。
运行结果:
(完)
参考文章:http://www.cnblogs.com/wuxl360/p/5817405.html
https://www.cnblogs.com/programlearning/archive/2017/05/10/6834963.html
https://www.cnblogs.com/programlearning/archive/2017/05/10/6834963.html
阅读全文
0 0
- java实现zookeeper的领袖选举
- 用zookeeper实现简单的master选举
- curator实现zookeeper的领导选举
- Zookeeper 实现 master 选举
- Zookeeper 实现 master 选举
- zookeeper实现主从选举
- Zookeeper的选举
- Zookeeper的Leader选举
- Zookeeper的Leader选举
- Zookeeper的Leader选举
- Zookeeper的leader选举
- Zookeeper的Leader选举
- zookeeper leader选举源码实现
- Zookeeper实现master-slave选举
- Zookeeper实现master-slave选举
- 自己动手实现zookeeper的FastLeaderELection选举算法和心跳同步
- 利用ZooKeeper服务实现分布式系统的Leader选举
- Zookeeper 的Leader选举机制
- 代理模式
- target 安装 服务端和客户端 centos7 debian
- 宏常量与宏替换
- CAD文件直接导入BIGEMAP进行套合配准(推荐)
- Redis学习-4:Redis特性
- java实现zookeeper的领袖选举
- Mybatis中的resultType和resultMap
- 为python的IDLE增加清屏功能
- JavaSE杂记
- Struts2和struts1的比较
- 软件工程课程实验报告:课程总结
- 浅谈js函数继承模式之二:借用模式
- Redis学习-5:Redis的持久化(结束)
- 图片上传 啊