zookeeper框架基础入门

Zookeeper的特点:
1.Zookeeper: 一个领导者(Leader), 多个跟随者(Follower) 组成的集群
2.集群中只要有半数以上的节点存活,Zookeeper集群就能正常服务。
3.全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个server数据都是一致的。
4.更新请求顺序进行,来自同一个client的更新请求按期发送顺序依次执行
5.数据更新原子性,一次数据更新要么成功,要么失败
6.实时性,在一定时间范围内,Client能读到最新的数据。
 

应用场景:
1.统一命名服务
    在分布式环境下,经常需要对应用/服务进行统一命名,便于识别。
    例如:Ip不容易记住,而域名容易记住
2.统一配置管理
    1)分布式环境下,配置文件同步非常常见
        1> 一般要求一个集群中,所有的节点的配置信息都是一致的,比如:Kafka集群
        2> 对配置文件修改后,希望能够快速同步到各个节点上
    2)配置管理可以交由Zookeeper实现
        1> 可将配置信息写入Zookeeper上的一个Znode
        2> 各个客户端服务器监听这个Znode
        3> 一旦Znode中的数据被修改,Zookeeper将通知各个客户端服务器
 

统一集群管理:
    分布式环境中,实时掌握每个节点的状态是必要的。
        可根据节点实时状态做出一些调整
    Zookeeper可以实现实时监控节点状态变化
        可将节点信息写入Zookeeper上的一个ZNode
        监听这个Znode可获取他的实时状态变化

 

服务器动态上下线:
    客户端能实时洞察到服务器上下线的变化

软负载均衡:
    在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新客户端的请求。

Zookepper的下载地址:
    官网地址:https://zookeeper.apache.org

 

安装zookeeper:
    1.把zookeeper-3.4.9.tar.gz上传到服务器
    2.解压zookeeper-3.4.9.tar.gz软件包,重命名为zookeeper
        tar -zxvf zookeeper-3.4.9.tar.gz 
        mv zookeeper-3.4.9  zookeeper
    3.修改配置文件zoo.cfg
        mv zookeeper/conf/zoo.simple.cfg  zookeeper/conf/zoo.cfg
        修改datadir路径:
        dataDir=/opt/mysoft/zookeeper/zkData

        创建制定路径的目录:zkData
        mkdir zkData
    4.启动服务器:
        bin/zkServer.sh start
            jps: QuorumPeerMain
    5.启动客户端:
        bin/zkCli.sh


选举机制:
    目前有5台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,它们的选择举过程如下:

    服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于Looking(选举状态)。
    服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,由于服务器2的编号大所以服务器2胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是LOOKING。
    服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号最大所以服务器3胜出,此时投票数正好大于半数,所以服务器3成为领导者,服务器1,2成为小弟。
    服务器4启动,给自己投票,同时与之前启动的服务器1,2,3交换信息,尽管服务器4的编号大,但之前服务器3已经胜出,所以服务器4只能成为小弟。
    服务器5启动,后面的逻辑同服务器4成为小弟。

Server状态:选举状态
    LOOKING,竞选状态。
    FOLLOWING,随从状态,同步leader状态,参与投票。
    OBSERVING,观察状态,同步leader状态,不参与投票。
    LEADING,领导者状态。

选举消息内容
在投票完成后,需要将投票信息发送给集群中的所有服务器,它包含如下内容。

    服务器ID
    数据ID
    逻辑时钟
    选举状态

节点类型:
    1.持久节点(Persistent) : 客户端和服务器断开连接后,创建的节点不删除
    2.短暂节点(Ephemeral): 客户端和服务器断开连接后,创建的节点自己删除

    持久编号节点
    短暂编号节点


Stat结构体:
    czxid :创建节点的事务zxid


监听器原理:
    1.首先要有一个main()线程
    2.在main线程中创建zookeeper客户端,这时就会创建两个线程,一个负责网络连接通信(connet)
       一个负责监听(listener)
    3.通过connet线程将注册的监听事件发送给Zookeeper
    4.在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中
    5.Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程
    6.listener线程内部调用了process()方法


写数据的流程:
    1.客户端向zookeeper的server1上写数据,发送一个写请求
    2.如果server1不是leader,那么server1会把接受到的请求进一步转发给
       leader,因为每个zookeeper的server里面有一个leader。这个leader
       会将写请求广播给各个server,比如server1和server2,各个server写
       成功后就会通知leader。
    3.当leader收到大多数server数据写成功了,那么久说明数据写成功了,
       如果这里三个节点的话,只要有两个节点数据写成功了,那么就认为
       数据写成功了,写成功之后,leader就会告诉server1数据写成功了。
    4.server1会进一步通知client数据写成功了,这时就认为整个写操作成功了。


Zookeeper分布式安装部署:
    1.把zookeeper的安装程序分别上传到指定的服务器上
    2.解压安装程序,并重命名zookeeper
    3.修改配置文件:
        zoo.cfg
        
        datadir = /opt/mysoft/zookeeper/zkData
        添加集群的地址:
        server.0=hadoop00:2888:3888
        server.1=hadoop01:2888:3888
        server.2=hadoop02:2888:3888
        
    4.在zkData目录中添加myid文件,并在文件中添加服务器对应的数字
        0
    
    5.服务器的启动:
        分别启动各个zookeeper服务器:
        bin/zkServer.sh start
        bin/zkServer.sh status

常用的shell命令:
    启动客户端:bin/zkCli.sh
    1.显示所有操作命令:help
    2.查看当前znode中包含的内容:ls /
    3.查看当前节点详细数据:ls2 /
    4.分别创建2个普通节点: create /test 'guest'
                        create /admin 'manager'
    5.创建短暂节点:create -e /sanguo/shuguo 'zhouyu'
    6.创建带序号的节点:create -s /sanguo/wuguo 'liubei'
    7.修改节点的值:set /sanguo/shuguo 'liubei'
    8.监听节点的值:get /sanguo watch
       在别的节点修改:set /sanguo 'zhangfei' , 节点会发生变化
       提示:SyncConnected type:NodeDataChanged path:/sanguo
       监听:注册一次有效一次
    9.监听路径的变化:
        ls /sanguo watch
        在另外的节点:create /sanguo/wuguo 'sunquan'
 

Java API操作zookeeper框架:

1.创建maven项目

zookeeper框架基础入门_第1张图片

2.添加pom.xml依赖

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.0.0

  zookeeper
  zookeeper
  0.0.1-SNAPSHOT
  jar
  zookeeper
  http://maven.apache.org
 
    UTF-8
 

 
   
      junit
      junit
      4.12
      test
   

   
        org.apache.zookeeper
        zookeeper
        3.4.10
   

 

3.编写测试类

package com.zoo;


import java.util.List;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.ZooDefs.Ids;
import org.junit.Before;
import org.junit.Test;

/**
 * Hello world!
 *
 */
public class TestZookeeper {
    String connect = "hadoop00:2181,hadoop01:2181,hadoop04:2181";
    int sessionTimeout = 2000;
    ZooKeeper zooKeeper = null;

    @Before
    public void init() throws Exception {
        zooKeeper = new ZooKeeper(connect, sessionTimeout, new Watcher() {
            public void process(WatchedEvent event) {
                // 这是监听程序,用于监听zookeeper操作变化
                try {
                    List children = zooKeeper.getChildren("/", true);
                    for(String child : children) {
                        System.out.println(child);
                    }
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    // 创建一个节点
    @Test
    public void createNode() throws Exception, InterruptedException {
        String path = zooKeeper.create("/sanguo/hanguo", "hanfeizi".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.print(path);
    }
    // 获取子节点 并监控节点的变化
    @Test
    public void getDataAndWatch() throws Exception {
        List children = zooKeeper.getChildren("/", true);
        for(String child : children) {
            System.out.println(child);
        }
        // 监听,让线程处于休眠状态, 然后在zookeeper客户端通过shell命令添加删除操作节点,在初始化的监听程序里打印信息
        Thread.sleep(Long.MAX_VALUE);
    }
    
    // 判断节点是否存在
    @Test
    public void exist() throws Exception{
        Stat stat = zooKeeper.exists("/sanguo", false);
        System.out.println(stat == null ? "not exist":"exist");
    }
}

你可能感兴趣的:(java大数据生态圈)