atguiguZookeeper

请简述选举机制(面试题)

1.半数机制:集群中半数以上的机器存活,集群可用,所以zookeeper适合安装奇数台服务器

2.zookeeper虽然在配置文件中没有指定Master,Slave,但是zookeeper,工作时,是有有个节点为Leaber,其他则为Follwer,Leader,是通过内部的选举机制临时产生的,

3.zookeeper选举流程图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cuWKnqJ1-1621866342253)(…/TypoarWrokPath/images/1618658450074.png)]

1.服务器1启动,此时只有它的服务器启动了,他发出的报文没有任何响应,所以他的选举状态一直是Looking状态

2.服务器2启动,它与最开始的服务器1进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以id值较大的服务器2胜出,但是由于没有达到超过半数以上的服务器都同意所有服务器1,2都保持Looking状态,

3.服务器3启动,根据前面的分析,服务器3成为服务器1,2,3中的老大,与上面不同的是此时有三台服务器选举了它,所以它成为了这次选举的Leader

4.服务器4 启动根据前面的理论按照道理说应该服务器4是最大的但是由于前面的选举数已经超一半选服务器3,所以服务器4是能是顺从

5.服务器五和服务器4一样顺从前前面的选举

zookeeper的监听原理是什么?(面试题)

1.监听原理

​ 1.首先要有一个main线程

​ 2.在main线程中创建客户端,这时就会创建两个线程,一个负责网络连接通信 (connect),一个负责监听.

​ 3.通过connect线程注册的监听事件发送给zookeeper

​ 4.zookeeper的注册监听器列表中将注册的监听事件添加到列表中

​ 5.zookeeper监听到数据有变化,就会将这个消息发送给listener线程

​ 6.listener线程内部调用了process()方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VCMjO0yh-1621866342255)(…/TypoarWrokPath/images/1618682657936.png)]

2.常见的监听

​ 1.监听节点数据的变化 [get path[watch]]

​ 2.监听子节点增减的变化[ls path[watch]]

zookeeper的部署方式有哪几种?集群中的角色有哪些?,集群最少需要几台?

1.部署方式: 单机模式、集群模式

2.角色: leader和follower

3.集群最少需要集群数: 3台

zookeeper的常用命令

1.ls / 查看节点 ls 路径

2.create /node “lhh” 创建永久节点 在根目录下node 注意一定要带数据

3.create -e -s /node “lhh” 创建临时节点 并且带序号,序号不重复

3.get /node 查看数据 get 路径

4.delete /node 删除节点 delete 路径

5.set /node “lhh1” 修改节点数据 set 路径

6.rmr /node/node 递归删除 rmr 路径

1.概述

Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目。

2.zookeeper工作机制

Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RDUDKe8Q-1621866342261)(…/TypoarWrokPath/images/1618684153039.png)]

3.zookeeper的特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RfEkJUs5-1621866342264)(…/TypoarWrokPath/images/1618684393167.png)]

  1. Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群。2)集群中只要有半数以上节点存活, Zookeeper集群就能正常服务。

3)全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的

4)更新请求顺序进行,来自同一个Client的更新请求按其发送顺序依次执行。

5)数据更新原子性,一次数据更新要么成功,要么失败。

6)实时性,在一定时间范围内,Client能读到最新数据。

4.zookeeper的数据结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n3Jvrg5j-1621866342265)(…/TypoarWrokPath/images/1618685123000.png)]

ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode。每一个 ZNode默认能够存储lMB的数据,每个ZNode都可以通过其路径唯一标识。

5.zookeeper的应用场景

提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等

6.zookeeper写数据流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QkPtxeAH-1621866342266)(…/TypoarWrokPath/images/1618685324363.png)]

1.client向zookeeper的server上写数据,发送一个写的请求

2.如果server不是leader,那么server1会把接收到的请求进一步转发给leade,因为每个zookeeper的server里面有一个是 leader,这个leader会将写请求广播给各个server,比如server1和server2,各个server写成功后就会通知leader

3.当leader收到大多数server数据写入成功了,那么说明数据写成功了,如果这个里三个节点的话,只要有两个节点数据写 成功了,那么认为数据写成功了,写成功之后leader就会告诉server数据写入成功

4.server会进一步通知client数据写成功了,这时就认为写操作成功.

7.zookeeper的负载均衡

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4BdnXqro-1621866342267)(…/TypoarWrokPath/images/1618686661604.png)]

8.服务器动态上下线

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xUouzGsM-1621866342268)(…/TypoarWrokPath/images/1618686709481.png)]

9.统一集群管理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dEvg7hpm-1621866342269)(…/TypoarWrokPath/images/1618686826259.png)]

10.统一配置管理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cF8WpFYP-1621866342270)(…/TypoarWrokPath/images/1618686898269.png)]

11.统一命名服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XKWO1RPh-1621866342271)(…/TypoarWrokPath/images/1618686885092.png)]

12.zookeeperApi操作

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

/**
 * @program: lhh
 * @description:
 * @author: 华仔
 * @create: 2021-04-17 21:55
 */
public class ZookeeperApi {
    //监听哪些zookeeper集群
    private String connecString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
    //会话的超时时间单位毫秒
    private int sessionTimeout = 2000;
    //Watcher 监听器
    //zookeeper客户端对象
    private ZooKeeper zkclit;

     @Before //初始化
    public void init() throws IOException {

        zkclit = new ZooKeeper(connecString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
               
            }
        });
    }
    
    
    @Before //初始化用于获取子节点并监控数据节点的变化 getDataandWatch()方法
    public void init() throws IOException {

        zkclit = new ZooKeeper(connecString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                System.out.println("**********************strat******************");
                List<String> children = null;
                try {
                    children = zkclit.getChildren("/", true);
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                for (String child : children) {
                    System.out.println("child-->"+child);
                }
                System.out.println("*************end***********************************");
            }
        });
    }

    //1.创建节点
    @Test
    public void createNode() throws KeeperException, InterruptedException {
        /**
         *  参数1:path
         *  参数2:携带的数据
         *  参数acl :需要记住 Ids
         */
        String path = zkclit.create("/atguigu", "dahaige".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println("path-->"+path);
    }
    //获取子节点并监控数据节点的变化
    @Test
    public void getDataandWatch() throws KeeperException, InterruptedException {
        List<String> children = zkclit.getChildren("/", true);
        for (String child : children) {
            System.out.println("child-->"+child);
        }
        Thread.sleep(Long.MAX_VALUE);
    }

    //拍断节点是否存在
    @Test
    public void exist() throws KeeperException, InterruptedException {
        //第一个参数路径,第二个参数是否监听
        Stat exists = zkclit.exists("/atguigu", false);
        System.out.println(exists !=null ? "节点存在":"节点不存在");
    }
}

13.监听服务器节点动态上下线案例

1.服务端

package com.lhh;

import org.apache.zookeeper.*;

import java.io.IOException;

/**
 * @program: lhh
 * @description:
 * @author: 华仔
 * @create: 2021-04-17 23:56
 */
public class DistributeServer {
    public static void main(String[] args) {
        DistributeServer server = new DistributeServer();
        //1.连接服务器zookeeper集群
        server.getConnect();
        //2. 注册节点
        server.regist("hadoop105");
        //3.业务逻辑处理
        server.business();
    }

    private void business() {
        try {
            //睡眠为了不程序不直接停止,保持一直在线
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void regist(String hostname) {
        try {
            //创建节点
            String  path= zooKeeper.create("/servers/servers",hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //监听哪些zookeeper集群
    private String connecString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
    //会话的超时时间单位毫秒
    private int sessionTimeout = 2000;

    private ZooKeeper zooKeeper;

    private void getConnect() {
        try {
            //获取zookeeper对象
            zooKeeper = new ZooKeeper(connecString, sessionTimeout, new Watcher() {
                public void process(WatchedEvent watchedEvent) {

                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.客户端

package com.lhh;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: lhh
 * @description:
 * @author: 华仔
 * @create: 2021-04-18 00:13
 */
public class DistributeClient {
    public static void main(String[] args) {
        DistributeClient client = new DistributeClient();

        //1.获取zookeeper集群连接
        client.getConnect();
        //2.注册监听
        client.getChlidren();
        //业务逻辑代码
        client.business();
    }

    private void business() {
        try {
             //睡眠为了不程序不直接停止,保持一直在线
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void getChlidren() {
        try {
            //获取/servers节点下面的所有子节点,并且监听
            List<String> children = zooKeeper.getChildren("/servers", true);
            //存储服务器节点主机名称集合
            ArrayList<String> hosts = new ArrayList<String>();
            for (String child : children) {
                //获取/servers/下面所有节点的所有数据,
                byte[] data = zooKeeper.getData("/servers/" + child, false, null);
                hosts.add(new String(data));
            }
            //打印
            System.out.println("hosts-->"+hosts);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
    private int sessionTimeout = 2000;
    private ZooKeeper zooKeeper;

    private void getConnect() {
        try {
            zooKeeper  =new ZooKeeper(connectString, sessionTimeout, new Watcher() {
                public void process(WatchedEvent watchedEvent) {
                   //在调用一次为了所有的监听只会行一次
                    getChlidren();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

    try {
        zooKeeper  =new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
               //在调用一次为了所有的监听只会行一次
                getChlidren();
            }
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热心市民爱抽烟屁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值