上次博客我们说了一下zookeeper的配置文件,以及命令的使用https://www.cnblogs.com/cxiaocai/p/11597465.html。我们这次来说一下我们的zookeeper的集群配置和java的API相关操作。

集群:

  一般情况下我们用zookeeper来做任务调度中心的,所以一定要做到高可用的,单机的不可能做到永不宕机,我们也不会信任他单机的永不宕机,这时我们就需要做集群处理,来实现我们的高可用。

配置集群时,我们尽可能采用奇数的服务器来配置,什么意思呢?尽力采用3,5,7,9台服务器来配置,原因是zookeeper会默认识别半数以上服务器正常运行,才认为zookeeper是正常运行的,比如我们现在部署4台zookeeper服务器,这时其中两台宕机了,这时zookeeper会认为这个集群时不可用的,同理我们如果是5台服务器的情况,有两台宕机了,可以正常运行,三台宕机了,才被认为是不可用的,这个很重要,包括后面的选举机制也是这样的。资金有限啊,我先用3台服务器搭建一下zookeeper集群。

1.集群配置

  下载解压什么的就不说了啊,上次都说过了,我们直接看下配置文件吧。和单机配置基本一致,我们看到dataDir=/tmp/zookeeper,也就是我们的数据存储路径,分别建立三个文件myid,内部输入1-255的数字

每台服务器别重复,切记一定建立在配置文件dataDir对应的目录下,不然启动会报找不到myid文件的错误,没有对应/tmp/zookeeper目录的,可以启动一下zookeeper再关闭就有文件夹了,或者自己手动创建也行。

再每一个配置文件内加入配置

server.1=172.16.140.106:2888:3888

server.2=172.16.140.105:2888:3888

server.3=172.16.214.74:2888:3888

server.myid(myid文件的数字)=ip(与myid相对应的IP):集群之间相互通讯的IP:选举时通讯的IP。三分配置文件都是一样的。

我们来分别启动一下。说到这里我们的集群配置也就成功了。

启动成功以后,我们分别输入./bin/zkServer.sh status 我们可以看到我们的服务器角色

2.角色:

leader 主节点,又名领导者。用于写入数据,通过选举产生,如果宕机将会选举新的主节点。

follower 子节点,又名追随者。用于实现数据的读取。同时他也是主节点的备选节点,并用拥有投票权。

observer 次级子节点,又名观察者。用于读取数据,与fllower区别在于没有投票权,不能选为主节点。并且在计算集群可用状态时不会将observer计算入内。也就是我们的半数原则计算。

observer配置:

只要在集群配置中加上observer后缀即可,示例如下:

server.3=127.0.0.1:2889:3889:observer

选举机制:

  先说一个简单的,投票机制的。假设我们现在有1,2,3,4,5五个follower要进行选举。

简单流程就是这样的,第一轮都认为自己很可以,自己要当选leader,但是选举流程失败了,还得继续,接下来会把自己的票全盘拖出给自己临近的id,1就会给2一票,2现在有了两票了,发现还是不够半数啊,半数是2.5啊,算了还得继续,2又把自己的两票都给了3,3这时获得了3票了,大于半数了,当选leader。

每轮选举结束后都会统一来处理,如果一轮投票就发现server1的zxid较大,那么直接server1会当选leader。

优先检查ZXID。ZXID比较大的服务器优先作为Leader。

如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。

留下一个思考题,5台服务器,如果启动可以指定 4号为leader服务 。

javaAPI相关操作

  maven的pom文件内加入

<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.5</version>
</dependency>

首先我们先初始化我们的Zookeeper的连接

connectString ->连接String连接串,包括ip+端口 ,集群模式下用逗号隔开192.168.0.149:2181,192.168.0.150:2181

sessionTimeout ->会话超时时间,类型int,该值不能超过服务端所设置的minSessionTimeout(默认2s)和maxSessionTimeout(默认60s),单位毫秒

watcher -> 会话监听器Watcher,服务端事件将会触该监听

sessionId -> 自定义会话ID long

sessionPasswd ->byte[] 会话密码

canBeReadOnly ->boolean该连接是否为只读的

hostProvider ->HostProvider 服务端地址提供者,指示客户端如何选择某个服务来调用,默认采用StaticHostProvider实现

@Before
public void init() throws IOException {
String conn = "47.111.109.3:2181"; // 连接字符串
int sessionTimeout = 4000; //连接超时时间
zooKeeper = new ZooKeeper(conn, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) { }
});
}

我们先来看看我们的新增节点,删除节点等操作吧。

查看节点:

我们使用getData方法,添加三个参数,分别是路径,是否监听,和返回值(状态stat)。

/**
* 获取数据
*
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void getData() throws KeeperException, InterruptedException {
byte[] data = zooKeeper.getData("/root", false, null);
System.out.println(new String(data));
}

添加监听:

/**
* 添加监听,结果在初始化里
*
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void getWatchData() throws KeeperException, InterruptedException {
byte[] data = zooKeeper.getData("/root", true, null);
System.out.println(new String(data));
Thread.sleep(Long.MAX_VALUE);
}

这个监听是一次性的,而且结果在我们的初始化的watch里,初始化方法改为

@Before
public void init() throws IOException {
String conn = "47.111.109.3:2181"; // 连接字符串
int sessionTimeout = 4000; //连接超时时间
zooKeeper = new ZooKeeper(conn, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) {
System.out.println(watchedEvent.getPath());
}
});
}

永久监听设置,我们只要将Watcher新建一下就可以了吗...我们来看一下实现

/**
* 永久监听
*
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void getWatchDataForever() throws KeeperException, InterruptedException {
byte[] data = zooKeeper.getData("/root", new Watcher() {
public void process(WatchedEvent watchedEvent) {
try {
zooKeeper.getData(watchedEvent.getPath(),this,null);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(watchedEvent.getPath());
}
}, null);
System.out.println(new String(data));
Thread.sleep(Long.MAX_VALUE);
}

stat:

/**
* Stat
*
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void getDataStat() throws InterruptedException, KeeperException {
Stat stat = new Stat();
zooKeeper.getData("/root",false, stat);
System.out.println(stat);
}

输出结果和我们命令stat的输入其实是完全一致的,只不过一个事16进制,一个事10进制的,可以自己对比一下。

获取子节点 :

/**
* 获取子节点
*
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void getWatchChildDataForever() throws KeeperException, InterruptedException {
List<String> children = zooKeeper.getChildren("/root", false);
for (int i = 0; i < children.size(); i++) {
System.out.println(children.get(i));
}
}

删除节点:

/**
* 删除节点
*
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void deletePath() throws KeeperException, InterruptedException {
zooKeeper.delete("/root/d2", 0);
}

创建节点:

/**
* 创建节点
*
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void createPath() throws KeeperException, InterruptedException {
List<ACL> acl = new ArrayList<ACL>();
int perm = ZooDefs.Perms.ADMIN | ZooDefs.Perms.CREATE | ZooDefs.Perms.READ;
ACL aclObj = new ACL(perm, new Id("world", "anyone"));
acl.add(aclObj);
zooKeeper.create("/root/d4", "hello".getBytes(), acl, CreateMode.CONTAINER);
}

说到这我们的API和集群操作就差不多说完了。

这次代码不多,就先不上传了,写完下次博客再一起上传。

最进弄了一个公众号,小菜技术,欢迎大家的加入

java架构之路-(分布式zookeeper)zookeeper集群配置和选举机制详解的更多相关文章

  1. java架构之路(mysql底层原理)Mysql之Explain使用详解

    上篇博客,我们详细的说明了mysql的索引存储结构,也就是我们的B+tree的变种,是一个带有双向链表的B+tree.那么我今天来详细研究一下,怎么使用索引和怎么查看索引的使用情况. 我们先来简单的建 ...

  2. 使用 ZooKeeper 同步集群配置

    用 ZooKeeper 同步集群配置,当需要修改所有节点配置时,将配置更新到 ZooKeeper 的一个节点,引起这个节点数据发生变化, 其他所有需要同步配置的节点上的本地 Watcher 会立即发现 ...

  3. Zookeeper的集群配置和Java测试程序

    Zookeeper是Apache下的项目之一,倾向于对大型应用的协同维护管理工作.IBM则给出了IBM对ZooKeeper的认知: Zookeeper 分布式服务框架是 Apache Hadoop 的 ...

  4. Zookeeper的集群配置和Java测试程序 (一)

    概述 Zookeeper是Apache下的项目之一,倾向于对大型应用的协同维护管理工作.IBM则给出了IBM对ZooKeeper的认知: Zookeeper 分布式服务框架是 Apache Hadoo ...

  5. Hadoop入门 完全分布式运行模式-集群配置

    目录 集群配置 集群部署规划 配置文件说明 配置集群 群起集群 1 配置workers 2 启动集群 总结 3 集群基本测试 上传文件到集群 查看数据真实存储路径 下载 执行wordcount程序 配 ...

  6. Linux 下Redis集群安装部署及使用详解(在线和离线两种安装+相关错误解决方案)

    一.应用场景介绍 本文主要是介绍Redis集群在Linux环境下的安装讲解,其中主要包括在联网的Linux环境和脱机的Linux环境下是如何安装的.因为大多数时候,公司的生产环境是在内网环境下,无外网 ...

  7. dubbo+zookeeper伪集群配置

    zookeeper作为注册中心,服务器和客户端都要访问,如果有大量的并发,肯定会有等待.所以可以通过zookeeper集群解决. 一.为什么需要zookeeper呢? 大部分分布式应用需要一个主控.协 ...

  8. 分布式缓存Redis集群配置使用

    Redis 简介          redis是一种开源的.基于内存的.可持久化的.高性能的Key-Value数据存储系统. redis能做什么? 持久化存储  高速缓存 消息中间件         ...

  9. hadoop分布式安装及其集群配置笔记

    各机器及角色信息: 共10台机器,hostname与ip地址映射在此不做赘述.此为模拟开发环境安装,所以不考虑将NameNode和SecondaryNameNode安装在同一台机器. 节点 角色 na ...

随机推荐

  1. python 35 多线程

    目录 多线程 1. 线程 2. 线程vs进程 3. 开启线程的两种方法. 4. 线程的特性 5. 线程的相关方法 6. join 阻塞 7. 守护线程 daemon 8. 互斥锁 多线程 1. 线程 ...

  2. 解决 java Could not resolve resource location pattern [classpath:sql/*.xml] 的问题

    时间过的真快,转眼间已经有2年了.2年里发生了太多的事,有些事依稀还记得,但更多的已经忘记.忘记了那些烦恼与忧愁,以为自己会快乐,才发现一切并不是以自己的意志为转移.终于在迷途中迷失了自己, 再也回不 ...

  3. JVM中class文件探索与解析

    一直想成为一名优秀的架构师的我,转眼已经工作快两年了,对于java内核了解甚少,闲来时间,看看JVM,吧自己的一些研究写下来供大家参考,有不对的地方请指正. 废话不多说,一起来看看JVM中类文件是如何 ...

  4. Codeforces Round #480 (Div. 2)980C Posterized+分组类贪心

    传送门:http://codeforces.com/contest/980/problem/C 参考 题意:给定n个数字,每个数在0~256间,现在给至多连续k的数分为一组,给出字典序最小的答案. 思 ...

  5. CodeForces 223C Partial Sums 多次前缀和

    Partial Sums 题解: 一个数列多次前缀和之后, 对于第i个数来说他的答案就是 ; i <= n; ++i){ ; j <= i; ++j){ b[i] = (b[i] + 1l ...

  6. webpack多页应用架构系列(一):一步一步解决架构痛点

    这系列文章讲什么? 前些时间,写过一个项目,前后端分离,没有借助任何框架,项目页面特别的多,页面都是html直接写的,许多公共html,写了好多处,有一个地方需要改就得改好多地方,js也是随意写,每个 ...

  7. net core天马行空系列: 一个接口多个实现类,利用mixin技术通过自定义服务名,实现精准属性注入

    系列目录 1.net core天马行空系列:原生DI+AOP实现spring boot注解式编程 2.net core天马行空系列: 泛型仓储和声明式事物实现最优雅的crud操作 哈哈哈哈,大家好,我 ...

  8. Java并发编程(一):进程和线程之由来

    转自:http://www.cnblogs.com/dolphin0520/p/3910667.html 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当 ...

  9. 手把手告诉你如何安装多个版本的node,妈妈再也不用担心版本高低引发的一系列后遗症(非常详细,非常实用)

    简介 最近好多人都问到node怎么同时安装多个版本? 如何配置node的环境变量,如何自如的在多个版本中切换node?还有就是自己在做appium自动化的时候,有时候会因为node的版本过高或者是太低 ...

  10. Git的使用(三)远程仓库添加及克隆

    Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上.怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的, ...