ZooKeeper

https://zookeeper.apache.org/

ZooKeeper 是一个分布式服务框架,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:命名服务、状态同步、配置中心、集群管理等

命名服务

命名服务是分布式系统最基本的公共服务之一。在分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等,这些我们都可以统称它们为名字(Name),其中较为常见的就是一些分布式服务框架(如 RPC、RMI)中的服务地址列表,通过使用命名服务,客户端应用能够根据指定名字来获取资源的实体、服务地址和提供者的信息等

状态同步

每个节点除了存储数据内容和 node 节点状态信息之外,还存储了已经注册的APP 的状态信息,当有些节点或 APP 不可用,就将当前状态同步给其他服务

配置中心

现在我们大多数应用都是采用的是分布式开发的应用,搭建到不同的服务器上,可以使用 ZooKeeper 来实现配置中心,ZooKeeper 采用的是推拉相结合的方式: 客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送 Watcher 事件通知,客户端接收到这个消息通知后,需要主动到服务端获取最新的数据

集群管理

所谓集群管理,包括 集群监控集群控制 两部分,前者侧重对集群运行时状态的收集,后者则是对集群进行操作与控制

  • 客户端如果对 ZooKeepe 的一个数据节点注册 Watcher 监听,那么当该数据节点的内容或是其子节点列表发生变更时,ZooKeeper 服务器就会向订阅的客户端发送变更通知
  • 对在 ZooKeeper 上创建的临时节点,一旦客户端与服务器之间的会话失效,该临时节点也就被自动除
1
Watcher(事件监听器):Zookeeper中很重要的特性。Zookeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务端会将事件通知到感兴趣的客户端上去,该机制是 Zookeeper实现分布式协调服务的重要特性

0、生产者启动
1、生产者注册至 zookeeper
2、消费者启动并订阅频道
3、zookeeper 通知消费者事件
4、消费者调用生产者
5、监控中心负责统计和监控服务状态

ZooKeeper 单机安装

ZooKeeper 依赖 Java 环境,要求 JDK1.7 及以上

  1. 配置java环境

    1
    2
    3
    4
    [root@zk1 ~]$java -version
    java version "1.8.0_271"
    Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
    Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)
  2. 部署 ZooKeeper
    官网下载地址:https://archive.apache.org/dist/zookeeper/
    注意,要下载带 bin 的包,不带 bin 的只是源码包,不包含必要的 jar 包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@zk1 src]$tar zxf apache-zookeeper-3.5.9-bin.tar.gz  
    [root@zk1 src]$mv apache-zookeeper-3.5.9-bin
    [root@zk1 src]$mv apache-zookeeper-3.5.9-bin /usr/local/zookeeper
    [root@zk1 src]$cd /usr/local/zookeeper/conf/
    [root@zk1 conf]$cp zoo_sample.cfg zoo.cfg
    [root@zk1 conf]$grep ^[a-Z] ./zoo.cfg
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/tmp/zookeeper
    clientPort=2181
    admin.serverPort=8180 # AdminServer监听的端口,默认8080,因为tomcat默认端口也是8080,为了避免冲突,这里修改为8180

    关于AdminServer:https://zookeeper.apache.org/doc/r3.5.0-alpha/zookeeperAdmin.html#sc_adminserver_config

  3. 启动 ZooKeeper

    1
    2
    3
    4
    5
    6
    7
    # zkServer.sh 	用于启动、重启、停止 ZooKeeper
    [root@zk1 bin]$pwd
    /usr/local/zookeeper/bin
    [root@zk1 bin]$./zkServer.sh start
    ZooKeeper JMX enabled by default
    Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
    Starting zookeeper ... STARTED
  4. 验证 Zookeeper 状态

    1
    2
    3
    4
    5
    [root@zk1 bin]$./zkServer.sh status
    ZooKeeper JMX enabled by default
    Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
    Client port found: 2181. Client address: localhost. Client SSL: false.
    Mode: standalone

ZooKeeper 集群简介

集群架构:

集群角色:

Zookeeper 集群部署

整个集群中只要有超过集群数量一半的 zookeeper 工作只正常的,那么整个集群对外就是可用的

1
2
3
zk1.ljk.cn:10.0.1.101
zk2.ljk.cn:10.0.1.102
zk3.ljk.cn:10.0.1.103
  1. 各个节点安装 zookeeper,参考上面单机部署,但是先不要启动

  2. 各个节点创建数据目录

    1
    2
    3
    4
    5
    6
    7
    8
    [root@zk1 ~]$cd /usr/local/zookeeper/
    [root@zk1 zookeeper]$mkdir data

    [root@zk2 ~]$cd /usr/local/zookeeper/
    [root@zk2 zookeeper]$mkdir data

    [root@zk3 ~]$cd /usr/local/zookeeper/
    [root@zk3 zookeeper]$mkdir data
  3. 各个节点配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [root@zk1 conf]$grep ^[a-Z] ./zoo.cfg
    tickTime=2000 # 心跳检测周期,单位为毫秒
    initLimit=10 # leader与follower初始连接心跳次数,即多少个2000毫秒
    syncLimit=5 # leader与follower连接完成之后,后期检测发送和应答的心跳次数,即该follower在5*2000毫秒内不能与leader进行通信,那么此follower将被视为不可用
    dataDir=/usr/local/zookeeper/data # 自定义的zookeeper保存数据的目录
    clientPort=2181 # 客户端连接Zookeeper服务器的端口,Zookeeper会监听这个端口,接受客户端的访问请求
    maxClientCnxns=128 # 单个客户端IP可以和zookeeper保持的连接数
    autopurge.snapRetainCount=3 # 保存快照的数量,启用后ZooKeeper只保存最新的几个快照,其余的会自动清除,最新快照和相应的事务日志分别保留在dataDir和dataLogDir中,默认值为 3。最小值为 3
    autopurge.purgeInterval=1 # 自动清理日志和快照文件的频率,单位小时,默认0,不开启自动清理
    server.1=10.0.1.101:2888:3888 # server.服务器编号=服务器IP:LF数据同步端口:LF选举端口
    server.2=10.0.1.102:2888:3888 # hostname也可以,只要dns能解析到就行
    server.3=10.0.1.103:2888:3888

    [root@zk1 conf]$scp ./zoo.cfg 10.0.1.102:/usr/local/zookeeper/conf
    [root@zk1 conf]$scp ./zoo.cfg 10.0.1.103:/usr/local/zookeeper/conf
  4. 集群id

    1
    2
    3
    4
    5
    [root@zk1 data]$echo 1 > myid

    [root@zk2 data]$echo 2 > myid

    [root@zk3 data]$echo 3 > myid
  5. 启动 zookeeper

    1
    2
    3
    4
    5
    [root@zk1 bin]$./zkServer.sh start

    [root@zk2 bin]$./zkServer.sh start

    [root@zk3 bin]$./zkServer.sh start
  6. 验证 Zookeeper 状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    [root@zk1 bin]$./zkServer.sh status 
    ZooKeeper JMX enabled by default
    Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
    Client port found: 2181. Client address: localhost. Client SSL: false.
    Mode: follower # follower

    [root@zk2 bin]$./zkServer.sh status
    ZooKeeper JMX enabled by default
    Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
    Client port found: 2181. Client address: localhost. Client SSL: false.
    Mode: follower # follower

    [root@zk3 bin]$./zkServer.sh status
    ZooKeeper JMX enabled by default
    Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
    Client port found: 2181. Client address: localhost. Client SSL: false.
    Mode: leader # leader

zookeeper 集群选举过程

节点角色状态:

1
2
3
4
LOOKING   # 寻找 Leader 状态,处于该状态需要进入选举流程
LEADING # 领导者状态,处于该状态的节点说明是角色已经是 Leader
FOLLOWING # 跟随者状态,表示 Leader 已经选举出来,当前节点角色是 follower
OBSERVER # 观察者状态,表明当前节点角色是 observer

选举 ID:

1
2
ZXID	# zookeeper transaction id,每个改变Zookeeper状态的操作都会形成一个对应的zxid
myid # 服务器的唯一标识(SID),通过配置myid文件指定,集群中唯一

zookeeper 数据增删改查

任意一台zookeeper节点进行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@zk1 bin]$./zkCli.sh -server 10.0.1.102:2181
...
Welcome to ZooKeeper!
JLine support is enabled
[zk: 10.0.1.102:2181(CONNECTING) 0] help
ZooKeeper -server host:port cmd args
addauth scheme auth
close
config [-c] [-w] [-s]
connect host:port
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
delete [-v version] path
deleteall path
delquota [-n|-b] path
get [-s] [-w] path
getAcl [-s] path
history
listquota path
ls [-s] [-w] [-R] path
ls2 path [watch]
printwatches on|off
quit
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
redo cmdno
removewatches path [-c|-d|-a] [-l]
rmr path
set [-s] [-v version] path data
setAcl [-s] [-v version] [-R] path acl
setquota -n|-b val path
stat [-w] path
sync path

zookeeper 客户端 ZooInspector

Linux:https://github.com/zzhang5/zooinspector
Windows:https://www.cnblogs.com/weiyiming007/p/11951591.html

  1. 下载、解压、双击 build/zookeeper-dev-ZooInspector.jar
  2. 连接成功