zookeeper简介

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的性能包含:配置保护、名字服务、分布式同步、组服务等。
ZooKeeper的指标就是封装好简单易出错的要害服务,将简略易用的接口和性能高效、性能稳固的零碎提供给用户。
ZooKeeper蕴含一个简略的原语集,提供Java和C的接口。ZooKeeper源代码中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-x.x.x\src\recipes。其中散布锁和队列有Java和C两个版本,选举只有Java版本。

zookeeper的原理

ZooKeeper是以Fast Paxos算法为根底的,paxos算法存在活锁的问题,即当有多个proposer交织提交时,有可能相互排挤导致没有一个proposer能提交胜利,而Fast Paxos作了一些优化,通过选举产生一个leader,只有leader能力提交propose。=。因而要想弄懂ZooKeeper首先得对Fast Paxos有所理解。

ZooKeeper的根本运行流程:

  1. 选举Leader。
  2. 同步数据。
  3. 选举Leader过程中算法有很多,但要达到的选举规范是统一的。
  4. Leader要具备最高的zxid。
  5. 集群中大多数的机器失去响应并follow选出的Leader

zookeeper的特点

在Zookeeper中,znode是一个跟Unix文件系统门路类似的节点,能够往这个节点存储或获取数据。如果在创立znode时Flag设置为EPHEMERAL,那么当创立这个znode的节点和Zookeeper失去连贯后,这个znode将不再存在在Zookeeper里,Zookeeper应用Watcher觉察事件信息。当客户端接管到事件信息,比方连贯超时、节点数据扭转、子节点扭转,能够调用相应的行为来解决数据。Zookeeper的Wiki页面展现了如何应用Zookeeper来处理事件告诉,队列,优先队列,锁,共享锁,可撤销的共享锁,两阶段提交。那么Zookeeper能作什么事件呢,简略的例子:假如咱们有20个搜索引擎的服务器(每个负责总索引中的一部分的搜寻工作)和一个总服务器(负责向这20个搜索引擎的服务器收回搜寻申请并合并后果集),一个备用的总服务器(负责当总服务器宕机时替换总服务器),一个web的cgi(向总服务器收回搜寻申请)。搜索引擎的服务器中的15个服务器提供搜寻服务,5个服务器正在生成索引。这20个搜索引擎的服务器常常要让正在提供搜寻服务的服务器进行提供服务开始生成索引,或生成索引的服务器曾经把索引生成实现能够搜寻提供服务了。应用Zookeeper能够保障总服务器主动感知有多少提供搜索引擎的服务器并向这些服务器收回搜寻申请,当总服务器宕机时主动启用备用的总服务器。

装置

筹备工作
在装置zookeeper之前咱们要确保本人主机上曾经有了Java环境,倡议装置Oracle JDK8.x

环境版本
RHEL/CentOS7.x
Java8.x
Zookeeper3.4.x
# 查看java环境[thinktik@localhost ~]$ java -versionjava version "1.8.0_191"Java(TM) SE Runtime Environment (build 1.8.0_191-b12)Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)[thinktik@localhost ~]$ lsapache-maven-3.6.0-bin.tar.gz  httpd-2.4.37.tar.gz         jenkins.war      sonarqube-6.7.5.tarhttpd                          java8                       maven            zookeeper-3.4.13.tar.gzhttpd-2.4.37                   jdk-8u191-linux-x64.tar.gz  sonarqube-6.7.5# 解压[thinktik@localhost ~]$ tar -zxvf zookeeper-3.4.13.tar.gz 

[thinktik@localhost ~]$ lsapache-maven-3.6.0-bin.tar.gz  httpd-2.4.37.tar.gz         jenkins.war      sonarqube-6.7.5.tarhttpd                          java8                       maven            zookeeper-3.4.13httpd-2.4.37                   jdk-8u191-linux-x64.tar.gz  sonarqube-6.7.5  zookeeper-3.4.13.tar.gz[thinktik@localhost ~]$ cd zookeeper-3.4.13[thinktik@localhost zookeeper-3.4.13]$ lsbin        dist-maven       lib          README_packaging.txt  zookeeper-3.4.13.jar.ascbuild.xml  docs             LICENSE.txt  recipes               zookeeper-3.4.13.jar.md5conf       ivysettings.xml  NOTICE.txt   src                   zookeeper-3.4.13.jar.sha1contrib    ivy.xml          README.md    zookeeper-3.4.13.jar# 创立data文件夹保持数据[thinktik@localhost zookeeper-3.4.13]$ mkdir data# 创立logs文件夹保留日志[thinktik@localhost zookeeper-3.4.13]$ mkdir logs[thinktik@localhost zookeeper-3.4.13]$ pwd/home/thinktik/zookeeper-3.4.13[thinktik@localhost zookeeper-3.4.13]$ cd conf/[thinktik@localhost conf]$ lsconfiguration.xsl  log4j.properties  zoo_sample.cfg# 将样例配置文件复制一份为zoo.cfg[thinktik@localhost conf]$ cp zoo_sample.cfg zoo.cfg # 批改配置文件[thinktik@localhost conf]$ vim zoo.cfg

配置文件参考(这里我将dataDir和dataLogDir门路改为了我方才创立文件夹)

单机版启动

[thinktik@localhost conf]$ cd ..[thinktik@localhost zookeeper-3.4.13]$ lsbin        dist-maven       LICENSE.txt           recipes                   zookeeper-3.4.13.jar.sha1build.xml  docs             logs                  srcconf       ivysettings.xml  NOTICE.txt            zookeeper-3.4.13.jarcontrib    ivy.xml          README.md             zookeeper-3.4.13.jar.ascdata       lib              README_packaging.txt  zookeeper-3.4.13.jar.md5[thinktik@localhost zookeeper-3.4.13]$ cd bin/[thinktik@localhost bin]$ lsREADME.txt    zkCli.cmd  zkEnv.cmd  zkServer.cmd  zkTxnLogToolkit.cmdzkCleanup.sh  zkCli.sh   zkEnv.sh   zkServer.sh   zkTxnLogToolkit.sh# 启动[thinktik@localhost bin]$ ./zkServer.sh startZooKeeper JMX enabled by defaultUsing config: /home/thinktik/zookeeper-3.4.13/bin/../conf/zoo.cfgStarting zookeeper ... STARTED# 状态查问为正在运行,单例模式[thinktik@localhost bin]$ ./zkServer.sh statusZooKeeper JMX enabled by defaultUsing config: /home/thinktik/zookeeper-3.4.13/bin/../conf/zoo.cfgMode: standalone# 查看端口监听ok[thinktik@localhost bin]$ netstat -nlp | grep 2181(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.)tcp6       0      0 :::2181                 :::*                    LISTEN      1958/java  # 查看运行线程ok[thinktik@localhost bin]$ ps -ef |grep zoothinktik  1958     1  0 11:17 pts/0    00:00:00 java -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -cp /home/thinktik/zookeeper-3.4.13/bin/../build/classes:/home/thinktik/zookeeper-3.4.13/bin/../build/lib/*.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/slf4j-log4j12-1.7.25.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/slf4j-api-1.7.25.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/netty-3.10.6.Final.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/log4j-1.2.17.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/jline-0.9.94.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/audience-annotations-0.5.0.jar:/home/thinktik/zookeeper-3.4.13/bin/../zookeeper-3.4.13.jar:/home/thinktik/zookeeper-3.4.13/bin/../src/java/lib/*.jar:/home/thinktik/zookeeper-3.4.13/bin/../conf: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false org.apache.zookeeper.server.quorum.QuorumPeerMain /home/thinktik/zookeeper-3.4.13/bin/../conf/zoo.cfgthinktik  1978  1890  0 11:19 pts/0    00:00:00 grep --color=auto zoo# 客户端连贯ok[thinktik@localhost bin]$ ./zkCli.sh Connecting to localhost:21812018-11-11 11:48:15,274 [myid:] - INFO  [main:Environment@100] - Client environment:zookeeper.version=3.4.13-2d71af4dbe22557fda74f9a9b4309b15a7487f03, built on 06/29/2018 04:05 GMT2018-11-11 11:48:15,277 [myid:] - INFO  [main:Environment@100] - Client environment:host.name=localhost2018-11-11 11:48:15,277 [myid:] - INFO  [main:Environment@100] - Client environment:java.version=1.8.0_1912018-11-11 11:48:15,279 [myid:] - INFO  [main:Environment@100] - Client environment:java.vendor=Oracle Corporation2018-11-11 11:48:15,279 [myid:] - INFO  [main:Environment@100] - Client environment:java.home=/home/thinktik/java8/jre2018-11-11 11:48:15,280 [myid:] - INFO  [main:Environment@100] - Client environment:java.class.path=/home/thinktik/zookeeper-3.4.13/bin/../build/classes:/home/thinktik/zookeeper-3.4.13/bin/../build/lib/*.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/slf4j-log4j12-1.7.25.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/slf4j-api-1.7.25.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/netty-3.10.6.Final.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/log4j-1.2.17.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/jline-0.9.94.jar:/home/thinktik/zookeeper-3.4.13/bin/../lib/audience-annotations-0.5.0.jar:/home/thinktik/zookeeper-3.4.13/bin/../zookeeper-3.4.13.jar:/home/thinktik/zookeeper-3.4.13/bin/../src/java/lib/*.jar:/home/thinktik/zookeeper-3.4.13/bin/../conf:2018-11-11 11:48:15,280 [myid:] - INFO  [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib2018-11-11 11:48:15,280 [myid:] - INFO  [main:Environment@100] - Client environment:java.io.tmpdir=/tmp2018-11-11 11:48:15,280 [myid:] - INFO  [main:Environment@100] - Client environment:java.compiler=<NA>2018-11-11 11:48:15,280 [myid:] - INFO  [main:Environment@100] - Client environment:os.name=Linux2018-11-11 11:48:15,280 [myid:] - INFO  [main:Environment@100] - Client environment:os.arch=amd642018-11-11 11:48:15,280 [myid:] - INFO  [main:Environment@100] - Client environment:os.version=3.10.0-862.el7.x86_642018-11-11 11:48:15,280 [myid:] - INFO  [main:Environment@100] - Client environment:user.name=thinktik2018-11-11 11:48:15,280 [myid:] - INFO  [main:Environment@100] - Client environment:user.home=/home/thinktik2018-11-11 11:48:15,281 [myid:] - INFO  [main:Environment@100] - Client environment:user.dir=/home/thinktik/zookeeper-3.4.13/bin2018-11-11 11:48:15,282 [myid:] - INFO  [main:ZooKeeper@442] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@25f38edc2018-11-11 11:48:15,320 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1029] - Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)Welcome to ZooKeeper!JLine support is enabled2018-11-11 11:48:15,489 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@879] - Socket connection established to localhost/127.0.0.1:2181, initiating session[zk: localhost:2181(CONNECTING) 0] 2018-11-11 11:48:15,829 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1303] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x100003dc9010000, negotiated timeout = 30000WATCHER::WatchedEvent state:SyncConnected type:None path:null[zk: localhost:2181(CONNECTED) 0] [zk: localhost:2181(CONNECTED) 0] 

这里Zookeeper单机版就装置实现了

Zookeeper集群

单机模式的zk过程尽管便于开发与测试,但并不适宜在生产环境应用。在生产环境下,咱们须要应用集群模式来对zk进行部署。

留神在集群模式下,倡议至多部署3个zk过程,或者部署奇数个zk过程。如果只部署2个zk过程,当其中一个zk过程挂掉后,剩下的一个过程并不能形成一个quorum的大多数。因而,部署2个过程甚至比单机模式更不牢靠,因为2个过程其中一个不可用的可能性比一个过程不可用的可能性还大。

我持续按单机版的装置形式在例外的两个虚构机上安装2个zookeeper,并相互凋谢防火墙。

主机IP
CentOS01192.168.50.186
CentOS02192.168.50.164
CentOS03192.168.50.30

关键点是你将所有的zookeeper节点都写在配置文件外面去,并在这些主机上开发端口。我开的是2181,2888,3888三个端口,3个主机都开。

我的集群配置增加如下3个节点配置(记得Linux关上端口):

server.1=192.168.50.186:2888:3888server.2=192.168.50.164:2888:3888server.3=192.168.50.30:2888:3888

同时不要忘了在这3个主机装置的zookeeper的dataDir建设各自的myid文件并填入本人的id.

# 我以3号zookeeper为例[thinktik@localhost zookeeper]$ cd data/[thinktik@localhost data]$ pwd/home/thinktik/zookeeper/data# 这个zookeeper配置dataDir上面我建设了myid[thinktik@localhost data]$ lsmyid  version-2  zookeeper_server.pid# myid外面写上了它的id,id好与server.x的x对应。例如三号机是server.3=192.168.50.30:2888:3888那么myid外面填3[thinktik@localhost data]$ cat myid 3

启动集群,这里3个zookeeper轻易启动就能够,没什么先后顺序,每个zookeeper启动后会找本人其余节点的。

# 1号zookeeper我先启动。 2,3号我接着起[thinktik@localhost bin]$ ./zkServer.sh startZooKeeper JMX enabled by defaultUsing config: /home/thinktik/zookeeper-3.4.13/bin/../conf/zoo.cfgStarting zookeeper ... STARTED[thinktik@localhost bin]$ ./zkServer.sh statusZooKeeper JMX enabled by defaultUsing config: /home/thinktik/zookeeper-3.4.13/bin/../conf/zoo.cfgError contacting service. It is probably not running.[thinktik@localhost bin]$ vim ../conf/zoo.cfg [thinktik@localhost bin]$ vim ../data/myid [thinktik@localhost bin]$ ./zkServer.sh startZooKeeper JMX enabled by defaultUsing config: /home/thinktik/zookeeper-3.4.13/bin/../conf/zoo.cfgStarting zookeeper ... STARTED# 1,2,3都起后查看状态,1号成了leader[thinktik@localhost bin]$ ./zkServer.sh statusZooKeeper JMX enabled by defaultUsing config: /home/thinktik/zookeeper-3.4.13/bin/../conf/zoo.cfgMode: leader
# 启动2,3号[thinktik@localhost bin]$ ./zkServer.sh startZooKeeper JMX enabled by defaultUsing config: /home/thinktik/zookeeper/bin/../conf/zoo.cfgStarting zookeeper ... STARTED[thinktik@localhost bin]$ vim ../data/myid bash: vim: command not found[thinktik@localhost bin]$ vi ../data/myid [thinktik@localhost bin]$ ./zkServer.sh startZooKeeper JMX enabled by defaultUsing config: /home/thinktik/zookeeper/bin/../conf/zoo.cfgStarting zookeeper ... STARTED# 1,2,3都起后查看状态,2,3号成了leader[thinktik@localhost bin]$ ./zkServer.sh statusZooKeeper JMX enabled by defaultUsing config: /home/thinktik/zookeeper/bin/../conf/zoo.cfgMode: follower

验证下集群的性能

leader:

[zk: localhost:2181(CONNECTED) 0] ls/ZooKeeper -server host:port cmd args    stat path [watch]    set path data [version]    ls path [watch]    delquota [-n|-b] path    ls2 path [watch]    setAcl path acl    setquota -n|-b val path    history     redo cmdno    printwatches on|off    delete path [version]    sync path    listquota path    rmr path    get path [watch]    create [-s] [-e] path data acl    addauth scheme auth    quit     getAcl path    close     connect host:port# 创立节点[zk: localhost:2181(CONNECTED) 1] create /testNode '测试'Created /testNode# 节点已创立[zk: localhost:2181(CONNECTED) 2] ls /[zookeeper, testNode]

follower

# 查问节点,发现leader的节点曾经同步,一致性没问题[zk: localhost:2181(CONNECTED) 1] ls /[zookeeper, testNode]# 查看这个节点的内容,也没故障[zk: localhost:2181(CONNECTED) 3] get /testNode测试cZxid = 0x100000002ctime = Sun Nov 11 13:28:20 CST 2018mZxid = 0x100000002mtime = Sun Nov 11 13:28:20 CST 2018pZxid = 0x100000002cversion = 0dataVersion = 0aclVersion = 0ephemeralOwner = 0x0dataLength = 6numChildren = 0

这里根本集群就ok了。

本文原创链接:Linux Zookeeper装置

本文除了浏览了Zookeeper官网文档还参考的其他人写的文章:

  • https://www.cnblogs.com/tonyl...
  • https://blog.csdn.net/lihao21...
  • https://blog.csdn.net/pucao_c...