超级详细的zookeeper的集群搭建
ZooKeeper集群搭建有两种方式:
- 伪分布式集群搭建:
所谓伪分布式集群搭建ZooKeeper集群其实就是在一台机器上启动多个ZooKeeper,在启动每个ZooKeeper时分别使用不同的配置文件zoo.cfg来启动,每个配置文件使用不同的配置参数(clientPort端口号、dataDir数据目录.
在zoo.cfg中配置多个server.id,其中ip都是当前机器,而端口各不相同,启动时就是伪集群模式了。
这种模式和单机模式产生的问题是一样的。也是用在测试环境中使用。
- 完全分布式集群搭建:
多台机器各自配置zoo.cfg文件,将各自互相加入服务器列表,每个节点占用一台机器
架构图
1.准备三台电脑(虚拟机)
安装三个linux虚拟机
配置虚拟网卡(三台电脑配置一个虚拟网卡)(虚拟网卡ip为:192.168.174.1)
为每台虚拟机配置静态ip地址
三台虚拟机分别是:192.168.174.128、192.168.174.129、192.168.174.130
关闭防火墙:service iptables stop
-1.1查看是否已经安装jdk
命令:rpm -qa|grep java
没有安装记得要安装jdk
上传jdk到linux
解压jdk
命令: tar -vxf jdk-8u181-linux-i586.tar.gz
- 1.2、配置环境变量
命令:cd / 退回根目录
命令:cd etc
命令:vim profile (编辑etc/profile文件,将如下配置粘贴到文件中)
#set java environment
JAVA_HOME=/usr/local/jdk1.8.0_181
CLASSPATH=.:$JAVA_HOME/lib.tools.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH
- 重新加载profile文件,即激活profile文件
命令:source profile
2、安装zookeeper到虚拟机并解压
2.1配置zookeeper
- 创建data目录
命令:cd zookeeper (进入zookeeper目录)
命令:mkdir data
- 修改conf/zoo.cfg
命令:cd conf (进入conf目录)
命令:cp zoo_sample.cfg zoo.cfg(复制zoo_sample.cfg,文件名为zoo.cfg)
命令:vim zoo.cfg (修改zoo.cfg)
内容:
修改:
dataDir = /usr/local/zookeeper/data
添加:
server.1=192.168.174.128:2182:3182
server.2=192.168.174.129:2182:3182
server.3=192.168.174.130:2182:3182
- 在data目录创建创建myid
命令:cd … (退出conf目录)
命令: cd data (进入data目录)
命令:vim myid(修改myid文件,分别设置为1,2,3)
3、启动zookeeper
命令:cd … (退出data目录)
命令:cd bin(进入bin路径)
命令: ./zkServer.sh start
3.1查看zookeeper状态
命令:./zkServer.sh status
4.leader选举
在领导者选举的过程中,如果某台ZooKeeper获得了超过半数的选票,则此ZooKeeper就可以成为Leader了。
- 服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于Looking(选举状态)。
- 服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,
每个Server发出一个投票由于是初始情况,1和2都会将自己作为Leader服务器来进行投票,每次投票会包含所推举的服务器的myid和ZXID,使用(myid, ZXID)来表示,此时1的投票为(1, 0),2的投票为(2, 0),然后各自将这个投票发给集群中其他机器。
接受来自各个服务器的投票集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器
处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下
· 优先检查ZXID。ZXID比较大的服务器优先作为Leader。
· 如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器
由于服务器2的编号大,更新自己的投票为(2, 0),然后重新投票,对于2而言,其无须更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可,此时集群节点状态为LOOKING。
统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息
- 服务器3启动,进行统计后,判断是否已经有过半机器接受到相同的投票信息,对于1、2、3而言,已统计出集群中已经有3台机器接受了(3, 0)的投票信息,此时投票数正好大于半数,便认为已经选出了Leader,
改变服务器状态。一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING
所以服务器3成为领导者,服务器1,2成为从节点。
ZXID: 即zookeeper事务id号。ZooKeeper状态的每一次改变, 都对应着一个递增的Transaction id, 该id称为zxid
4.1测试集群
第一步:3台集群,随便挑选一个启动,执行命令./zkCli.sh
第二步:添加节点数据
第三步:找另一台机器,测试查询,可以获取hello节点的数据
也可以使用代码测试
@Test
public void createNode() throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.174.128:2181", 3000, 3000, retryPolicy);
client.start();
client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/bbb/b1","haha".getBytes());
client.close();
}
@Test
public void updateNode() throws Exception {
//创建失败策略对象
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,1);
CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.174.129:2181",1000,1000,retryPolicy);
client.start();
//修改节点
client.setData().forPath("/bbb/b1", "fff".getBytes());
client.close();
}
@Test
public void getData() throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 1);
CuratorFramework client =
CuratorFrameworkFactory.newClient("192.168.174.130:2181",1000,1000, retryPolicy);
client.start();
// 查询节点数据
byte[] bytes = client.getData().forPath("/bbb/b1");
System.out.println(new String(bytes));
client.close();
}
@Test
public void deleteNode() throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 1);
CuratorFramework client =
CuratorFrameworkFactory.newClient("192.168.174.130:2181",1000,1000, retryPolicy);
client.start();
// 递归删除节点
client.delete().deletingChildrenIfNeeded().forPath("/bbb");
client.close();
}
测试使用任何一个IP都可以获取
测试如果有个机器宕机,(./zkServer.sh stop),会重新选取领导者。