本文共 10809 字,大约阅读时间需要 36 分钟。
Zookeeper
:它服务的不是商家和用户,而是应用程序。应用程序注入到 Zookeeper中后,Zookeeper就可以为这些应用程序提供服务
Zookeeper
的现实版本,是一个服务平台,以淘宝为例: Zookeeper
是一个开源、分布式( 多台服务器干一件事 ) ,并且为分布式应用提供协调服务的Apache项目从设计模式角度上来看:zookeeper是基观察者模式设计的分布式服务管理框架
负责存储、管理,一些大家都关心的数据。然后接受 观察者
(类似淘宝客户) 的注册,一旦这些数据发生变化,Zookeeper
将通知已经注册的那些观察者做出相应的反应。从而实现集群中类似的 主从管理模式
Zookeeper = 文件系统 + 通知机制
分布式
和 集群
:
无论分布式还是集群,都是有很多 人(很多台服务器) 再做事情,
例如:饭店招聘
分布式:
招了1个厨师,3个服务员,1个前台。虽然工作不一样,但是都是为这个饭店的运转工作
集群:
招聘3个服务员,但是这3个人的工作是一样的,这就是集群
实际运用:
Feature:
zookeeper是 一个leader、多个follower 组成的集群
Leader是通过内部选举机制临时产生
集群中,只要有半数以上的节点存活,Zookeeper就能正常工作,比如:
假设有10台服务器:
Zookeeper中的数据,具有全局一致性,每台服务器都保存一分相同的数据副本。无论,客户端连接哪台服务器,数据都是一致的
数据的跟新,具有原子性。要么成功,要么失败
实时性,在一定的时间范围内,客户端都能读取到最新的数据
更新的请求 按照顺序执行,会按照发向服务器请求的顺序,逐一执行
树状结构
,每一个节称为:Znode ( ZookeeperNode )1MB
的 元数据
,每个Znode的路径都是唯一的 描述数据的数据
。简单来说,就是记录数据信息的数据Zookeeper提供了统一命名服务
, 统一配置管理
, 统一集群管理
, 服务器节点动态上下线
, 软负载均衡
等
分布式环境下,需要对应用或者服务进行统一命名,便于识别
例如:服务器IP地址不易记住,但是域名很容易记住
通过域名去访问服务器
现将Zookeeper的文件上传到虚拟机的 /opt
目录
# 解压安装包tar -zxvf apache-zookeeper-3.6.0-bin.tar.gz# 查看ll# 解压后的文件名太长,改名为:zookeepermv apache-zookeeper-3.6.0-bin zookeeper# 查看目录ll
# 进入到配置文件夹中cd /opt/zookeeper/conf
修改 zoo_sample.cfg
文件,但是不直接修改,复制一份取名为:zoo.cfg
,在此文件上修改
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2ohAKhhP-1617932299530)(F:\TyporaNotes\picture\image-20210406150817929.png)]
# 复制 zoo_sample.cfg文件cp zoo_sample.cfg zoo.cfg# 打开 zoo.cfgvim zoo.cfg
打开 zoo.cfg
后,修改配置:
# 存放数据的目录dataDir=/opt/zookeeper/zkData# 存放日志的目录dataLogDir=/opt/zookeeper/zkLog
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fJbMQAs9-1617932299532)(F:\TyporaNotes\picture\image-20210406152327672.png)]
然后 ESC
, :wq
保存退出
注意:配置后,要在 opt/zookeeper/
这个目录下,创建 zkData
和 zkLog
这两个目录
cd /opt/zookeeper# 创建目录mkdir zkDatamkdir zkLog
安装完成
# 进入 Zookeeper安装目录下的 `bin` 目录cd /opt/zookeeper/bin
启动Zookeeper
# 启动服务./zkServer.sh start
查看当前 Zookeeper的启动状态
./zkServer.sh status
查看进程是否启动
jps# 只要有 QuorumPeerMain ,说明Zookeeper启动成功
启动客户端
./zkCli.sh# 进入客户端后# 查看 所有Zookeeper的所有节点ls /# 退出客户端窗口quit
停止Zookeeper
# 停止服务./zkServer.sh stop
进入配置文件目录:/opt/zookeeper/conf
找 zoo_sample.cfg
, 但是我们复制了一份:zoo.cfg
,来修改
查看配置文件
vim zoo.cfg
tickTime = 2000
毫秒
,是Zookeeper服务器和客户端之间的心跳时间。initLimit = 10
(集群中的)learder 和 follower 的初始通信时限。
集群启动时能容忍的最多心跳数
initLimit = 10,即 tickTime * initLimit = 10*2000 ms= 20s,也就是说 20s之内,没有心跳发出,那么视为失效的连接,leader 和 follower 彻底断开
syncLimit = 5
learder 和 follower 的同步通信时限。
集群启动后,learder 和 follower 的最大响应时间
如果超过 syncLimit * tickTime
=5*2= 10s,那么 leader认为 follower已经挂掉,leader会将follower从服务器列表删除
dataDir = /opt/zookeeper/zkData
dataLogDir = /opt/zookeeper/zkLog
clientPort = 2181
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-271829qy-1617932299535)(F:\TyporaNotes\picture\image-20210406162336132.png)]
半数机制:
集群中,半数以上的服务器存活,集群可用。所以,Zookeeper适合安装奇数台服务器
Leader的选举机制:
持久型:
持久化目录节点
:客户端和服务器断开连接后,创建的节点依然存在持久化顺序编号目录节点
:客户端和服务器断开连接后,创建的节点依然存在。创建Znode时会设置顺序标识,即在Znode名后附加一个值来标识顺序,例如:Znode001,Znode002…短暂型:
临时目录节点
:客户端和服务器断开连接后,创建的节点会自动删除零时顺序编号目录节点
:客户端和服务器断开连接后,创建的节点会自动删除。创建Znode时会设置顺序标识,即在Znode名后附加一个值来标识顺序,例如:Znode001,Znode002…注意:顺序标识的序号,呈 i ++ 的增长。和数据库中自增类似
网络通信
,一个负责监听
过网络通信
线程,发送给 Zookeeper监听事件
添加到监听列表
中数据变化
或者路径变化
就会将这个消息发送监听
线程server1
上写入数据)server1
不是Leader,那么 server1
会把请求进一步转发给 Leader
Leader
会将写请求的操作,广播给每个server,server写数据操作执行成功后会通知 Leader
Leader
接到半数以上的 server 写数据成功的通知,那么写入数据的操作成功Leader
会告诉 server1
写入数据成功server1
通知 客户端,写入数据成功,整个流程结束集群思路:先搞定一台服务器,再克隆出两台,形成3台服务器的集群(3台是最低标准)
略…( 上文有介绍 )
在 /opt/zookeeper/zkData
中创建 myid
文件
cd /opt/zookeeper/zkData/# 创建myidvim myid# i键进行编辑 (实际上是添加该服务器对应的编号:1 )1# Esc :WQ# 查看myid文件cat myid
上文是介绍了,配置文件是复制一份并且重名为 zoo.cfg
打开配置文件
# 进入bin目录 cd /opt/zookeeper/conf# 打开配置文件vim zoo.cfg
修改配置文件:
# ---------cluster(集群)-----------server.1=192.168.2.17:2888:3888server.2=192.168.2.18.82:2888:3888server.3=192.168.2.19:2888:3888
参数解读: server.A = B : C : D
A
:我们之前配置的服务器编号(/opt/zookeeper/zkData/myid
中的值)B
:该服务器的IP地址C
:与集群中 Leader 服务器交换信息的端口D
:选举机制的专用端口 (万一leader服务器宕机,需要该端口来重新选举一个服务器作为 Leader)。该端口在选举时,进行服务器之间的相互通信查看配置文件是否修改成功:
cat /opt/zookeeper/conf/zoo.cfg
找到存放虚拟机数据的目录 (D:\Program Files\vm
)
在 D:\Program Files\vm
目录下创建 zk02
文件夹
将我们刚刚配置好的服务器数据目录中 所有的.vmx
文件和.vmdk
文件分别拷贝到 zk02
文件夹
打开 虚拟机
—> 文件
—> 打开
( 选择zk02下的 .vmx文件 )
开启虚拟机后,弹出对话框,选择 我已复制该虚拟机
进入系统后:
/opt/zookeeper/zkData/myid
为 2ping www.baidu.com
同理,按照相同的操作配置另外的服务器
关闭每台服务器的防火墙
防火墙的状态:
Active: active (running)
:开启Active: inactive (dead)
:关闭常用命令:
# 查看防火墙systemctl status firewalld# 开启防火墙systemctl start firewalld.service# 关闭防火墙systemctl stop firewalld.service# 设置开机自动启动防火墙systemctl enable firewalld.service# 关闭开机制动启动防火墙systemctl disable firewalld.service# 在不改变状态的条件下重新加载防火墙firewall-cmd --reload
关闭防火墙之后,启动第一台服务器
# 进入bin目录cd /opt/zookeeper/bin/# 启动服务./zkServer.sh start
查看启动状态
cd /opt/zookeeper/bin/ # 查看状态./zkServer.sh status
会发现有一个Error
注意:当启动两台服务器时,查看状态:
mode: follower
mode: leader
启动客户端 ( Server1: 服务器编号为1 )
cd /opt/zookeeper/bin# 启动./zkCli.sh
显示所有操作命令:help
查看Znode中的所有内容:ls + path
# 查看根目录下有哪些Znodels /
查看当前节点的详细数据:ls -s + path
# 查看根节点的详细数据ls -s /
创建普通节点:create
# 在根目录下创建USAcreate /USAcreate /UK
在更目录/
下创建,俄罗斯节点,并保存“普京” 数据到节点上
create /Ru "pujing"
创建多级节点:
# 先创建日本节点create /japan# 再在日本节点下, 创建东京节点create /japan/Tokyo
获得节点的值:get
get /Ru
创建临时节点(断开连接后,删除): create -e
create -e /YiLaKe
创建带序号的节点:create -s
# 创建持久的顺序节点create -s /USA/city # 执行3次# 创建临时的顺序节点create -s -e /USA/city
修改节点中的值:set
set /japan/Tokyo-1
监听节点的值变化或子节点变化
在server3服务器上,注册监听/USA
的变化
addwatch /USA
在Server1 主机上修改/USA
的数据
set /USA "hot"
Server3会立刻响应:
WatchedEvent state:SyncConnected type:NodeDataChanged path:/USA
如果在Server1 的/USA
下创建子节点 NewYork
,Server3会立刻响应
WatchedEvent state:SyncConnected type:NodeCreated path:/USA/NewYork
删除:delete
递归参数:deleteall
deleteall /USA
创建maven项目
导入依赖
org.apache.logging.log4j log4j-core 2.13.3 org.apache.zookeeper zookeeper 3.6.0 junit junit 4.12
在resource目录下创建 log4j.properties
其实就是创建Zookeeper的客户端
public ZooKeeper( String connectString, int sessionTimeout, Watcher watcher)
参数详解:
connectString
:ip:port这种格式,多个的话用逗号,
隔开(不能有空格)sessionTimeout
: watcher
: public class TestZK { private String connectString = "192.168.2.17:2181," + "192.168.2.18:2181," + "192.168.2.19:2181"; private int sessionTimeout = 120 * 1000; /** * 客户端对象 */ private ZooKeeper zkClient; @Test public void init() throws Exception{ zkClient=new ZooKeeper(connectString, sessionTimeout, new Watcher() { public void process(WatchedEvent watchedEvent) { System.out.println("监听到,并且正在处理"); } }); }}
// create方法, 客户端对象调用public String create( String path, byte[] data, Listacl, CreateMode createMode)
参数详解:
path
:节点路径String
用getBytes
方法转换)acl
:节点的权限 id-permission对
,类似于 key-value
键值对permission
:是一个int
表示的位码,每一位代表一种操作对应的允许状态,类似于Linux的文件权限,不同的是共有5种操作:CREATE
、READ
、WRITE
、DELETE
、ADMIN
(admin 对应更改ACL权限) createMode
:创建节点的类型,比如:持久型的,还是临时节点 // 创建节点String str = zkClient.create( "/usa", "要存储的数据".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
然后在服务端查看:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mLYiEgJY-1617932299543)(F:\TyporaNotes\picture\image-20210407180633868.png)]
节点创见成功
public byte[] getData( String path, boolean watch, Stat stat)
参数详解:
String path
:想要获取数据的节点的路径boolean watch
:是用来注册的通知接口,如果节点发生变更,就会通过当前的接口通知客户端。Stat stat
:是用来描述该数据节点的状态信息// 获取数据byte[] data = zkClient.getData("/usa", false, new Stat());// 将获取到的数据,转为StringString str = new String(data);
public Stat setData( String path, byte[] data, int version)
参数详解:
String path
:要修改的目标节点byte[] data
:修改的内容int version
:版本号 (在服务器上用: ls -s
查看)// 修改 /usa 节点上的数据 Stat stat = zkClient.setData( "/usa", "usa节点的值已修改".getBytes(), 0 );
public void delete(String path, int version)
参数详解:
String path
:要删除的目标节点int version
:版本号 (在服务器上用: ls -s
查看)zkClient.delete("/usa", 1);
public ListgetChildren(String path, boolean watch)
参数详解:
String path
:目标节点路径boolean watch
: 监听还是不监听返回值:
List<String>
:目标节点的所有子节点集合Listlist = zkClient.getChildren("/USA", false);
和获取字节点的方法一样,值时参数 watch
为true,变为了监听状态
// 监听根节点Listlist = zkClient.getChildren("/", true);
如果 /
目录下,有节点发生变化,就会被监听到,调用内部的 process
方法。 process
方法在我们创建 Zookeeper对象
时就会定义
public Stat exists(String path, boolean watch)
例子:
Stat stat = zkClient.exists("/YiLaKe", false);// 判断if (stat==null){ System.out.println("节点不存在");}else { System.out.println("节点存在");}
模拟美团的服务平台
提前在更节点下,创建好/meituan
节点
同 4.3.1…
…待跟新
…待跟新
转载地址:http://yhuen.baihongyu.com/