ZooKeeper入门 : 安装部署,监听器原理,Server动态监听

ZooKeeper概述

Zookeeper是一个基于观察者模式设计的分布式服务管理框架,Zookeeper负责存储和管理数据,观察者通过在Zookeeper上注册,并接收Zookeeper观察到的数据状态变化的通知.

Zookeeper=文件系统+通知机制

特点

image-20220320180358012

  1. Zookeeper:一个Leader,多个Follower组成的集群

  2. 集群只要有半数以上节点存活,就还能正常服务

    说明:

    以6台服务器的zk集群为例,必须满足4台节点存活,容错为2台,

    5台服务器的集群只需3台存活,容错也是2台,

    因此奇数台集群相比偶数,容错更高,推荐zk集群安装奇数台服务器

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

    说明:

    1)数据一致的前提是,客户端从正常服务的zk集群中的一台Server读写数据,而不适用于未启动zk集群的某个Server

    2)Zookeeper底层使用了基于Paxos算法改进的Zab算法完成数据一致

  4. 来自Client的更新请求顺序进行:请求队列执行FIFO策略(先进先出)

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

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

数据结构

Zookeeper角色之一是文件系统,类似Unix文件系统,使用目录树结构,每个节点称为ZNode,每个ZNode默认能存储1MB的数据,每个ZNode可以通过其路径唯一标识

image-20220320205256521

应用场景

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

  1. 统一命名服务:满足分布式环境下对应用/服务统一命名的需求

  2. 统一配置管理:

    1)集群中所有节点配置信息一致,比如Kafka集群

    2)分布式环境下同步配置文件:将配置信息写入Zookeeper上一个Znode

    3)客户端服务器监听该Znode,一旦其中数据被修改,ZK将通知各个客户端服务器

  3. 统一集群管理:ZK实时监控节点状态变化

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

  5. 服务器动态上下线[下图]:客户端能实时洞察到服务器上下线

image-20220320211016711

ZK本地模式安装部署

  1. 准备工作:安装好jdk,解压Zookeeper安装包到指定目录

  2. 配置修改:

    1)zookeeper-3.5.7/conf路径下的zoo_sample.cfg修改为zoo.cfg;

    2)修改zoo.cfg中内容:dataDir=/opt/module/zookeeper-3.5.7/zkData

    3)对应的位置创建 zkData

    4)将zookeeper-3.5.7/bin添加到环境变量

  3. 操作Zookeeper

    1)启动Zookeeper: zkServer.sh start

    2)查看状态: zkServer.sh status

    3)启动客户端: zkCli.sh (注意这里没有参数start)

    4)退出客户端: quit

    5)停止Zookeeper: zkServer.sh stop

Zookeeper集群操作

ZK分布式安装部署

  1. 准备工作:同步zookeeper-3.5.7目录到三个节点

  2. 配置服务器编号:zkData目录下创建myid,三个节点分别编辑内容:2/3/4

  3. zoo.cfg配置文件修改并同步:

    #######################cluster##########################

    server.2=hadoop102:2888:3888

    server.3=hadoop103:2888:3888

    server.4=hadoop104:2888:3888

    说明:

    这里server.A=B:C:D中

    A对应myid的内容,对应将三个服务器认定为zk集群节点

    B是这个服务器的地址

    C是这个服务器Follower与集群中的Leader服务器交换信息的端口

    D是选举Leader时的相互通信的端口

  4. 修改环境变量

  5. 分别在三个节点启动Zookeeper(以hadoop102,hadoop103,hadoop104为例):zkServer.sh start

  6. 分别查看状态:zkServer.sh status

    注意:

    1)单个节点启动Zookeeper,集群启动失败(半数以上),而且客户端无法连接该节点

    2)屏幕输出中可以看到,这里三者角色分别为:follower,leader,follower

    由此引出Leader选举机制

选举机制

  1. Zookeeper第一次启动的选举机制:

image-20220320220336052

  1. 非第一次启动的选举机制:

image-20220320220612707

选举Leader规则:

①EPOCH大的直接胜出 ②EPOCH相同,事务id大的胜出 ③事务id相同,服务器id大的胜出

节点类型

image-20220320224644168

注意:

  1. 创建节点时,要赋值
  2. 同一节点下可以创建相同值的相同名称的有序节点,zk自动将节点名称增加序号,序号按原节点下已有n个节点的n开始

监听器原理

image-20220320225204620

  1. 客户端注册监听某节点–>该节点变化(增删改)–>Zookeeper通知客户端
  2. Zookeeper以此机制保证数据的改变快速响应到注册监听的应用程序
  3. 注册一次,只能监听一次。想再次监听,需要再次注册。

客户端命令行操作

命令基本语法功能描述
help显示所有操作命令
ls path使用 ls 命令来查看当前 znode 的子节点 [可监听]
-w 监听子节点变化
-s 附加次级信息
create普通创建
-s 含有序列
-e 临时(重启或者超时消失)
get path获得节点的值 [可监听]
-w 监听节点内容变化
-s 附加次级信息
set设置节点的具体值
stat查看节点状态
delete删除节点
deleteall递归删除节点

客户端API操作

如何使用客户端API实现,获取子节点并监听节点变化?(以根节点为例)

  1. 创建Zookeeper客户端:

    new ZooKeeper(connectString,sessionTimeout,new Watcher());

    重写new Watcher()匿名子类的process()方法:调用getChildren("/",false)获取子节点.

  2. 调用getChildren("/",true),参数传入true表示开启监听,并让当前所在线程延时阻塞Thread.sleep();

  3. 此时通过其他连接到集群的客户端操作"/"根节点即可监听到数据变化

个人认为:

  1. 程序的最后,即主线程末尾设置了延时阻塞,说明监听线程为守护线程
  2. 上述开启监听方法的第2步可省略,换为直接在1中getChildren()参数设置为true,并让线程阻塞.(客户端在完成注册时会监听一次)

客户端向服务端写数据流程

  1. 写入请求直接发给Leader节点:

    image-20220320233318456

    客户端发送写请求到Leader–>Leader节点完成数据写入–>将写入请求广播给1个Follower–>该Follower收到通知完成写入,回复Leader完成写入–>Leader收到ack,判断满足集群一半以上节点完成写入–>Leader回复客户端集群已完成数据写入–>Leader广播剩下的Follower完成写入然后收到ack

  2. 写入请求发给Follower节点:

    除了将客户端的写入请求转发给Leader和集群完成写入的ack回复给客户端,这两处流程与1中不同,其他基本相同

服务器动态上下线监听案例

需求

某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线

image-20220320211016711

实现

  1. 集群上创建/servers节点

  2. IDEA中代码实现:

    编写服务器端代码:

    1)获取集群连接: new ZooKeeper();

    2)注册: 调用create()在"/servers"下创建"/servers/hadoop102"节点

    3)业务代码: 延时阻塞

    编写客户端代码:

    1)获取集群连接: new ZooKeeper();

    2)监听: 调用getChildren("/servers",true);

    3)业务代码: 延时阻塞

ZooKeeper分布式锁

一个进程在使用该资源时,会先获得锁,保持对该资源独占,其他进程就无法访问该资源用完该资源以后就将锁释放掉,让其他进程来获得锁,那么通过这个锁机制,我们就能保证了分布式系统中多个进程能够有序的访问该临界资源。

分布式环境下的这个锁叫作分布式锁。

image-20220321000420625

Curator框架实现分布式锁:

1)原生的 Java API 开发存在的问题:

(1)会话连接是异步的,需要自己去处理。比如使用 CountDownLatch
(2)Watch 需要重复注册,不然就不能生效
(3)开发的复杂性还是比较高的
(4)不支持多节点删除和创建。需要自己去递归

2)Curator 是一个专门解决分布式锁的框架,解决了原生Java API

生产集群安装

生产经验推荐(奇数台):

10 台服务器:3 台 zk;
20 台服务器:5 台 zk;
100 台服务器:11 台 zk;
200 台服务器:11 台 zk

服务器台数多:好处,提高可靠性;坏处:提高通信延时(投票半数以上机制)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值