1、概述
8月份的第一周,忙得晕头转向,为了解决OSGI-Felix 下 hibernate JPA的ClassLoader问题,就耽误了至少两天时间,还好在周五系统成功在servicemix上运行了。已经几天时间没有碰博客了,刚好下周有安排给实验室的几个大神讨论zookeeper相关技术。
我这么一想,咦~~刚好这周末准备PPT的时候,还不如就预先做几篇关于zookeeper的文章,这样既可以两件工作合成一件,又可以在介绍枯燥的负载均衡层的时候,提前给大家透露一些更精彩的技术内容,权当是为以后hadoop生态系统的讲解预热吧。
话转正题,介绍zookeeper的文章,我将分成三个部分,第一篇文章我们讲解zookeeper的两种安装方式包括一些基本的;第二篇文章我们讲解zookeeper的核心原理,包括选举算法和事件机制;第三篇文章我们做一些编码实例,实际讲解zookeeper的使用场景。这样希望大家可以学以致用。
哦,还要说明一下,包括LVS+Keepalived+Nginx配置在内的最后两篇负载均衡层的文章不会水了大家。只是延迟一周左右退出,要知道小弟我也要优先完成公司的的任务啊,毕竟要吃一口饭。哈哈。
2、zookeeper是什么
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop的重要组件,CDH版本中更是使用它进行Namenode的协调控制。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。
ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
好吧,我“百度”的,怎样?不服就飞成都约我吃饭,^_^。说得那么抽象,zookeeper到底能为我们的分布式系统做什么事情呢:
- 管理系统中独特的/统一的信息:
一个分布式系统的各节点可能需要一个规范的、各节点的唯一的命名(例如节点名、CPU编号等),ZK可以实现这个的应用场景。
各个节点也会有一致的信息,例如每个节点的主配置信息。为了管理方便,新加入的节点也需要快速同步这些信息。使用ZK可以方便的做到。
- 集群状态监控和通知:
分布式系统中的每个节点需要知道整个系统的状态、知道系统中每个节点的状态:当有新节点加入时它需要知道、当有节点出现故障时它需要知道、当有节点退出时它需要知道。ZK就是这样一个“通知工具”。
- 协调资源抢占(锁):
当分布式系统的多个节点试图同时抢占唯一资源时(例如同时写入一个文件),就需要对这个唯一资源的使用进行协调。这是ZK的“协调者”功能。
- 分派计算任务:
如何协调1000个需要同时处理的任务到分布式系统的13个节点?如何保证执行失败的任务能被重新执行?如何在某个节点崩溃的情况下,接管其正在处理的任务?
在了解了zookeeper的工作原理后,也许您还可以发现zookeeper的更多使用场景。我们也会在介绍zookeeper的第三篇文章中,用实际编写代码的方式向各位读者演示zookeeper如何实现以上各种工作任务的。
3、单点模式的安装
下面我们就来实际安装zookeeper。首先我们进行单服务器的zookeeper安装,让zookeeper跑起来。成功后,我们再进行扩展,在多台(三台)服务器上进行zookeeper的安装,并让其作为一个整体,运行起来。
3.1、准备工作
我们将在IP:192.168.61.130的机器上安装zookeeper,您至少需要准备:
1、JDK1.7.X版本,根据您自己的实际情况选择32位系统或者63位系统。下载地址为:http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html
2、zookeeper,我下载的是zookeeper-3.4.6版本,您可以访问zookeeper官网,下载稳定版本:http://www.apache.org/dyn/closer.cgi/zookeeper/
JDK的安装这里用几句话描述就行了,但是一定记得设置PATH,classpath,JAVA_HOME环境变量:
tar -zxvf ./jdk-7u71-linux-x64.tar.gz
我将设置JDK的路径为:/usr/jdk1.7.0_71
mv ./jdk1.7.0_71 /usr/jdk1.7.0_71/
记得设置环境变量(全局配置文件为:/etc/profile):
vim /etc/profile
粘贴以下脚本到文件:
export PATH=/usr/jdk1.7.0_71/bin:$PATH
export classpath=/usr/jdk1.7.0_71/lib
export JAVA_HOME=/usr/jdk1.7.0_71
记得保存文件哈。然后重新加载操作系统用户的环境信息:
su - root
完成准备工作后,运行一下java命令,验证准备工作是正确的(如果出现了一些java的帮助信息,说明java命令运行成功了)。
3.2、正式安装(配置项讲解)
zookeeper的目录我是放置在/usr/zookeeper-3.4.6/这个位置,所以:
tar -zxvf ./zookeeper-3.4.6.tar.gz
mv ./zookeeper-3.4.6 /usr/zookeeper-3.4.6/
同样的,设置全局环境变量:
export PATH=/usr/zookeeper-3.4.6/bin:$PATH
好的,安装完成了,是不是简单。接下来,我们讲解一下zookeeper的主配置文件。zookeeper的主配置文件所在的地址是:${您的zookeeper安装位置}/conf/zoo.cfg
但是,解压后的zookeeper并没有这个配置文件,有一个名叫zoo_sample.cfg,所以,我们复制一个zoo.cfg文件:
cp /usr/zookeeper-3.4.6/conf/zoo_sample.cfg /usr/zookeeper-3.4.6/conf/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=/tmp/zookeeper
# 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
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# The number of snapshots to retain in dataDir
# autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
# autopurge.purgeInterval=1
- tickTime:这个属性我们将在讲解zookeeper的选举机制时进行着重说明。
- dataDir:zookeeper的工作目录,注释写得很清楚,只有测试环境才使用tmp目录,否则都建议进行专门的设置。
- clientPort:客户端的连接端口
- maxClientCnxns:客户端最大连接数
最后,使用zkServer.sh start命令,启动zookeeper:
[root@vm2 ~]# zkServer.sh start
JMX enabled by default
Using config: /usr/zookeeper-3.4.6/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
之后可以使用zkServer.sh status查看zookeeper的工作状态:
[root@vm2 ~]# zkServer.sh status
JMX enabled by default
Using config: /usr/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: standalone
使用jps命令也可以查看:
[root@vm2 ~]# jps
28172 Jps
14639 QuorumPeerMain
QuorumPeerMain这个进程就是zookeeper的进程。至此,zookeeper的单节点安装就成功了。
4、集群模式下的安装
4.1、准备工作
我们将在以下三台机器上安装并采用集群方式运行zookeeper:
- 192.168.61.129
- 192.168.61.130
- 192.168.61.131
安装JDK,设置华景变量,解压并防止zookeeper,这些步骤就都不说了,请参见上文中的设置。以下是我的建议:
所有节点的JDK安装路径,zookeeper的安装路径和环境变量的设置都完全一样,这样不会配着配着就把自己脑袋配晕(特别是如果您是第一次进行zookeeper的配置)
在正式环境中,我们不会使用root用户进行zookeeper的运行。所以您最好在测试环境的时候创建一个用户,例如名字叫做zookeeper的用户。
正式换进下我们一般也不会关闭防火墙。但是为了保证在测试环境下熟悉相关的配置,我建议您关闭防火墙。(如果开启防火墙的话,请打开2181、2888、3888这几个端口)
我们先创建几个文件夹,注意文件夹的权限要为您当前的用户打开(如果是root用户,就不需要关心这个问题)。等一下配置过程中,我们会用到这些文件夹。
创建zookeeper工作目录:
mkdir -p /usr/zookeeperdata/
mkdir -p /usr/zookeeperdata/data
创建zookeeper日志目录:
mkdir -p /usr/zookeeperdata/log
到此,准备工作结束。
4.2、正式安装(配置项讲解)
如果您是按照我的建议进行的准备工作,那么到这里,您三台机器的目录结构、环境变量、执行用户都应该是完全一致的。这里您只需要配置其中的一台,然后将配置文件scp到另外两台,就可以完成配置了。
以下是其中一台的配置信息:
# 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/zookeeperdata/data
dataLogDir=/usr/zookeeperdata/log
# 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
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.1=192.168.61.129:2888:3888
server.2=192.168.61.130:2888:3888
server.3=192.168.61.131:2888:3888
请注意变化的信息:
我们重新设置了zookeeper的工作目录和日志目录:
dataDir=/usr/zookeeperdata/data
dataLogDir=/usr/zookeeperdata/log
我们指定了整个zookeeper集群的server编号、地址和端口:
server.1=192.168.61.129:2888:3888
server.2=192.168.61.130:2888:3888
server.3=192.168.61.131:2888:3888
========================华丽的分割线====================
完成后我们将其中配置文件拷贝到另外两台机器上:
scp /usr/zookeeper-3.4.6/conf/zoo.cfg root@192.168.61.129:/usr/zookeeper-3.4.6/conf/zoo.cfg
scp /usr/zookeeper-3.4.6/conf/zoo.cfg root@192.168.61.131:/usr/zookeeper-3.4.6/conf/zoo.cfg
现在最重要的一个步骤到了。还记得我们在配置文件中给出的server列表都有一个编号吗?我们需要为这三个节点创建对应的编号文件,在/usr/zookeeperdata/data/myid文件中。如下:
server.1=192.168.61.129:2888:3888,所以在129这台机器上执行:
echo 1 > /usr/zookeeperdata/data/myid
server.2=192.168.61.130:2888:3888,所以在130这台机器上执行:
echo 2 > /usr/zookeeperdata/data/myid
server.3=192.168.61.131:2888:3888,所以在131这台机器上执行:
echo 3 > /usr/zookeeperdata/data/myid
至此,大功告成,我们准备开始启动了。分别在三台机器上执行(注意,执行部分先后):
zkServer.sh start
出现的结果如下(可能您的结果状态和我的会不一样)
129:
zkServer.sh status
JMX enabled by default
Using config: /usr/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: follower
130:
zkServer.sh status
JMX enabled by default
Using config: /usr/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: leader
131:
zkServer.sh status
JMX enabled by default
Using config: /usr/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: follower
在一个zookeeper集群集群中,始终有一个节点会通过集群所有节点参与的选举被推举为“leader”节点。其他节点就是“follower”节点。具体的原理,我们会在下篇文章进行详细的阐述。
5、简要命令和结构说明
本小结,我们简单说明一下zookeeper的数据存储结构,算是为下一篇文章介绍zookeeper中几个重要的原理打打基础。
5.1、zookeeper的存储结构
zookeeper中的数据是按照“树”结构进行存储的。而且znode节点还分为4中不同的类型。如下:
PERSISTENT-持久化节点:创建这个节点的客户端在与zookeeper服务的连接断开后,这个节点也不会被删除(除非您使用API强制删除)。
PERSISTENT_SEQUENTIAL-持久化顺序编号节点:当客户端请求创建这个节点A后,zookeeper会根据parent-znode的zxid状态,为这个A节点编写一个全目录唯一的编号(这个编号只会一直增长)。当客户端与zookeeper服务的连接断开后,这个节点也不会被删除。
EPHEMERAL-临时znode节点:创建这个节点的客户端在与zookeeper服务的连接断开后,这个节点就会被删除。
EPHEMERAL_SEQUENTIAL-临时顺序编号znode节点:当客户端请求创建这个节点A后,zookeeper会根据parent-znode的zxid状态,为这个A节点编写一个全目录唯一的编号(这个编号只会一直增长)。当创建这个节点的客户端与zookeeper服务的连接断开后,这个节点被删除
5.2、运行zkCli.sh命令
我们可以使用zkCli.sh命令,登录到一个zookeeper节点(不一定是leader节点),并通过命令行操作zookeeper的数据结构。
[root@vm2 ~]# zkCli.sh
Connecting to localhost:2181
2015-08-08 08:18:15,181 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT
2015-08-08 08:18:15,193 [myid:] - INFO [main:Environment@100] - Client environment:host.name=vm2
。。。
。。。
[zk: localhost:2181(CONNECTED) 0]
通过ls命令,可以查看zookeeper集群当前的数据结构:
[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper]
当然,您还可以更多的命令:
connect host:port
get path [watch]
ls path [watch]
set path data [version]
rmr path
delquota [-n|-b] path
quit
printwatches on|off
create [-s] [-e] path data acl
stat path [watch]
close
ls2 path [watch]
history
listquota path
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
setquota -n|-b val path
6、后文介绍
下一篇文章,我们将按照新的计划,介绍zookeeper中的几个关键原理。包括选举策略,事件机制等。稍等片刻,马上回来!