zookeeper入门

来源:互联网 发布:阿里云手机验证码 编辑:程序博客网 时间:2024/05/16 18:13

简介

ZooKeeper 是一个为分布式应用所设计的分布的、开源的协调服务。分布式的应用可以建立在同步、配置管理、分组和命名等服务的更高级别的实现的基础之上。 ZooKeeper 意欲设计一个易于编程的环境,它的文件系统使用我们所熟悉的目录树结构。 ZooKeeper 使用 Java 所编写,但是支持 Java 和 C 两种编程语言。众所周知,协调服务非常容易出错,但是却很难恢复正常,例如,协调服务很容易处于竞态以至于出现死锁。我们设计 ZooKeeper 的目的是为了减轻分布式应用程序所承担的协调任务。

数据模型和层次命名空间

提供的命名空间与标准的文件系统非常相似。一个名称是由通过斜线分隔开的路径名序列所组成的。ZooKeeper中的每一个节点是都通过路径来识别。

节点和临时节点

ZooKeeper的节点是通过像树一样的结构来进行维护的,并且每一个节点通过路径来标示以及访问。除此之外,每一个节点还拥有自身的一些信息,包括:数据、数据长度、创建时间、修改时间等等。从这样一类既含有数据,又作为路径表标示的节点的特点中,可以看出,ZooKeeper的节点既可以被看做是一个文件,又可以被看做是一个目录,它同时具有二者的特点。为了便于表达,今后我们将使用Znode来表示所讨论的ZooKeeper节点。

具体地说,Znode维护着数据、ACL(access control list,访问控制列表)、时间戳等交换版本号等数据结构,它通过对这些数据的管理来让缓存生效并且令协调更新。每当Znode中的数据更新后它所维护的版本号将增加,这非常类似于数据库中计数器时间戳的操作方式。

另外Znode还具有原子性操作的特点:命名空间中,每一个Znode的数据将被原子地读写。读操作将读取与Znode相关的所有数据,写操作将替换掉所有的数据。除此之外,每一个节点都有一个访问控制列表,这个访问控制列表规定了用户操作的权限。

ZooKeeper中同样存在临时节点。这些节点与session同时存在,当session生命周期结束,这些临时节点也将被删除。临时节点在某些场合也发挥着非常重要的作用。

安装

ZooKeeper的安装模式分为三种,分别为:单机模式(stand-alone)、集群模式和集群伪分布模式。ZooKeeper 单机模式的安装相对比较简单,如果第一次接触ZooKeeper的话,建议安装ZooKeeper单机模式或者集群伪分布模式。

单机模式

1. 下载安装文件

从Apache官网下载稳定版本,地址

2. 安装Java环境&配置Path

ZooKeeper 要求 JAVA 的环境才能运行,并且需要 JAVA6 以上的版本,可以从 SUN 官网上下载,并对 JAVA环境变量进行设置。除此之外,为了今后操作的方便,我们需要对 ZooKeeper 的环境变量进行配置,方法如下,在/etc/profile 文件中加入如下的内容:

#Set ZooKeeper Enviromentexport ZOOKEEPER_HOME=/root/hadoop-0.20.2/zookeeper-3.3.1export PATH=$PATH:$ZOOKEEPER_HOME/bin:$ZOOKEEPER_HOME/conf

3. 配置

ZooKeeper 服务器包含在单个 JAR 文件中,安装此服务需要用户创建一个配置文档,并对其进行设置。我们在 ZooKeeper-..* 目录(我们以当前 ZooKeeper 的最新版 3.3.1 为例,故此下面的“ ZooKeeper-..* ”都将写为“ZooKeeper-3.3.1” )的 conf 文件夹下创建一个 zoo.cfg 文件,它包含如下的内容:

tickTime=2000dataDir=/var/zookeeperclientPort=2181

在这个文件中,我们需要指定 dataDir 的值,它指向了一个目录,这个目录在开始的时候需要为空。下面是每个参数的含义:

tickTime :基本事件单元,以毫秒为单位。它用来指示心跳,最小的 session 过期时间为两倍的 tickTime. 。

dataDir :存储内存中数据库快照的位置,如果不设置参数,更新事务日志将被存储到默认位置。

clientPort :监听客户端连接的端口

使用单机模式时用户需要注意:这种配置方式下没有 ZooKeeper 副本,所以如果 ZooKeeper 服务器出现故障, ZooKeeper 服务将会停止。

集群模式

为了获得可靠的 ZooKeeper 服务,用户应该在一个集群上部署 ZooKeeper 。只要集群上大多数的 ZooKeeper服务启动了,那么总的 ZooKeeper 服务将是可用的。另外,最好使用奇数台机器。 如果 zookeeper 拥有 5 台机器,那么它就能处理 2 台机器的故障了。

之后的操作和单机模式的安装类似,我们同样需要对 JAVA 环境进行设置,下载最新的 ZooKeeper 稳定版本并配置相应的环境变量。不同之处在于每台机器上 conf/zoo.cfg 配置文件的参数设置,参考下面的配置(以其中的一台为例):

tickTime=2000dataDir=/var/zookeeper/clientPort=2181initLimit=5syncLimit=2server.1=zoo1:2888:3888server.2=zoo2:2888:3888server.3=zoo3:2888:3888

“server.id=host:port:port. “指示了不同的 ZooKeeper 服务器的自身标识,作为集群的一部分的机器应该知道ensemble 中的其它机器。用户可以从“ server.id=host:port:port. ”中读取相关的信息。 在服务器的 data ( dataDir参数所指定的目录)目录下创建一个文件名为 myid 的文件,这个文件中仅含有一行的内容,指定的是自身的 id值。比如,服务器“ 1 ”应该在 myid 文件中写入“ 1 ”。这个 id 值必须是 ensemble 中唯一的,且大小在 1 到 255 之间。这一行配置中,第一个端口( port )是从( follower )机器连接到主( leader )机器的端口,第二个端口是用来进行 leader 选举的端口。在这个例子中,每台机器使用三个端口,分别是: clientPort , 2181 ; port ,2888 ; port , 3888 。

集群伪分布式

简单来说,集群伪分布模式就是在单机下模拟集群的ZooKeeper服务。

那么,如何对配置 ZooKeeper 的集群伪分布模式呢?其实很简单,在 zookeeper 配置文档中, clientPort 参数用来设置客户端连接 zookeeper 的端口。 server.1=IP1:2887:3887 中, IP1 指示的是组成 ZooKeeper 服务的机器IP 地址, 2887 为用来进行 leader 选举的端口, 3887 为组成 ZooKeeper 服务的机器之间通信的端口。集群伪分布模式我们使用每个配置文档模拟一台机器,也就是说,需要在单台机器上运行多个 zookeeper 实例。但是,我们必须要保证各个配置文档的 clientPort 不能冲突。

例如,通过 zoo1.cfg , zoo2.cfg , zoo3.cfg 模拟了三台机器的 ZooKeeper 集群。

除了 clientPort 不同之外, dataDir 也不同。另外,不要忘记在 dataDir 所对应的目录中创建 myid 文件来指定对应的 zookeeper 服务器实例。

配置详解

ZooKeeper 的功能特性通过 ZooKeeper 配置文件来进行控制管理( zoo.cfg 配置文件)。 ZooKeeper 这样的设计其实是有它自身的原因的。通过前面对 ZooKeeper 的配置可以看出,对 ZooKeeper 集群进行配置的时候,它的配置文档是完全相同的(对于集群伪分布模式来说,只有很少的部分是不同的)。这样的配置方使得在部署ZooKeeper 服务的时候非常地方便。另外,如果服务器使用不同的配置文件,必须要确保不同配置文件中的服务器列表相匹配。

在设置 ZooKeeper 配置文档的时候,某些参数是可选的,但是某些参数是必须的。这些必须的参数就构成了ZooKeeper 配置文档的最低配置要求。

下面是在最低配置要求中必须配置的参数:

最低配置

  • clientPort

监听客户端连接的端口;

  • dataDir

存储内存中数据库快照的位置;

注意 应该谨慎地选择日志存放的位置,使用专用的日志存储设备能够大大地提高系统的性能,如果将日志存储在比较繁忙的存储设备上,那么将会在很大程度上影响系统的性能。

  • tickTime

基本事件单元,以毫秒为单位。它用来控制心跳和超时,默认情况下最小的会话超时时间为两倍的 tickTime 。

高级配置

下面是高级配置要求中可选的配置参数,用户可以使用下面的参数来更好地规定 ZooKeeper 的行为:

  • dataLogDir

这个操作将管理机器把事务日志写入到“ dataLogDir ”所指定的目录,而不是“ dataDir ”所指定的目录。这将允许使用一个专用的日志设备并且帮助我们避免日志和快照之间的竞争。配置如下dataLogDir=/root/hadoop-0.20.2/zookeeper-3.3.1/log/data_log

  • maxClientCnxns

这个操作将限制连接到 ZooKeeper 的客户端的数量,限制并发连接的数量,它通过 IP 来区分不同的客户端。此配置选项可以用来阻止某些类别的 Dos 攻击。将它设置为 0 或者忽略而不进行设置将会取消对并发连接的限制。

  • minSessionTimeout 和 maxSessionTimeout

最小的会话超时时间以及最大的会话超时时间。其中,最小的会话超时时间默认情况下为 2 倍的 tickTme 时间,最大的会话超时时间默认情况下为 20 倍的会话超时时间。在配置 minSessionTmeout 以及 maxSessionTimeout 的值的时候需要注意,如果将此值设置的太小的话,那么会话很可能刚刚建立便由于超时而不得不退出。一般情况下,不能将此值设置的比 tickTime 的值还小。

集群配置

  • initLimit

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

  • syncLimit

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

启动

不同的模式下启动方式大同小异,但是输出会有些不同

单机模式

zkServer.sh start

集群模式

在每台机器上执行 zkServer.sh start

集群伪分布式

需要指定各自的zoo.cfg文件   zkServer.sh start zoo1.cfg zkServer.sh start zoo2.cfg zkServer.sh start zoo3.cfg

有时候会出现异常,比如Can not open channel to 3 at election address xxxx:2181

异常信息是由于 ZooKeeper 服务的每个实例都拥有全局的配置信息,它们在启动的时候需要随时地进行 Leader 选举操作(此部分内容下面将会详细讲述)。此时第一个启动的 Zookeeper 需要和另外两个ZooKeeper 实例进行通信。但是,另外两个 ZooKeeper 实例还没有启动起来,因此将会产生上述所示的异常信息。

我们直接将其忽略即可,因为当把图示中的“ 2 号”和“ 3 号” ZooKeeper 实例启动起来之后,相应的异常信息就回自然而然地消失。

四字命令

ZooKeeper 支持某些特定的四字命令字母与其的交互。它们大多是查询命令,用来获取 ZooKeeper 服务的当前状态及相关信息。用户在客户端可以通过 telnet 或 nc 向 ZooKeeper 提交相应的命令。

  • conf

输出相关服务配置的详细信息。

  • cons

列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。包括“接受 / 发送”的包数量、会话 id 、操作延迟、最后的操作执行等等信息。

  • dump

列出未经处理的会话和临时节点。

  • envi

输出关于服务环境的详细信息(区别于 conf 命令)。

  • reqs

列出未经处理的请求

  • ruok

测试服务是否处于正确状态。如果确实如此,那么服务返回“ imok”,否则不做任何相应。

  • stat

输出关于性能和连接的客户端的列表。

  • wchs

列出服务器 watch 的详细信息。

  • wchc

通过 session 列出服务器 watch 的详细信息,它的输出是一个与watch 相关的会话的列表。

  • wchp

通过路径列出服务器 watch 的详细信息。它输出一个与 session相关的路径。

举例

echo stat|nc 172.168.2.101 2181    Zookeeper version: 3.4.6-1569965, built on 02/20/2014 09:09 GMTClients:     /172.168.2.133:36068[1](queued=0,recved=218777,sent=218777)     /172.168.3.133:35330[1](queued=0,recved=218786,sent=218786)Latency min/avg/max: 0/0/13Received: 4359214Sent: 4359641Connections: 16Outstanding: 0Zxid: 0x900001d11Mode: followerNode count: 463

Zookeeper命令行

当启动 ZooKeeper 服务成功之后,输入下述命令,连接到 ZooKeeper 服务:zkCli.sh -server 10.77.20.23:2181

然后通过help命令了解其他命令,比如下面例子

**注:**zookeeper中的节点既是”目录”也是”文件”,就是一棵树上的节点,本身可以包含信息,也可以有子节点

查看当前节点包含的内容

ls /

创建节点信息

create /sys_conf hellozookeeper

获取节点信息

get /sys_conf

更新节点信息

set /sys_conf newhello

删除节点信息

delete /sys_conf

一致性&Leader选举机制

关于一致性

Zookeeper 是一种高性能、可扩展的服务。 Zookeeper 的读写速度非常快,并且读的速度要比写的速度更快。另外,在进行读操作的时候, ZooKeeper 依然能够为旧的数据提供服务。这些都是由于 ZooKeepe 所提供的一致性保证,它具有如下特点:

  • 顺序一致性

客户端的更新顺序与它们被发送的顺序相一致。

  • 原子性

更新操作要么成功要么失败,没有第三种结果。

  • 单系统镜像

无论客户端连接到哪一个服务器,客户端将看到相同的 ZooKeeper 视图。

  • 可靠性

一旦一个更新操作被应用,那么在客户端再次更新它之前,它的值将不会改变。。这个保证将会产生下面两种结果:

- 如果客户端成功地获得了正确的返回代码,那么说明更新已经成果。如果不能够获得返回代码(由于通信错误、超时等等),那么客户端将不知道更新操作是否生效。- 当从故障恢复的时候,任何客户端能够看到的执行成功的更新操作将不会被回滚。
  • 实时性

在特定的一段时间内,客户端看到的系统需要被保证是实时的(在十几秒的时间里)。在此时间段内,任何系统的改变将被客户端看到,或者被客户端侦测到。

给予这些一致性保证, ZooKeeper 更高级功能的设计与实现将会变得非常容易,例如: leader 选举、队列以及可撤销锁等机制的实现。

Leader选举机制

ZooKeeper 需要在所有的服务(可以理解为服务器)中选举出一个 Leader ,然后让这个 Leader 来负责管理集群。此时,集群中的其它服务器则成为此 Leader 的 Follower 。并且,当 Leader 故障的时候,需要 ZooKeeper 能够快速地在 Follower 中选举出下一个 Leader 。这就是 ZooKeeper 的 Leader 机制,下面我们将简单介绍在ZooKeeper 中, Leader 选举( Leader Election )是如何实现的。

核心思想

首先创建一个 EPHEMERAL 目录节点,例如“ /election ”。然后。每一个ZooKeeper 服务器在此目录下创建一个 SEQUENCE| EPHEMERAL 类型的节点,例如“ /election/n_ ”。在SEQUENCE 标志下, ZooKeeper 将自动地为每一个 ZooKeeper 服务器分配一个比前一个分配的序号要大的序号。此时创建节点的 ZooKeeper 服务器中拥有最小序号编号的服务器将成为 Leader 。

选举策略

当 Leader 服务器发生故障的时候,系统能够快速地选出下一个 ZooKeeper 服务器作为 Leader 。一个简单的解决方案是,让所有的 follower 监视 leader 所对应的节点。当 Leader 发生故障时, Leader 所对应的临时节点将会自动地被删除,此操作将会触发所有监视 Leader 的服务器的 watch 。这样这些服务器将会收到 Leader 故障的消息,并进而进行下一次的 Leader 选举操作。但是,这种操作将会导致“从众效应”的发生,尤其当集群中服务器众多并且带宽延迟比较大的时候,此种情况更为明显。

改进

在 Zookeeper 中,为了避免从众效应的发生,它是这样来实现的:每一个 follower 对 follower 集群中对应的比自己节点序号小一号的节点(也就是所有序号比自己小的节点中的序号最大的节点)设置一个 watch 。只有当follower 所设置的 watch 被触发的时候,它才进行 Leader 选举操作,一般情况下它将成为集群中的下一个 Leader。很明显,此 Leader 选举操作的速度是很快的。因为,每一次 Leader 选举几乎只涉及单个 follower 的操作。

总结

总算是对zookeeper有了比较直观的了解了。找到一篇靠谱的文章也不容易。

附录

本文不是原创,来源于zookeeper系列文章

0 0
原创粉丝点击