码迷,mamicode.com
首页 > 其他好文 > 详细

Zookeeper入门:基本概念、5项配置、启动

时间:2015-12-01 12:55:13      阅读:2265      评论:0      收藏:0      [点我收藏+]

标签:

起源


   最早接触Zookeeper,是在学习Hadoop权威指南这本书的时候,印象中是Hadoop项目的一个子工程。
   
   最近,项目中需要用到“分布式锁”。
   
   之前,在开发P2P网贷系统的时候,就用到了“分布式锁”,这个概念听起来挺高端的,实际就是多台机器下,同时运行项目下的“锁”。
 之前是用Redis实现“分布式锁”,但是周期性地出现了问题。只能是推测,程序异常退出,或者本地开发和测试环境用的一套Redis,
 本地线程定时任务,经常被强制关闭,锁没有成功释放。
 
   听Boss说,Memcache自带的就是分布式的锁,目前还没用过。
   据Boss说,2005年之前,实现分布式锁主要是用Memcache和Oracle。后来,出现了NoSQL的Redis,Oracle基本被MySQL取代,
“分布式锁”就成了个问题。至于其他人是怎么解决的,可能还是用了Memcache做缓存,也可能还有其它机智或者解决方案。


   探讨技术概念“分布式锁”,真正的实现,必须是要考虑“业务场景”的。
   单独的技术,很少有脱离业务场景的。
   
   后来Hadoop出现,有Zookeeper,不知什么时候起,用Zookeeper实现分布式锁的人就变多了。
   
   从哪里可以看出来呢?百度搜索“Zookeeper”,相关的文章多了,搜索Zookeeper+分布式锁的人变多了。
   
   看一个技术火不火,看看有多少人在学习,有多少人在总结相关的文章,就知道了。
   
Zookeeper基本介绍
 
   ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。
   它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。
ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper包含一个简单的原语集,[1]  提供Java和C的接口。
   ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-3.4.3\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。


   ZooKeeper是以Fast Paxos算法为基础的,paxos算法存在活锁的问题,即当有多个proposer交错提交时,有可能互相排斥导致没有一个proposer能提交成功,
   而Fast Paxos作了一些优化,通过选举产生一个leader,只有leader才能提交proposer,具体算法可见Fast Paxos。因此,要想弄懂ZooKeeper首先得对Fast Paxos有所了解。[3] 
ZooKeeper的基本运转流程:
1、选举Leader。
2、同步数据。
3、选举Leader过程中算法有很多,但要达到的选举标准是一致的。
4、Leader要具有最高的zxid。
5、集群中大多数的机器得到响应并follow选出的Leader。


官方网站
   http://zookeeper.apache.org/
   
Zookeeper启动
   实际项目开发中,用的是Linux版本的。
   #Zookeeper启动
./zkServer.sh start &
./zkCli.sh -server 127.0.0.1:2181 &
  没啥大问题


  自己学习,用的是Windows版本的。
  #Zookeeper启动
  cd /d E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin
  
  zkServer start &
  zkCli -server 127.0.0.1:2181 &


  E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin>zkServer.cmd start
系统找不到指定的路径。
Error: JAVA_HOME is incorrectly set.


E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin>call  "-Dzookeeper.log.dir=E:\M
ongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin\..\logs" "-Dzookeeper.root.logger=I
NFO,CONSOLE" "-Dzookeeper.log.file=zookeeper-Administrator-server-XIAOLEI.log" "
-XX:+HeapDumpOnOutOfMemoryError" "-XX:OnOutOfMemoryError=cmd /c taskkill /pid %%
p /t /f" -cp "E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin\..\build\classes;
E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin\..\build\lib\*;E:\Mongodb-Redis
-Nginx\zookeeper-3.5.1-alpha\bin\..\*;E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alp
ha\bin\..\lib\*;E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin\..\conf" org.ap
ache.zookeeper.server.quorum.QuorumPeerMain "E:\Mongodb-Redis-Nginx\zookeeper-3.
5.1-alpha\bin\..\conf\zoo.cfg" start
文件名、目录名或卷标语法不正确。


E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin>endlocal


#打印Java_HOME,明明已经配置好了,所以排除JAVA_HOME的原因
E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin>echo %JAVA_HOME%
C:\Program Files\Java\jdk1.7.0_17;
就算是把JAVA_HOME改为"C:\Program Files\Java\jdk1.7.0_17"还是不行。




网上搜了下,可能是JDK版本的问题,我用的是JDK1.7。
因此,我判断很可能是JDK和Zookeeper的版本匹配问题。


重新下载3.4.6版本的Zookeeper
  cd /d E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin
  zkServer start &
  
  E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin>zkServer.cmd start


E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin>java "-Dzookeeper.log.dir=E:\Mongodb-
Redis-Nginx\zookeeper-3.4.6\bin\.." "-Dzookeeper.root.logger=INFO,CONSOLE" -cp "
E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin\..\build\classes;E:\Mongodb-Redis-Ngi
nx\zookeeper-3.4.6\bin\..\build\lib\*;E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin
\..\*;E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin\..\lib\*;E:\Mongodb-Redis-Nginx
\zookeeper-3.4.6\bin\..\conf" org.apache.zookeeper.server.quorum.QuorumPeerMain
"E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin\..\conf\zoo.cfg" start
错误: 找不到或无法加载主类 org.apache.zookeeper.server.quorum.QuorumPeerMain


E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin>endlocal


配置zoo.cfg文件
在conf目录,复制zoo_sample.cfg,重名为zoo.cfg,重新启动


又报错了
E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin>zkServer.cmd start


E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin>java "-Dzookeeper.log.dir=E:\Mongodb-
Redis-Nginx\zookeeper-3.4.6\bin\.." "-Dzookeeper.root.logger=INFO,CONSOLE" -cp "
E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin\..\build\classes;E:\Mongodb-Redis-Ngi
nx\zookeeper-3.4.6\bin\..\build\lib\*;E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin
\..\*;E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin\..\lib\*;E:\Mongodb-Redis-Nginx
\zookeeper-3.4.6\bin\..\conf" org.apache.zookeeper.server.quorum.QuorumPeerMain
"E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin\..\conf\zoo.cfg" start
2015-12-01 10:14:27,347 [myid:] - INFO  [main:DatadirCleanupManager@78] - autopu
rge.snapRetainCount set to 3
2015-12-01 10:14:27,350 [myid:] - INFO  [main:DatadirCleanupManager@79] - autopu
rge.purgeInterval set to 0
2015-12-01 10:14:27,351 [myid:] - INFO  [main:DatadirCleanupManager@101] - Purge
 task is not scheduled.
2015-12-01 10:14:27,351 [myid:] - WARN  [main:QuorumPeerMain@113] - Either no co
nfig or no quorum defined in config, running  in standalone mode
2015-12-01 10:14:27,411 [myid:] - ERROR [main:ZooKeeperServerMain@54] - Invalid
arguments, exiting abnormally
java.lang.NumberFormatException: For input string: "E:\Mongodb-Redis-Nginx\zooke
eper-3.4.6\bin\..\conf\zoo.cfg"
        at java.lang.NumberFormatException.forInputString(Unknown Source)
        at java.lang.Integer.parseInt(Unknown Source)
        at java.lang.Integer.parseInt(Unknown Source)
        at org.apache.zookeeper.server.ServerConfig.parse(ServerConfig.java:60)
        at org.apache.zookeeper.server.ZooKeeperServerMain.initializeAndRun(ZooK
eeperServerMain.java:83)
        at org.apache.zookeeper.server.ZooKeeperServerMain.main(ZooKeeperServerM
ain.java:52)
        at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(Qu
orumPeerMain.java:116)
        at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain
.java:78)
2015-12-01 10:14:27,415 [myid:] - INFO  [main:ZooKeeperServerMain@55] - Usage: Z
ooKeeperServerMain configfile | port datadir [ticktime] [maxcnxns]
Usage: ZooKeeperServerMain configfile | port datadir [ticktime] [maxcnxns]


妈蛋啊,网上找了很多资料,没啥可用的。
后来,还是根据错误信息“windows zookeeper启动 java.lang.NumberFormatException”找到了1个答案。
zkServer.cmd 不要后面的“start”就正常启动了。


cd /d E:\Mongodb-Redis-Nginx\zookeeper-3.4.6\bin
zkCli.cmd -server 127.0.0.1:2181
通过艰难的几步,就正常启动了。


Zookeeper启动总结
1.实际项目用的是Linux,问题不大,本地开发学习用Windows,问题多多。
2.Zookeeper3.5.1-alpha,和本地JDK1.7,有冲突,无法正常启动。
3.Zookeeper启动,需要配置conf目录下的zoo.cfg。复制-粘贴-重命名一次就可以了。
4.Windows下启动,不需要带“start”参数,直接zkServer.cmd,真是够坑的。


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=C:/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.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# 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




dataDir和clientPort应该是必须的。

一点感想:逃避or面对
在Windows下遇到问题的时候,其实我非常想立即转到Linux下,就没有这么多屁事了。
但是,我一直意识到“人”比较喜欢逃避问题,就硬是忍着去正面解决了问题。
另外,是想把遇到的每一个问题都解决了,自己解决问题的能力,肯定是大幅度提高了。




参考资料
Zookeeper百度百科
http://baike.baidu.com/link?url=MsOQSGlqQA1BKF8v9OlB7k_jRi6lZm4fU9JeyP_pwA8yFa8mJopj3B7INfVVLRCIKkkEo2osXfBqnnSvuTq0p_


Zookeeper异常ConnectionLossException解决
http://www.sjsjw.com/kf_cloud/article/022572ABA018042.asp
E:\Mongodb-Redis-Nginx\zookeeper-3.5.1-alpha\bin


启动Zookeeper时抛出“Invalid arguments, exiting abnormally”错误信息
http://www.bug315.com/article/156.htm

Zookeeper入门:基本概念、5项配置、启动

标签:

原文地址:http://blog.csdn.net/fansunion/article/details/50126583

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!