一、ZooKeeper简介
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。ZooKeepe提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization)、命名服务(NamingService)、集群维护(Group Maintenance)等。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。ZooKeeper包含一个简单的原语集,提供Java和C的接口。ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-3.4.8\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。ZooKeeper本身可以以Standalone模式安装运行,不过它更强大之处在于通过分布式ZooKeeper集群(一个Leader和多个Follower),基于一定的策略来保证ZooKeeper集群的稳定性和可用性,从而实现分布式应用的可靠性。
二、ZooKeeper Standalone模式(ZooKeeper独立式)
首先我们从Apache官网下载ZooKeeper软件包,我们以版本3.4.8(zookeeper-3.4.8.tar.gz)为例子,单独一台服务器部署非常简单,只需要解压缩后,简单配置一下即可以启动ZooKeeper服务器进程。
将zookeeper-3.4.8/conf目录下面的zoo_sample.cfg修改为zoo.cfg,配置文件内容如下所示:
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/usr/local/zookeeper-3.4.8/conf
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
各个参数的含义上边都有注释,大家可以理解下。
下面启动ZooKeeper服务器进程:
cd /usr/local/zookeeper-3.4.8/bin
zkServer.shstart
通过jps命令可以查看ZooKeeper服务器进程,名称为QuorumPeerMain。
在客户端连接ZooKeeper服务器,命令如下:
zkCli.sh-server kinder:2181
上面kinder为主机名,如果在本机执行,则可执行如下命令:
zkCli.sh
可查看客户端连接信息。
可使用help查看Zookeeper客户端的基本操作命令。
三、ZooKeeper Distributed模式(ZooKeeper分布式)
ZooKeeper的分布式部署也称集群部署,也相对的简单。
ZooKeeper集群是一个独立的分布式协调服务集群,“独立”的含义就是说,如果想使用ZooKeeper实现分布式应用的协调与管理,简化协调与管理,任何分布式应用都可以使用,这就要归功于Zookeeper的数据模型(DataModel)和层次命名空间(HierarchicalNamespace)结构。详细可以参考:
http:///doc/trunk/zookeeperOver.html
在设计分布式应用协调服务时,首要的就是考虑如何组织层次命名空间。
下面说明分布式模式的安装配置,过程如下所示:
第一步:主机名称到IP地址映射配置
ZooKeeper集群中具有两个关键的角色:Leader和Follower。集群中所有的结点作为一个整体对分布式应用提供服务,集群中每个结点之间都互相连接,所以,在配置的ZooKeeper集群的时候,每一个结点的host到IP地址的映射都要配置上集群中其它结点的映射信息。
例如,ZooKeeper集群中每个结点的配置,以zoo1为例,/etc/hosts内容如下所示:
192.168.1.111 zoo1
192.168.1.112 zoo2
192.168.1.113 zoo3
192.168.1.114 zoo4
192.168.1.115 zoo5
ZooKeeper采用一种称为Leaderelection的选举算法。在整个集群运行过程中,只有一个Leader,其他的都是Follower,如果ZooKeeper集群在运行过程中Leader出了问题,系统会采用该算法重新选出一个Leader。因此,各个结点之间要能够保证互相连接,必须配置上述映射。
ZooKeeper集群启动的时候,会首先选出一个Leader,在Leaderelection过程中,某一个满足选举算的结点就能成为Leader。整个集群的架构可以参考:
http:///doc/trunk/zookeeperOver.html#sc_designGoals
第二步:修改ZooKeeper配置文件
先在一台机器zoo1上,解压缩zookeeper-3.4.8.tar.gz,修改配置文件conf/zoo.cfg,内容如下所示:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/zookeeper-3.4.8/conf
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
server.4=zoo4:2888:3888
server.5=zoo5:2888:3888
clientPort=2181
第三步:远程复制分发安装文件
上面已经在一台机器zoo1上配置完成ZooKeeper,现在可以将该配置好的安装文件远程拷贝到集群中的各个结点对应的目录下:
cd /usr/local
scp -rzookeeper-3.4.8/ root@zoo2:/usr/local/
scp -rzookeeper-3.4.8/ root@zoo3:/usr/local/
scp -rzookeeper-3.4.8/ root@zoo4:/usr/local/
scp -rzookeeper-3.4.8/ root@zoo5:/usr/local/
第四步:设置myid
在我们配置的dataDir指定的目录下面,创建一个myid文件,里面内容为一个数字,用来标识当前主机,conf/zoo.cfg文件中配置的server.X中X为什么数字,则myid文件中的内容就是什么数字。比如zoo1中myid内容为1,zoo2中myid内容为2 …
第五步:启动ZooKeeper集群
在ZooKeeper集群的每个结点上,执行启动ZooKeeper服务的脚本:
cd /usr/local/zookeeper-3.4.8/bin
zkServer.shstart
启动后可查看zookeeper.out的日志。
启动的顺序是zoo1> zoo2>zoo3> zoo4> zoo5,由于ZooKeeper集群启动的时候,每个结点都试图去连接集群中的其它结点,除了zoo5能连接所有节点,其它的都存在启动时后边的节点还没启动,所以会出现异常的日志,这是正常的。启动选出一个Leader后,最后稳定了。
第六步:安装验证
可以通过ZooKeeper的脚本来查看启动状态,包括集群中各个结点的角色(或是Leader,或是Follower),如下所示,是在ZooKeeper集群中的每个结点上查询的结果:
cd /usr/local/zookeeper-3.4.8/bin
zkServer.shstatus
会得到以下内容:
1个Mode:leader
4个Mode:follower
通过上面状态查询结果可见,zoo1是集群的Leader,其余4个的结点是Follower。
另外,可以通过客户端脚本,连接到ZooKeeper集群上。对于客户端来说,ZooKeeper是一个整体(ensemble),连接到ZooKeeper集群实际上感觉在独享整个集群的服务,所以,你可以在任何一个结点上建立到服务集群的连接。
四、补充说明
主机名映射的ip与必须与实际配置的一致,集群中各个结点之间才能正常建立链路,整个ZooKeeper集群启动才能成功。修改每个结点的/etc/hosts文件,将ZooKeeper集群中所有结点主机名到IP地址的映射配置上。