zookeeper的简单介绍和安装

ZooKeeper

一、 ZooKeeper 简介
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop(分布式系统基础架构)和Hbase(分布式数据库)的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper包含一个简单的原语集,提供Java和C的接口。
Zookeeper是一个维护配置信息、命名、提供分布式同步和提供群组服务的高性能分布式系统协调服务。它暴露公共的服务:像命名、配置管理、同步、和群组服务。
顾名思义 zookeeper 就是动物园管理员,他是用来管 hadoop(大象)、Hive(数据仓库工具)(蜜蜂)、pig(大规模数据分析平台)的管理员, Apache Solr 和Redis的分布式集群都用到了 zookeeper

二、 ZooKeeper 的作用

1.1 配置管理

在我们的应用中除了代码外,还有一些就是各种配置。比如数据库连接等。一般我们都是使用配置文件的方式,在代码中引入这些配置文件。当我们只有一种配置,只有一台服务器,并且不经常修改的时候,使用配置文件是一个很好的做法,但是如果我们配置非常多,有很多服务器都需要这个配置,这时使用配置文件就不是个好主意了。这个时候往往需要寻找一种集中管理配置的方法,我们在这个集中的地方修改了配置,所有对这个配置感兴趣的都可以获得变更。Zookeeper 就是这种服务,它使用 Zab 这种一致性协议来提供一致性。现在有很多开源项目使用 Zookeeper 来维护配置,在开源的消息队列 Kafka 中,使用 Zookeeper 来维护 broker 的信息。在 Alibaba 开源的 SOA 框架 Dubbo 中也广泛的使用 Zookeeper 管理一些配置来实现服务治理。
MVC结构的服务调用:

分布式结构的服务调用:

1.2 名字服务

名字服务这个就很好理解了。比如为了通过网络访问一个系统,我们得知道对方的 IP 地址,但是 IP 地址对人非常不友好,这个时候我们就需要使用域名来访问。但是计算机是不能是域名的。怎么办呢?如果我们每台机器里都备有一份域名到 IP 地址的映射,这个倒是能解决一部分问题,但是如果域名对应的 IP 发生变化了又该怎么办呢?于是我们有了 DNS 这个东西。我们只需要访问一个大家熟知的(known)的点,它就会告诉你这个域名对应IP 是什么。在我们的应用中也会存在很多这类问题,特别是在我们的服务特别多的时候,如果我们在本地保存服务的地址的时候将非常不方便,但是如果我们只需要访问一个大家都熟知的访问点,这里提供统一的入口,那么维护起来将方便得多了。

1.3 分布式锁
在一个分布式环境中,为了提高可靠性,集群的每台服务器上都部署着同样的服务。但是,一件事情如果集群中的每个服务器都进行的话,那相互之间就要协调,编程非常复杂。而如果我们只让一个服务进行操作,那又存在单点。通常还有一种做法就是使用分布式锁,在某个时刻只让一个服务去干活,当这台服务出问题的时候锁释放,立即 fail over 到另外的服务。这种设计叫 Leader Election(leader 选举)。

1.4 集群管理

在分布式的集群中,经常会由于各种原因,比如硬件故障,软件故障,网络问题,有些节点会进进出出。有新的节点加入进来,也有老的节点退出集群。这个时候,集群中其他机器需要感知到这种变化,然后根据这种变化做出对应的决策。比如我们是一个分布式存储系统,有一个中央控制节点负责存储的分配,当有新的存储进来的时候我们要根据现在集群目前的状态来分配存储节点。这个时候我们就需要动态感知到集群目前的状态。还有,比如一个分布式的 SOA 架构中,服务是一个集群提供的,当消费者访问某个服务时,就需要采用某种机制发现现在有哪些znode节点可以提供该服务(这也称之为服务发现,比如 Alibaba 开源的 SOA 框架 Dubbo 就采用了 Zookeeper 作为服务发现的底层机制)。还有开源的 Kafka 队列也采用了 Zookeeper 作为 Cosnumer 的上下线管理。
三、 Zookeeper 的存储结构

1 Znode

在 Zookeeper 中,znode 是一个存储节点,可以往znode 存储或获取数据。

Zookeeper 底层是一套数据结构。这个存储结构是一个树形结构,其上的每一个节点,

我们称之为“znode”

zookeeper 中的数据是按照“树”结构进行存储的。而且 znode 节点还分为 4 中不同的类

型。

每一个 znode 默认能够存储 1MB 的数据(对于记录状态性质的数据来说,够了)

可以使用 zkCli 命令,登录到 zookeeper 上,并通过 ls、create、delete、get、set 等命令操作这些 znode 节点

2 Znode 节点四种类型
两个持久节点
(1)PERSISTENT 持久化节点: 所谓持久节点,是指在节点创建后,就一直存在,直到有删除操作来主动清除这个节点。否则不会因为创建该节点的客户端会话失效而消失。

(2)PERSISTENT_SEQUENTIAL 持久顺序节点:这类节点的基本特性和上面的节点类型是一致的。额外的特性是,在 ZK 中,每个父节点会为他的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。基于这个特性,在创建子节点的时候,可以设置这个属性,那么在创建节点过程中,ZK 会自动为给定节点名加上一个数字后缀,作为新的节点名。这个数字后缀的范围是整型的最大值。 在创建节点的时候只需要传入节点 “/test_”,这样之后,zookeeper 自动会给”test_”后面补充数字。

两个临时节点
(3)EPHEMERAL 临时节点:和持久节点不同的是,临时节点的生命周期和客户端会话绑定。也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉(类似于request的生命周期)。注意,这里提到的是会话失效,而非连接断开。另外,在临时节点下面不能创建子节点。

这里还要注意一件事,就是当你客户端会话失效后,所产生的节点也不是一下子就消失了,也要过一段时间,大概是 10 秒以内,本机操作生成节点,在服务器端用命令来查看当前的节点数目,你会发现客户端已经 stop,但是产生的节点还在。

(4) EPHEMERAL_SEQUENTIAL 临时自动编号节点:此节点是属于临时节点,不过带有顺序,客户端会话结束节点就消失。

四、 安装 zookeeper

1 安装单机版

1.1 安装 Linux

1.2 安装 JDK

配置环境变量

1.3 上传 Zookeeper

官方资源包可在 zookeeper.apache.com 站点中下载。最新发布版本为:3.4.12。

1.4 解压 Zookeeper 压缩包

[root@localhost temp]# tar -zxvf zookeeper-3.4.6.tar.gz [root@localhost temp]# cp zookeeper-3.4.6 /usr/local/zookeeper -r

1.5 Zookeeper 目录结构

  1. bin:放置运行脚本和工具脚本,如果是 Linux 环境还会有有 zookeeper 的运行日志 zookeeper.out

  2. conf:zookeeper 默认读取配置的目录,里面会有默认的配置文件

  3. contrib:zookeeper 的拓展功能

  4. dist-maven:zookeeper 的 maven 打包目录

  5. docs:zookeeper 相关的文档

  6. lib:zookeeper 核心的 jar

  7. recipes:zookeeper 分布式相关的 jar 包

  8. src:zookeeper 源码

1.6 配置 Zookeeper

Zookeeper 在启动时默认的去 conf 目录下查找一个名称为 zoo.cfg 的配置文件。

在 zookeeper 应用目录中有子目录 conf。其中有配置文件模板:zoo_sample.cfg

执行cp zoo_sample.cfg zoo.cfg。

zookeeper 应用中的配置文件为 conf/zoo.cfg。

修改配置文件 zoo.cfg 设置数据缓存路径

在zookeeper下创建 data 目录,用于缓存应用运行数

1.7 启动 Zookeeper
./zkServier.sh 回车
发现: 后面提示要接命令

./zkServier.sh start就是启动
./zkServier.sh stop就是停止

默认加载配置文件:./zkServer.sh start:默认的会去 conf 目录下加载 zoo.cfg 配置文件。

2 安装集群版

2.1 Zookeeper 集群中的角色

Zookeeper 集群中的角色主要有以下三类

zookeeper 集群通常是用来对用户的分布式应用程序提供协调服务的,为了保证数据的一致性,对 zookeeper 集群进行了这样三种角色划分:leader、follower、observer分别对应着总统、议员和观察者。
  总统(leader):负责进行投票的发起和决议,更新系统状态。
  议员(follower):用于接收客户端请求并向客户端返回结果以及在选举过程中参与投票。
  观察者(observer):也可以接收客户端连接,将写请求转发给leader节点,但是不参与投票过程,只同步leader的状态。通常对查询操作做负载。

zookeeper集群得是奇数
  我们知道,在每台机器数据保持一致的情况下,zookeeper集群可以保证,客户端发起的每次查询操作,集群节点都能返回同样的结果。
  但是对于客户端发起的修改、删除等能改变数据的操作呢?集群中那么多台机器,你修改你的,我修改我的,最后返回集群中哪台机器的数据呢?
  这就是一盘散沙,需要一个领导,于是在zookeeper集群中,leader的作用就体现出来了,只有leader节点才有权利发起修改数据的操作,而follower节点即使接收到了客户端发起的修改操作,也要将其转交给leader来处理,leader接收到修改数据的请求后,会向所有follower广播一条消息,让他们执行某项操作,follower 执行完后,便会向 leader 回复执行完毕。当 leader 收到半数以上的 follower 的确认消息,便会判定该操作执行完毕,然后向所有 follower 广播该操作已经生效。
  所以zookeeper集群中leader是不可缺少的,但是 leader 节点是怎么产生的呢?其实就是由所有follower 节点选举产生的,讲究民主嘛,而且leader节点只能有一个,毕竟一个国家不能有多个总统。
  这个时候回到我们的小标题,为什么 zookeeper 节点数是奇数,我们下面来一一来说明:
  ①、容错率
  首先从容错率来说明:(需要保证集群能够有半数进行投票)
  2台服务器,至少2台正常运行才行(2的半数为1,半数以上最少为2),正常运行1台服务器都不允许挂掉,但是相对于 单节点服务器,2台服务器还有两个单点故障,所以直接排除了。
  3台服务器,至少2台正常运行才行(3的半数为1.5,半数以上最少为2),正常运行可以允许1台服务器挂掉
  4台服务器,至少3台正常运行才行(4的半数为2,半数以上最少为3),正常运行可以允许1台服务器挂掉
  5台服务器,至少3台正常运行才行(5的半数为2.5,半数以上最少为3),正常运行可以允许2台服务器挂掉
  ②、防脑裂
  脑裂集群的脑裂通常是发生在节点之间通信不可达的情况下,集群会分裂成不同的小集群,小集群各自选出自己的leader节点,导致原有的集群出现多个leader节点的情况,这就是脑裂。
  3台服务器,投票选举半数为1.5,一台服务裂开,和另外两台服务器无法通行,这时候2台服务器的集群(2票大于半数1.5票),所以可以选举出leader,而 另外1 台服务器的集群无法选举。
  4台服务器,投票选举半数为2,可以分成 1,3两个集群或者2,2两个集群,对于 1,3集群,3集群可以选举;对于2,2集群,则都不能选举,造成没有leader节点。
5台服务器,投票选举半数为2.5,可以分成1,4两个集群,或者2,3两集群,这两个集群分别都只能选举一个集群,满足zookeeper集群搭建数目。
  以上分析,我们从容错率以及防止脑裂两方面说明了3台服务器是搭建集群的最少数目,4台在发生脑裂时会造成没有leader节点的错误所以集群得是奇数。

2.2 设计目的

1.最终一致性:client 不论连接到哪个 Server,展示给它都是同一个视图,这是 zookeeper 最重要的性能。

2 .可靠性:具有简单、健壮、良好的性能,如果消息 m 被到一台服务器接受,那么它将被所有的服务器接受。

3 .实时性:Zookeeper 保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper 不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用 sync()接口。

4 .等待无关(wait-free):慢的或者失效的 client 不得干预快速的 client 的请求,使得每

个 client 都能有效的等待。

5.原子性:更新只能成功或者失败,没有中间状态。

6 .顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息 a 在消息 b 前发布,则在所有 Server 上消息 a 都将在消息 b 前被发布;偏序是指如果一个消息 b 在消息 a 后被同一个发送者发布,a 必将排在 b 前面。

2.3 集群安装

使用 3 个 Zookeeper 应用搭建一个伪集群。应用部署位置是:192.168.159.161。服务监听

端口分别为:2181、2182、2183。投票选举端口分别为 2881/3881、2882/3882、2883/3883。(投票端口/选举端口)端口号都可以自定义,只要没有被占用
tar -zxf zookeeper-3.4.6.tar.gz

将解压后的 Zookeeper 应用目录重命名,便于管理 mv zookeeper-3.4.12 zookeeper01

2.3.1 提供数据缓存目录

在 zookeeper01 应用目录中,创建 data 目录,用于缓存应用运行数据 cd zookeeper01

mkdir data

2.3.2 复制应用

复制两份 Zookeeper 应用。用于模拟集群中的 3 个节点。

cp -r zookeeper01 zookeeper02

cp -r zookeeper01 zookeeper03

2.3.3 提供配置文件

在 zookeeper 应用目录中有子目录 conf。其中有配置文件模板:zoo_sample.cfg cp zoo_sample.cfg zoo.cfg

zookeeper 应用中的配置文件为 conf/zoo.cfg。

2.3.4 修改配置文件 zoo.cfg - 设置数据缓存路径

dataDir 参数值为应用运行缓存数据保存目录。是 3.2.3 步骤中创建的目录。使用绝对路径赋值。不同的应用路径不同。

接下来的zookeeper02,中把dataDir修改为/usr/local/zookeepercluster/zookeeper02/data
端口改为2182
接下来的zookeeper03,中把dataDir修改为/usr/local/zookeepercluster/zookeeper03/data
端口改为2183

2.3.5 提供应用唯一标识

在 Zookeeper 集群中,每个节点需要一个唯一标识。这个唯一标识要求是自然数。且唯一标识保存位置是:$dataDir/myid。其中 dataDir 为配置文件 zoo.cfg 中的配置参数

在 data 目录中创建文件 myid : touch myid

为应用提供唯一标识。本环境中使用 1、2、3 作为每个节点的唯一标识。

vim myid

简化的创建方式为: echo [唯一标识] >> myid。 echo 命令为回声命令,系统会将命令发送的数据返回。 '>>'为定位,代表系统回声数据指定发送到什么位置。 此命令代表系统回声数据发送到 myid 文件中。 如果没有文件则创建文件。

echo 1 >> zookeeper01/data/myid
用以下命令可以查看是否创建并浏览myid中的数据:
cat zookeeper01/data/myid
能看到输出值为1
再执行
echo 2 >> zookeeper02/data/myid
echo 3 >> zookeeper03/data/myid
这样我们就在每个zookeeper中创建了一个文件myid文件并且往里面放入了唯一标识

2.3.6 修改配置文件 zoo.cfg - 设置服务、投票、选举端口

在每个zookeeper中的zoo.cfg文件都添加加以下配置
vi zoo.cfg

server.1=192.168.159.161:2881:3881

server.2=192.168.159.161:2882:3882

server.3=192.168.159.161:2883:3883

1.在zookeepercluster目录下创建一个统一启动的命令文件
vim startall.sh
2.把下面的启动命令放入文件

zookeeper01/bin/zkServer.sh start
zookeeper02/bin/zkServer.sh start
zookeeper03/bin/zkServer.sh start

3.给启动文件授权:
[root@localhost zookeepercluster]# chmod +x startall.sh

运行./startall.sh ,可以一次启动三个zookeeper节点了

  1. 用同样的方法创建统一关闭zookeeper节点的命令文件:
    vim stopall.sh

zookeeper01/bin/zkServer.sh stop
zookeeper02/bin/zkServer.sh stop
zookeeper03/bin/zkServer.sh stop

  1. 用同样的方式创建统一查看角色的命令:
    vim showStatus.sh
    zookeeper01/bin/zkServer.sh status
    zookeeper02/bin/zkServer.sh status
    zookeeper03/bin/zkServer.sh status

可以看到所有节点的角色

2.3.7 启动 ZooKeeper 应用

bin/zkServer.sh start

ZooKeeper 集群搭建后,至少需要启动两个应用才能提供服务。因需要选举出主服务节

点。启动所有 ZooKeeper 节点后,可使用命令 bin/zkServer.sh status 来查看节点状态。如下:

Mode: leader

主机

Mode: follower

备份机

2.3.8 关闭 ZooKeeper 应用

bin/zkServer.sh stop 命令为关闭 ZooKeeper 应用的命令。

2.3.9 控制台访问 ZooKeeper 应用

bin/zkCli.sh -server 192.168.199.175:2181

命令格式为: zkCli.sh -server host:port。默认连接 localhost:2181。

随便进一个zookeeper节点,用客户端访问指定的节点:

[root@localhost bin]# ./zkCli.sh -server 192.158.159.129:2182
以上是访问端口为: 2182的那个节点

2.3.10 控制台客户端常用命令
1.在单机版的zookepper/bin下运行zkCli.sh自带的客户端

ls / : 进入zookepper的根目录
单机版的zookepper的结构如下:

quit :退出

本课程只介绍常用命令。

connect host:port - 连接其他的 ZooKeeper 应用。

ls path - 列表路径下的资源。在 ZooKeeper 控制台客户端中,没有默认列表功能,必须指定要列表资源的位置。 如: ls / ; ls /path 等。

create [-e] [-s] path data - 创建节点,
如:
create /test 123 创建一个/test 节点,节点携带数据信息 123。
create -e /test 123 创建一个临时节点/test,携带数据为 123,临时节点只在当前会话生命周期中有效,会话结束节点自动删除。
create -s /test 123 创建一个顺序节点

/test,携带数据 123,创建的顺序节点由 ZooKeeper 自动为节点增加后缀信息,如-/test00000001

等。-e 和-s 参数可以联合使用。

操作集群
集群zookepper连接
先启动集群中zookepper任意一个客户端
./zkCli.sh 回车(当前我们的集群在本机上,所以可以直接回车运行)

或者指定连哪个服务器和端口
./zkCli.sh -server 192.168.159.128:2181
切换端口: connect 192.168.159.128:2182

创建节点:

在根下创建永久节点: create /test 123 (123是节点中的值)
在根下创建临时节点: create -e /text2 333(临时节点会随着客户端的存在而存在,(quit)退出zkCli.sh即被删除)大概有10秒的延时
创建顺序节点(增加后缀信息的节点): create -s /text3 321

创建临时的顺序节点: create -e -s /text4 322

get节点的数据

get path - 查看指定节点的数据。 如: get /test。结果如下:

[zk: 192.168.199.175:2181(CONNECTED) 22] get /test 123
cZxid = 0xd # 创建节点时的事务 ID,由 ZooKeeper 维护。

ctime = Tue Jun 12 07:45:53 PDT 2018

mZxid = 0x1f # 当前节点携带数据最后一次修改的事务 ID。

mtime = Tue Jun 12 07:52:53 PDT 2018

pZxid = 0x21 # 子节点列表最后一次修改的事务 ID。

cversion = 1 # 节点版本号,当节点的子节点列表发生变化时,版本变更。 dataVersion = 2 # 数据版本号,当节点携带数据发生变化时,版本变更。 aclVersion = 0

ephemeralOwner = 0x0 # 此数据值不是 0x0 时,代表是临时节点 dataLength = 3 # 节点携带数据长度 numChildren = 1 # 子节点数量

修改节点值:
set /text 456 1 (1是dataVersion的版本号,必须要写,dataVersion每修改一个值,都会作自增)

删除节点:

delete /text 2 (2是dataVersion的版本号,必须要写,不能删除含有子节点的节点)

删除指定节点:
rmr /text2 (可以删除含有子节点的节点)

开发中一般查询集群中的数据,很少修改
重点:
搭建zookeeper集群

set path data [version] - 设置对应位置节点的数据。如: set /test ‘test data’。 如果要设置的数据中有空格,则使用单引号界定数据的范围。每次修改数据后,dataVersion 属性自增。那么在 set 命令中可以指定 version,version 数据必须与上次查询的值一致,用于保证本次修改命令执行时,没有其他会话修改此数据。

delete path [version] - 删除指定节点,此命令不能删除有子节点的节点。如:delete /test。其中 version 参数和 set 命令的 version 含义一致

rmr path - 删除指定结点,包括子节点。

quit - 退出控制台

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值