Zookeeper初探

前言

前不久研究了下Zookeeper,感觉挺不错的,这几天把成果总结下,方便记忆。

今天先简单介绍下它的安装使用和一些特性吧。

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

正文

Zookeeper的安装与配置

首先需要下载安装包。

Zookeeper官网地址

点击这里 我们可以通过镜像的方式将压缩包下载下来。

upload successful

解压到合适目录,进入到zookeeper目录下的conf目录,需要新建zoo.cfg文件,可以看到里面有一个zoo_sample.cfg文件,可以作为我们的配置参考。

upload successful

我们来看下它里面的一些常用参数:

tickTime=2000
指Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。单位毫秒

initLimit=10
此配置表示,允许 follower(相对于 leader 而言)连接并同步到 leader 的初始化连接时间,它以 tickTime 的倍数来表示。当超过设置倍数的 tickTime 时间,则连接失败。

syncLimit=5
此配置表示,leader 与 follower 之间发送消息,请求和应答时间长度。如果 follower 在设置的时间内不能与leader 进行通信,那么此 follower 将被丢弃。

dataDir=D:/zookeeper1/zookeeper/data
数据存储快照的地址

dataLogDir=D:/zookeeper1/zookeeper/log
数据库事务日志地址,如果不设置此项,默认dataDir的地址

clientPort=2181
供客户端连接的端口,对外提供的端口

server.10=127.0.0.1:2888:3888
集群模式下需要的配置(单机不需要) server.A = B:C:D
A:表示这是第几号服务器
B:服务器的 IP 地址
C:集群内机器通讯使用(Leader监听此端口)
D:一旦集群中的 Leader 服务器挂了,需要一个端口重新进行选举,选出一个新的 Leader

Zookeeper的启动和使用

看完上面配置后,我们先配置单机zookeeper对其简单使用。

进入到zookeeper bin目录下,我们可以看到一些脚本,分为cmd脚本和sh脚本。

upload successful

zkCleanup  清理Zookeeper历史数据脚本,包括日志文件和快照数据文件
zkCli    Zookeeper的客户端脚本
zkEnv    设置Zookeeper的环境变量脚本
zkServer   Zookeeper服务器的启动、停止、和重启脚本

启动Zookeeper

Windows操作:

进入到bin目录下,执行如下命令:
zkServer
可以启动zookeeper服务。(需要注意windows下dataDir路径支持/和\\,但使用\会出现问题。)

下图是我公司电脑(Windows)上的zookeeper启动图。

upload successful

Linux/Mac/Unix操作:

进入到bin目录下,执行如下命令:
./zkServer.sh start
可以启动zookeeper服务。

停止Zookeeper

Windows操作:

直接可以Ctrl+C结束命令。

Linux/Mac/Unix操作:

./zkServer.sh stop
PS:杀进程也可以结束,不推荐

连接Zookeeper

Windows操作:

进入到bin目录下,执行如下命令:
zkCli -server localhost:2181
可以连接到zookeeper服务。

下图是Windows电脑上连接到zookeeper服务的图。

upload successful

Linux/Mac/Unix操作:

进入到bin目录下,执行如下命令:
./zkCli.sh -server localhost:2181
可以连接到zookeeper服务。

Zookeeper常用命令

在zookeeper客户端,使用help可以查看可以使用的命令。

upload successful

我们说几个比较常用的命令。

创建节点:

create [-s] [-e] path data acl
使用此命令可以创建一个zookeeper节点。
其中,-s或-e分别指定节点特性,顺序或临时节点,若不指定,则表示持久节点;acl用来进行权限控制。

create -s /zk-test test
表示创建顺序节点zk-test。

upload successful

可以看到创建的zk-test节点后面添加了一串数字以示区别顺序。

create -e /zk-temp test
表示创建临时节点。临时节点在客户端断开连接后会自动删除。

upload successful

upload successful

可以看到创建临时节点重新登陆后节点已被删除。

create /zk-permanent  test
创建永久节点zk-permanent。

读取节点:

ls path [watch] 
可以列出节点下面的所有子节点。
get path [watch] 
可以获取根节点数据内容和属性信息。
ls2 path [watch] 
列出节点信息。

如下图:

upload successful

更新节点:

set path data [version]

我们将zk-permanent节点下的数据test变为test1。

upload successful

可以看到dataVersion也发生了变化,用来表示已经进行了更新。

删除节点:

delete path [version]

我们删除刚才创建的zk-permanent节点。

upload successful

可以看到节点已经被删除。

PS:若删除节点存在子节点,那么无法删除该节点,必须先删除子节点,再删除父节点。

Zookeeper部署模式

Zookeeper的部署模式一般分为3种,单机模式、伪集群模式、集群模式。

单机模式

单个Zookeeper服务,如上面所述。

伪集群模式

所谓伪集群, 是指在单台机器中启动多个zookeeper进程, 并组成一个集群。

以3个zookeeper服务进程为例。

需要有3个zookeeper项目。

upload successful

三个项目配置特殊的地方:

zookeeper1配置:

1
2
3
4
5
6
7
dataDir=D:/zookeeper1/zookeeper/data
dataLogDir=D:/zookeeper1/zookeeper/log
clientPort=2181
server.1=127.0.0.1:2881:3881
server.2=127.0.0.1:2882:3882
server.3=127.0.0.1:2883:3883
#同时在dataDir路径文件夹里需要新建myid文件,里面写入服务器的编号 1

zookeeper2配置:

1
2
3
4
5
6
7
dataDir=D:/zookeeper2/zookeeper/data
dataLogDir=D:/zookeeper2/zookeeper/log
clientPort=2182
server.1=127.0.0.1:2881:3881
server.2=127.0.0.1:2882:3882
server.3=127.0.0.1:2883:3883
#同时在dataDir路径文件夹里需要新建myid文件,里面写入服务器的编号 2

zookeeper3配置:

1
2
3
4
5
6
7
dataDir=D:/zookeeper3/zookeeper/data
dataLogDir=D:/zookeeper3/zookeeper/log
clientPort=2183
server.1=127.0.0.1:2881:3881
server.2=127.0.0.1:2882:3882
server.3=127.0.0.1:2883:3883
#同时在dataDir路径文件夹里需要新建myid文件,里面写入服务器的编号 3

在同一台机器上,3者的端口号不能相同,不然出现端口冲突。

集群模式

集群模式下配置和伪集群相似。

服务器1配置:

1
2
3
4
5
6
7
8
9
tickTime=2000
initLimit=10
syncLimit=5
dataDir=D:/zookeeper1/zookeeper/data
dataLogDir=D:/zookeeper1/zookeeper/log
clientPort=2181
server.1=10.1.100.1:2888:3888
server.2=10.1.100.2:2888:3888
server.3=10.1.100.3:2888:3888

由于不在一个服务器上,故服务器2,服务器3也如上面的配置即可,它们3个唯一不同的地方是dataDir文件夹里面的myid文件,代表着服务器各自的编号。

Zookeeper特性

由上面内容,我们汇总说下Zookeeper的一些性质。

类文件系统(数据节点)

Zookeeper有类似于Unix文件系统的节点。它可以自由创建、修改和删除子目录,这些目录项被称为znode,znode可以存储数据。

Zookeeper有4种类型的znode:

1. PERSISTENT
   持久化目录节点,客户端与zookeeper断开连接后,该节点依旧存在 
2. PERSISTENT_SEQUENTIAL
   持久化顺序编号目录节点,客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 
3. EPHEMERAL
   临时目录节点,客户端与zookeeper断开连接后,该节点被删除 
4. EPHEMERAL_SEQUENTIAL
   临时顺序编号目录节点,客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

通知机制

客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。这是非常重要的一条性质。

高可用性

zookeeper的高可用性通过zookeeper集群实现。

Zookeeper一般有三种集群角色:

Leader(领导者)
Follower(跟随者)
Observer(观察者)

一个 ZooKeeper 集群同一时刻只会有一个 Leader,其他都是 Follower 或 Observer。

ZooKeeper 默认只有 Leader 和 Follower 两种角色,没有 Observer 角色。为了使用 Observer 模式,在任何想变成Observer的节点的配置文件中加入 peerType=observer 并在所有 server 的配置文件中,配置成 observer 模式的 server 的那行配置追加 :observer即可。

ZooKeeper 集群的所有机器通过一个 Leader 选举过程来选定一台机器作为Leader,Leader服务器为客户端提供读和写服务。Follower 和 Observer 都能提供读服务,不能提供写服务。两者唯一的区别在于,Observer机器不参与 Leader 选举过程,也不参与写操作的过半写成功策略,因此 Observer 可以在不影响写性能的情况下提升集群的读性能。

我们简单来看下:

我在自己的Mac机器上创建了4个zookeeper服务并启动(伪集群),其中一个是Observer,另三个其中一个是Leader,其它两个Follower。(3台机器中谁是Leader是选举出来的,一般情况下先启动的会成为Leader)。

配置如下(关键配置):

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
# zookeeper1的配置,myid文件里值为1
clientPort=2181
server.1=127.0.0.1:2881:3881
server.2=127.0.0.1:2882:3882
server.3=127.0.0.1:2883:3883
server.4=127.0.0.1:2884:3884:observer

# zookeeper2的配置,myid文件里值为2
clientPort=2182
server.1=127.0.0.1:2881:3881
server.2=127.0.0.1:2882:3882
server.3=127.0.0.1:2883:3883
server.4=127.0.0.1:2884:3884:observer

# zookeeper3的配置,myid文件里值为3
clientPort=2183
server.1=127.0.0.1:2881:3881
server.2=127.0.0.1:2882:3882
server.3=127.0.0.1:2883:3883
server.4=127.0.0.1:2884:3884:observer

# zookeeper4的配置,myid文件里值为4
clientPort=2184
peerType=observer
server.1=127.0.0.1:2881:3881
server.2=127.0.0.1:2882:3882
server.3=127.0.0.1:2883:3883
server.4=127.0.0.1:2884:3884:observer

启动后查看它们的角色:

upload successful

可以看到zookeeper2是leader,我们停掉zookeeper2.

upload successful

可以看到leader变成了zookeeper3.

我们继续把zookeeper3停掉。

upload successful

可以发现zookeeper集群已经不能正常运行了。

zookeeper在执行增删改操作时,只要有半数以上服务器通过,就可以成功执行(不包括observer服务器)

半数以上投票通过:可以这样理解,客户端的增删改操作无论访问到了哪台zookeeper服务器,最终都会被转发给leader服务器,再由leader服务器分给zookeeper集群中所有follower服务器去投票(投票指的是在内存中做增删改操作),半数投票通过就被认为操作可执行(commit),否则不可执行。

由于在增删改操作中需要半数以上服务器通过,来分析以下情况。

2台服务器,至少2台正常运行才行,正常运行1台服务器都不允许挂掉。
3台服务器,至少2台正常运行才行,正常运行可以允许1台服务器挂掉。
4台服务器,至少3台正常运行才行,正常运行可以允许1台服务器挂掉。
......

故上面例子当挂掉两台服务器时,zookeeper服务已经不能正常运行了。

由上面可以知道,2n-1台服务器和2n台服务器都最多允许n-1台服务器挂掉(n>=2)。

一般为了节省资源,环境基本配置奇数2n-1台服务器(不包括observer)。

Zookeeper应用场景

Zookeeper的应用场景还是很多的,如:

1.命名服务
2.分布式协调服务/通知 
3.数据发布与订阅(配置中心) 
4.Master选举 
5.分布式锁

等。

我会在后面结合例子研究zookeeper的一些应用场景。

结语

通过对Zookeeper的一些学习,明白了Zookeeper的一些特点用途,了解了一些简单操作,还是蛮不错的一次学习过程。




-------------文章结束啦 ~\(≧▽≦)/~ 感谢您的阅读-------------

您的支持就是我创作的动力!

欢迎关注我的其它发布渠道