zookeeper单机模式实现分布式,开发部署测试模式机器有限情况

ZooKeeper的部署和测试

背景

zookeeper是一个开源的分布式应用程序协调服务,是Apache Hadoop 的一个子项目。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。其原理是基于google发表的《The Chubby lock service for loosely-coupled distributed systems》论文。网上关于zookeeper的博客也很多,但很多讲的不细致,如如何测试部署成功。在学习别人的博客进行部署的过程中遇到了一些问题。所以写这篇博客主要是总结zookeeper的部署方法及在这过程中遇到的问题,提供更加详细的部署方案,希望能为其他初学者提供一些参考。

所需境和包

1. JDK 环境

java JDK包可以到官网下载(这里提供所有版本的JDK下载地址:http://www.oracle.com/technetwork/java/archive-139210.html) 
JDK安装可参考: 
tar.gz方式:http://blog.csdn.net/zhangxh1013/article/details/7320860 
rpm方式: http://alan-hjkl.iteye.com/blog/1527179

JDK 环境是必须的,zookeeper是用java开发的,所以需要在JDK环境下运行。所以建议首先安装JDK,本人就是因为以为自己电脑上已经安装JDK,就直接部署zookeeper,在测试时并不成功,结果各种排错。

2. zookeeper 包:

下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/

单机部

1.创建工作目录

mkdir /usr/lib/zookeeper

  • 1

2.创建data,logs文件

data :下存放节点ID  
logs:用于下存放相关日志文件

mkdir/usr/lib/zookeeper/data

mkdir/usr/lib/zookeeper/logs

  • 1
  • 2

3.zookeeper到工作目

下载zookeeper的安装包之后, 解压到工作目录下(本文解压到/usr/lib/zookeeper).

tar -zxvf zookeeper-3.4.6.tar.gz/usr/lib/zookeeper

  • 1

4.创建zoo.cfg

进入zookeeper目录下的conf子目录, 复制zoo_sample.cfg 并命名为zoo.cfg。

zookeeper服务器启动默认加载zoo.cfg文件,当然也可以命名为其他文件,但是在运行是需要指定cfg文件名。如命名为zk1.cfg时,启动zookeeper命令为:./zkServer.sh start zk1.cfg 。如果是zoo.cfg 启动时命令为:./zkServer.sh start

打开zoo.cfg 并修改相关配置

sudovi /usr/lib/zookeeper/zookeeper-3.4.6/conf/zoo.cfg

  • 1

设置配置文件中的相关参数:

tickTime=2000

initLimit=10   

syncLimit=5  

dataDir=/usr/lib/zookeeper/data   

dataLogDir=/usr/lib/zookeeper/logs    

clientPort=2181   

参数说明:

  • tickTime: zookeeper中使用的基本时间单位, 毫秒值
  • initLimit Follower在启动过程中,会从Leader同步所有最新数据,然后确定自己能够对外服务的起始状态。Leader允许Follower在initLimit时间内完成这个工作
  • syncLimit在运行过程中,Leader负责与ZK集群中所有机器进行通信,如果L发出心跳包在syncLimit之后,还没有从F那里收到响应,那么就认为这个F已经不在线了。
  • dataDir: 数据目录. 可以是任意目录.本文制定/usr/lib/zookeeper/data 
  • dataLogDir: log目录, 同样可以是任意目录. 如果没有设置该参数, 将使用和dataDir相同的设置.
  • clientPort: 监听client连接的端口号

更多参数信息参考:http://www.cnblogs.com/ggjucheng/p/3352591.html

在某些博客中还会涉及设置环境变量这一步。 
在/etc/profile 文件中加入如下的内容:

#Set ZooKeeper Enviroment

exportZOOKEEPER_HOME=/usr/lib/zookeeper/zookeeper-3.4.6/

exportPATH=$PATH:$ZOOKEEPER_HOME/bin:$ZOOKEEPER_HOME/conf

但我经过尝试后发现,其实并不需要进行环境的设置就可以部署成功。单机部署就到此完成了,接下来就是验证下是否部署成功了。

测试

这一步就是检验之前所部署的zookeeper是否能够成功运行。

1.

首先进入到zookeeper-3.4.6的bin文件夹下,再启动zkServer.sh

 cd/usr/lib/zookeeper/zookeeper-3.4.6/bin

./zkServer.sh start

 /usr/lib/zookeeper/zookeeper-3.4.6/bin/zkServer.shstart

运行结果:

root@jaylon:/usr/lib/zookeeper/zookeeper-3.4.6/bin# ./zkServer.sh start

JMXenabled by default

Usingconfig:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../conf/zoo.cfg

Startingzookeeper ... STARTED.

root@jaylon:/usr/lib/zookeeper/zookeeper-3.4.6/bin# 

这里需要注意的是启动时命令为./zkServer.sh start。如果是启动zkServer.sh start的话会报错找不到命令错误。这点初学者需要小心。

2.检查运行状态

通过./zkServer.sh status来检查服务器运行状态

root@jaylon:/usr/lib/zookeeper/zookeeper-3.4.6/bin# ./zkServer.sh status

JMXenabled by default

Usingconfig:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../conf/zoo.cfg

Mode:standalone

root@jaylon:/usr/lib/zookeeper/zookeeper-3.4.6/bin# 

Mode:standalone 表明当前是单机模式,也表明部署成功。如果出现下面的情况说明部署不成功:

root@jaylon:/usr/lib/zookeeper/zookeeper-3.4.6/bin# ./zkServer.sh status

JMXenabled by default

Usingconfig:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../conf/zoo.cfg

Errorcontacting service. Itis probablynotrunning.

root@jaylon:/usr/lib/zookeeper/zookeeper-3.4.6/bin# 

如果出现这种情况检查以下几个方面: 
1.JDK环境是否搭建好 
2.检查zoo.cfg中的dataDir,dataLogDir路径是否有错误

3.

如果确认没错的话,便可启动客户端进行交互测试。 
运行bin下的zkCli.sh 文件, 
具体指令:./zkCli.sh -server localhost:2181 
localhost 表示指向本地地址(服务器地址) 
2181 即是在配置文件zoo.cfg 中设置的clientPort端口号 
意思是要建立与地址为localhost,端口号为2181的服务进行通信。如果运行该指令显示的结果如下,说明以及链接成功(即光标停止不动或最后一行显示[zk: localhost:2181(CONNECTED) 0] )

root@jaylon:/usr/lib/zookeeper/zookeeper-3.4.6/bin# ./zkCli.sh -server localhost:2181

Connecting tolocalhost:2181

2015-08-0709:39:06,957[myid:] - INFO  [main:Environment@100] - Client environment:zookeeper.version=3.4.6-1569965, built on02/20/201409:09GMT

2015-08-0709:39:06,961[myid:] - INFO  [main:Environment@100] - Client environment:host.name=jaylon

2015-08-0709:39:06,961[myid:] - INFO  [main:Environment@100] - Client environment:java.version=1.7.0_80

2015-08-0709:39:06,965[myid:] - INFO  [main:Environment@100] - Client environment:java.vendor=Oracle Corporation

2015-08-0709:39:06,965[myid:] - INFO  [main:Environment@100] - Client environment:java.home=/usr/java/jdk1.7.0_80/jre

2015-08-0709:39:06,965[myid:] - INFO  [main:Environment@100] - Client environment:java.class.path=/usr/lib/zookeeper/zookeeper-3.4.6/bin/../build/classes:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../build/lib/*.jar:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../lib/slf4j-log4j12-1.6.1.jar:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../lib/slf4j-api-1.6.1.jar:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../lib/netty-3.7.0.Final.jar:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../lib/log4j-1.2.16.jar:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../lib/jline-0.9.94.jar:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../zookeeper-3.4.6.jar:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../src/java/lib/*.jar:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../conf:

2015-08-0709:39:06,966[myid:] - INFO  [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/i386:/lib:/usr/lib

2015-08-0709:39:06,966[myid:] - INFO  [main:Environment@100] - Client environment:java.io.tmpdir=/tmp

2015-08-0709:39:06,966[myid:] - INFO  [main:Environment@100] - Client environment:java.compiler=<NA>

2015-08-0709:39:06,967[myid:] - INFO  [main:Environment@100] - Client environment:os.name=Linux

2015-08-0709:39:06,967[myid:] - INFO  [main:Environment@100] - Client environment:os.arch=i386

2015-08-0709:39:06,967[myid:] - INFO  [main:Environment@100] - Client environment:os.version=3.13.0-32-generic

2015-08-0709:39:06,968[myid:] - INFO  [main:Environment@100] - Client environment:user.name=root

2015-08-0709:39:06,968[myid:] - INFO  [main:Environment@100] - Client environment:user.home=/root

2015-08-0709:39:06,968[myid:] - INFO  [main:Environment@100] - Client environment:user.dir=/usr/lib/zookeeper/zookeeper-3.4.6/bin

2015-08-0709:39:06,972[myid:] - INFO  [main:ZooKeeper@438] - Initiating client connection, connectString=localhost:2181sessionTimeout=30000watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@e01430

Welcome toZooKeeper!

2015-08-0709:39:07,015[myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@975] - Opening socket connection toserver localhost/127.0.0.1:2181.Will notattempt toauthenticate usingSASL (unknown error)

JLine support isenabled

2015-08-0709:39:07,034[myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@852] - Socket connection established tolocalhost/127.0.0.1:2181, initiating session

[zk: localhost:2181(CONNECTING)0] 2015-08-0709:39:07,065[myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1235] - Session establishment complete onserver localhost/127.0.0.1:2181, sessionid = 0x14f05cde0f10001, negotiated timeout = 30000

 

WATCHER::

 

WatchedEvent state:SyncConnected type:None path:null

进行通

现在进行客户端与服务端的通信,该步在3步基础上进行。在命令行输入help 会显示一些常用的通信指令:

[zk: localhost:2181(CONNECTED) 0] help

ZooKeeper -server host:port cmd args

   connect host:port

   getpath [watch]

   ls path [watch]

   setpath 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

[zk: localhost:2181(CONNECTED) 1]

查看文件列表:

[zk: localhost:2181(CONNECTED) 1] ls/

[zookeeper]

新建文件:

[zk: localhost:2181(CONNECTED) 4] create/node node

Created /node

获取文件:

[zk: localhost:2181(CONNECTED) 5] get /node

node

cZxid= 0x100000008

ctime= Fri Aug 07 09:51:40 CST 2015

mZxid= 0x100000008

mtime= Fri Aug 07 09:51:40 CST 2015

pZxid= 0x100000008

cversion= 0

dataVersion= 0

aclVersion= 0

ephemeralOwner= 0x0

dataLength= 4

numChildren= 0

其他操作可以查看help。到这里已经完成了单机下的部署与测试了。接下就是要关闭服务。

5.

操作完成记得关闭服务,不然端口一直被占用。在没有关闭服务的情况下再重启开启则会显示该服务正在运行。关闭代码如下:

root@jaylon:/usr/lib/zookeeper/zookeeper-3.4.6/bin# ./zkServer.sh stop

JMXenabled by default

Usingconfig:/usr/lib/zookeeper/zookeeper-3.4.6/bin/../conf/zoo.cfg

Stoppingzookeeper ... STOPPED

伪集群模式部

简单的说伪集群是指在单台机器中启动多个zookeeper进程, 并组成一个集群来模拟多台机器上的集群操作. 本文以启动3个zookeeper进程(节点)为例.

节点个数最好是奇数个,zookeeper集群是以宕机个数过半才会让整个集群宕机的,所以奇数个集群更佳。你可以设置3,5,7 个,原理上说节点越多越稳定。

1.创建虚拟节

在本地建立三个节点,即三个文件夹来存放不同的节点配置

mkdir /usr/lib/zk/

mkdir /usr/lib/zk/server1

mkdir /usr/lib/zk/server2

mkdir /usr/lib/zk/server3

并在每个节点文件夹下建立data,logs文件夹,类似单机模式。将zookeeper软件包分别解压到三文件夹下(server1,server2,server3)。和单模式下一样,在每个节点的zookeeper-3.4.6/conf下创建zoo.cfg 。做法与单机模式一样。

2.配置不同点的zoo.cfg

现在有3个节点,有三个配置文件(zoo.cfg)。所以需要对三个配置文件分别进行配置。

节点1 
/usr/lib/zk/server1/zookeeper-3.4.6/conf/zoo.cfg

tickTime=2000

initLimit=10   

syncLimit=5  

dataDir=/usr/lib/zk/server1/data    #注意这边路劲的不同

dataLogDir=/usr/lib/zk/server1/logs #注意这边路劲的不同

clientPort=2181  #端口号每个节点不同

 

server.1=127.0.0.1:2888:3888

server.2=127.0.0.1:2889:3889

server.3=127.0.0.1:2890:3890

与单机模式不同的是底下加入了三行配置:

server.服务号=服务地址:服务端口:通信端口

  • 1

服务号:为每个节点分配对应的id 
服务地址:服务所在地址,因为现在用的是单机所以地址都是本地 
服务端口:和clientPort端口是不同的 
在设置过程中服务端口和通信端口应该不同,每个节点的服务端口和通信端口也不同,以防止端口冲突。 
其他文件节点zoo.cfg配置基本一样,不同的在于dataDir,dataLogDir和clientPort

节点2 
/usr/lib/zk/server2/zookeeper-3.4.6/conf/zoo.cfg

tickTime=2000

initLimit=10   

syncLimit=5  

dataDir=/usr/lib/zk/server2/data    #注意这边路劲的不同server2

dataLogDir=/usr/lib/zk/server2/logs #注意这边路劲的不同server2

clientPort=2182  #端口号每个节点不同2182

 

server.1=127.0.0.1:2888:3888

server.2=127.0.0.1:2889:3889

server.3=127.0.0.1:2890:3890

节点3 
/usr/lib/zk/server3/zookeeper-3.4.6/conf/zoo.cfg

tickTime=2000

initLimit=10   

syncLimit=5  

dataDir=/usr/lib/zk/server3/data    #注意这边路劲的不同server3

dataLogDir=/usr/lib/zk/server3/logs #注意这边路劲的不同server3

clientPort=2183  #端口号每个节点不同2183

 

server.1=127.0.0.1:2888:3888

server.2=127.0.0.1:2889:3889

server.3=127.0.0.1:2890:3890

3.配置不同点上的myid

在每个节点的data文件夹下分别创建myid文件(没有后缀)。并在每个myid文件里只写上该节点的id如: 
server1/data/myid 里写1 
server2/data/myid 里写2 
server3/data/myid 里写3

4. 

与单机模式不同,集群模式需要同时启动所有节点上的服务 
建议在/root 下建立一个start.sh 文件到时只需要启动该文件则可以将三个服务同时启动,则不用分别进入每个文件夹下启动zkServer.sh 。 
start.sh 文件内容如下:

/usr/lib/zk/server1/zookeeper-3.4.6/bin/zkServer.shstart

/usr/lib/zk/server2/zookeeper-3.4.6/bin/zkServer.shstart

/usr/lib/zk/server3/zookeeper-3.4.6/bin/zkServer.shstart

启动服务:

root@jaylon:~# gedit start.sh

root@jaylon:~# ./start.sh 

JMX enabled by default

Using config: /usr/lib/zk/server1/zookeeper/bin/../conf/zoo.cfg

Starting zookeeper ...STARTED

JMX enabled by default

Using config: /usr/lib/zk/server2/zookeeper/bin/../conf/zoo.cfg

Starting zookeeper ...STARTED

JMX enabled by default

Using config: /usr/lib/zk/server3/zookeeper/bin/../conf/zoo.cfg

Starting zookeeper ...STARTED

5.测试 

检查服务是否正常启动。我们可以写一个指令文件status.sh 内容如下(和start.sh 不同的在于将start改成status):

/usr/lib/zk/server1/zookeeper-3.4.6/bin/zkServer.sh status

/usr/lib/zk/server2/zookeeper-3.4.6/bin/zkServer.sh status

/usr/lib/zk/server3/zookeeper-3.4.6/bin/zkServer.sh status

启动检查:

root@jaylon-Lenovo-G460:~# ./status.sh 

JMX enabled bydefault

Usingconfig: /usr/lib/zk/server1/zookeeper/bin/../conf/zoo.cfg

Mode: leader

JMX enabled bydefault

Usingconfig: /usr/lib/zk/server2/zookeeper/bin/../conf/zoo.cfg

Mode: follower

JMX enabled bydefault

Usingconfig: /usr/lib/zk/server3/zookeeper/bin/../conf/zoo.cfg

Mode: follower

从mode中可以看到每个节点的状态。节点1 是leader 其他两个节点是follower。 

ZooKeeper需要在所有的服务(可以理解为服务器)中选举出一个Leader,然后让这个Leader来负责管理集群。此时,集群中的其它服务器则成为此Leader的Follower。并且,当Leader故障的时候,需要ZooKeeper能够快速地在Follower中选举出下一个Leader 

6.通信

从任意节点下启动一个客户端链接任意节点的服务端口。 
如启动节点3的客户端链接节点2的服务:

cd/usr/lib/zk/server3/zookeeper-3.4.6/bin

./zkCli.sh -server localhost:2182

链接成功后的通信与链接失败的问题解决也可以参考单机模式。

7.

root@jaylon:/usr/lib/zk/server1/zookeeper-3.4.6/bin/zkServer.sh stop

root@jaylon:/usr/lib/zk/server2/zookeeper-3.4.6/bin/zkServer.sh stop

root@jaylon:/usr/lib/zk/server3/zookeeper-3.4.6/bin/zkServer.sh stop

问题总结

安装过程中常遇到的问题就是部署完如何检验部署成功,这也是很多博文没有提供的。另外就是部署不成功,问题如何解决。以下总结自己遇到的问题,及觉得容易忽略的问题:

  • JDK没有安装好就启动了zookeeper服务
  • 配置文件zoo.cfg 中的路径写错了,与具体文件没对应上
  • 每个节点的clientPort 设置相同了
  • 每个节点的myid文件的内容是否和对应节点id一样
  • zoo.cfg 的服务端口和通信端口设置是否正确,端口是否被占用

参考

http://coolxing.iteye.com/blog/1871009 
http://blog.chinaunix.net/uid-20498361-id-3184380.html 
http://blog.csdn.net/cuiran/article/details/8509429

另一种集群配置方式:http://blog.fens.me/hadoop-zookeeper-intro/ 

原文地址:https://www.cnblogs.com/SunshineKimi/p/12931517.html