Zookeeper简单学习

news/2025/2/26 11:29:49

观察者模式

Zookeeper实际是观察者模式负责存储管理数据,接收观察者的注册,一旦数据发生变化,Zookeeper负责通知对应的观察者

Zookeeper=文件系统+通知系统

Zookeeper特点

image-20210519172643570

1,一个领导者(Leader)多个跟随着(Follower)

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

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

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

5,数据更新原子性

6,近实时性,在一定范围内,Client都能获取到最新数据

数据结构

通过树节点存储,每个节点叫一个ZNode,默认每个ZNode可以存储1M数据,每个ZNode可以通过路径唯一确定

image-20210519183733867

应用

1,统一命名管理(一个域名对应多个IP地址)

image-20210519185208462

2,统一配置更新(将配置信息存储到一个ZNode上,多个客服端观察,一旦改变Zookeeper会通知各个客服端更新)

3,统一集群管理(实时监控节点状态变换,将节点信息写入ZNode,监听该ZNode实时获取其变化)

4,服务动态上下线(服务启动会注册到对于的根节点下,下线会取消注册,服务消费者可以观察该节点,动态获取服务状态)

5,软负载均衡(图同1,会在每个IP下记录访问次数,让访问次数最少的去处理新的请求)

客服端命令(不存在的命令会直接打印所有支持的命令相当于Help)

注意监听前都会普通调用一次(主要是减小服务器压力,需要时才监听)

ls path [watch]:按路径查看指定节点的包含节点 watch监听包含节点是否变化(非阻塞,调用一次只监听一次)

ls2 path [watch]:查看指定路径下更详细的信息 watch使用同上

create path value(必须有value否则创建失败) 创建普通节点 -s(创建节点若已经存在添加序号,默认创建若存在会报错) -e(创建临时节点)

get path [watch]:获取指定节点value watch非阻塞监听节点值变化,调用一次只监听一次

set path value:设置节点值

stat path:查看节点状态

delete path:删除单个节点(不能有子节点)

rmr path:递归删除节点

quit:退出关闭客服端

配置文件(/conf/zoo.cfg)

# 心跳时间(毫秒),每tickTime发送一次心跳,会默认设置session超时时间为两倍心跳时间
tickTime=2000
# Follower与Leader初始连接时能容忍的心跳数,超出视为连接失败
initLimit=10
# Follower与Leader同步通信的最大心跳数,若超出该时间,Leader会认为Follower死掉,从服务列表把它删除
syncLimit=5
# 用于保存持久化文件数据
dataDir=../data
# 服务端口
clientPort=2181

选举机制

流程:(每台机器启动先给自己投票,未果投票给Id大的,超过半数的投票才算数,因此必须有半数或以上的启动集群才能正常工作,这里举例有5台依次启动)

第一台,投票给自己并发送投票消息,因为其他机器未启动,它一直处于选举状态

第二台,依旧投票给自己,并与第一台交换信息,因为投票数未超过半数,投票无效

第三台,给自己投票,此时超出了半数,票数相同(会重投给Id大的),第三台编号大胜出成为Leader,其他成为Follower

第四台,给自己投票,虽然编号大,但是已经有Leader成为Follower,后面的类似成为Follower

节点类型

持久:客服端创建的节点不会在断开连接后删除

短暂:客服端创建的节点会在断开连接后自动删除

持久顺序:类似持久不过名称会追加一个父节点维护的自增数字

短暂顺序:类似短暂不过名称会追加一个父节点维护的自增数字

关于顺序的说明:创建ZNode时会对其设置顺序标识,在ZNode名称后附加一个顺序号,顺序号是一个单调递增的计数器,由父类维护

顺序号可以用于推断事件发生的顺序

节点详细信息解释

image-20210520134352211

cZxid:事务ID,记录修改次序,每次修改都会有唯一的cZxid

ctime:创建时间(毫秒数)

mZxid:最后更新的事务Id

mtime:最后修改时间(毫秒数)

pZxid:最后更新的子节点

cversion:子节点变换号,记录子节点修改次数

dataVersion:数据变换号

aclVersion:访问控制列表的变换号

ephemeralOwner:临时节点,这个节点的session Id,不是临时节点,该值为0

dataLength:数据的长度

numChildren:子节点的数量

Zookeeper监听器原理

image-20210520135727966

客服端会创建两个线程(connect负责网络连接,listener负责监听)

Zookeeper会把监听请求注册到监听器列表,一旦发生改变,Zookeeper会把这个消息发送给Listener线程

Listener线程内部调用process方法,对改变进行处理

Zookeeper写数据

1,Client写数据向Server1发送写请求

2,若该Server1不是Leader,Server1会把写请求转发给Leader,Leader负责把写请求广播给所有Server

3,Server写成功后会通知Leader,若超过半数的写数据成功,就认为写数据成功了,Leader最后再告诉该Server1写数据成功

4,该Server1进一步通知Client数据写成功

代码操控

依赖

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

创建客服端

//                                      参数  连接地址           超时时间      监听事件
ZooKeeper keeper = new ZooKeeper("127.0.0.1:2181", 2000, watchedEvent -> {});

创建节点

//  创建节点                    路径         值                                                    
String res = keeper.create("/sk", "HelloWorld".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);//创建模式

监听变换(同样只生效一次)

//获取子节点并指定监听			可以使用布尔值表示是否监听这样监听事件会触发创建ZooKeeper指定的监听器
List<String> list = keeper.getChildren("/", true);
// 							若这样直接指定 触发这个,不再触发创建ZooKeeper时指定的
List<String> list = keeper.getChildren("/", System.out::println);

判断指定路径是否存在

// 判断指定路径是否存在  也可以监听   若存在返回其状态  不存在返回null
Stat exists = keeper.exists("/2233", false);

获取指定路径下的数据

byte[] data=zooKeeper.getData(baseNode + "/" + nodeName, false, null);//可以直接通过new String(data)转换为字符串

ZooKeeper的部署方式,集群角色,集群最少几台机器

1,单机模式,集群模式

2,角色有:Leader和Follower

3,集群最少3台

服务器角色

Leader

(1)事务请求的唯一调度和处理者,保证集群事务处理的顺序性

(2)集群内部各服务的调度者

Follower

(1)处理客户端的非事务请求,转发事务请求给 Leader 服务器

(2)参与事务请求 Proposal 的投票

(3)参与 Leader 选举投票

Observer

(1)3.0 版本以后引入的一个服务器角色,在不影响集群事务处理能力的基础上提升集群的非事务处理能力

(2)处理客户端的非事务请求,转发事务请求给 Leader 服务器

(3)不参与任何形式的投票


http://www.niftyadmin.cn/n/657998.html

相关文章

B. Working out 四角dp

https://codeforces.com/problemset/problem/429/B 这个题目之前写过&#xff0c;不过好像。。忘记了&#xff0c;今天又没有写出来&#xff0c;应该之前没有想明白。。。 这个应该算一个四角dp(网上说的&#xff0c;感觉很符合)&#xff0c;所以呢就是要从四个角进行dp&#x…

xml数据岛 + recordset 数据处理程序简单例子

本程序将数据库中数据一次性装载到客户端xml数据岛中&#xff0c;然后在客户端处理 用recordset 处理数据。 从数据库中提取数据的程序&#xff1a;xmlDeptMatch.asp <!--#include file"../inc/conn.asp"--><!--#include file"../inc/config.asp"…

Java透明窗体绘制不遮挡鼠标交换

我原来想用Java写个桌宠&#xff0c;探索了一下&#xff0c;发现直接继承JFrame设置背景色为透明&#xff0c;再直接在子类下重写的paint(Graphics g)写绘图事件就能实现该功能 动画偏移懒与发射的物体位置懒得校对了&#xff0c;可能会有部分不准确 这个代码有点多&…

Docker 及Docker-distribution

一&#xff1a;docker-distribution#1、获取仓库中的镜像curl 127.0.0.1:5000/v2/_catalog #2、获取镜像的标签curl registry_url/<name>/tags/list 二&#xff1a;Docker #1、默认docker 本地镜像 /var/lib/docker/image/overlay2/imagedb/content/sha256 #2、默认docke…

pl/sql语言的中几个知识点的总结(一)

1 用 update 多字段批量更新 update dog qq set(b,c)(select b,c from cat tt where tt.aqq.a)上面的括号很重要&#xff0c;不能省略。 如果是t-sql就不能这样写。需要有一个from dog的语句。相比来说麻烦了点儿 2 用目表生成新表并拷贝数据 create table horse as sel…

BZOJ4573: [Zjoi2016]大森林

BZOJ4573: [Zjoi2016]大森林 Description 小Y家里有一个大森林&#xff0c;里面有n棵树&#xff0c;编号从1到n。一开始这些树都只是树苗&#xff0c;只有一个节点&#xff0c;标号为1。这些树都有一个特殊的节点&#xff0c;我们称之为生长节点&#xff0c;这些节点有生长出子…

18岁少女欲6000元卖处救患血癌弟弟(组图)

本文转载自&#xff1a;ChinaRen社区 原文地址&#xff1a;http://club.chinaren.com/bbs/index_800.jsp?boardid0&hotmsgid84580187 时报记者开解阿萍&#xff0c;最终让她放弃了“卖身”的念头18岁少女欲卖贞操救弟弟   致电律师称弟弟患血癌愿以处女之身换6000元 经…

编写一个简易版Redis客服端

前置知识Resp Redis的序列化协议(Redis Serialization Protocol),直观的文本协议&#xff0c;优点&#xff1a;实现简单&#xff0c;解析性能好 传输5种最小的数据类型&#xff0c;单元结束统一使用 \r\n 单行字符串使用开头 hello world\r\n 多行使用$开头&#xff0c;后跟…