ZooKeeper 搭建

在这里插入图片描述

认识ZooKeeper

ZooKeeper概述

背景

随着互联网技术的高速发展,企业对计算机系统的计算、存储能力要求越来越高,最简单的证明就是出现了一些诸如:高并发,海量存储这样的词汇。在这样的背景下,单纯依靠少量高性能主机来完成计算任务已经不能满足企业的需求,企业的IT架构逐步从集中式向分布式过渡,所谓的分布式是指:把一个计算任务分解成若干个计算单元,并且分派到若干不同的计算机中去执行,然后汇总计算结果的过程!

ZooKeeper是什么

ZooKeeper是源代码开放的分布式协调服务,由雅虎创建,是Google Chubby的开源实现。ZooKeeper是一个高性能的分布式数据一致性解决方案,它将那些复杂的、容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并提供一系列简单易用的接口给用户使用

ZooKeeper的应用场景
  • 数据发布/订阅

数据发布/订阅 顾名思义就是一方把数据发布出来,另一方通过某种手段可以得到这些数据
通常数据订阅有两种方式:推模式和拉模式,推模式一般是服务器主动向客户端推送信息, 拉模式是客户端主动去服务器获取数据(通常是采用定时轮询的方式),
ZK采用两种方式相结合
发布者将数据发布到ZK集群节点上,订阅者通过一定的方法告诉服务器,我对哪个节点的数据感兴趣,那服务器在这些节点的数据发生变化时,就通知客户端,客户端得到通知后可以去服务器获取数据信息

  • 负载均衡

步骤:
1、首先DB在启动的时候先把自己在ZK上注册成一个临时节点,ZK的节点后面我们会讲到有两种,一种是永久节点,一类是临时节点临时节点在服务器出现问题的时候,节点会自动的从ZK上删除,那么这样ZK上的服务器列表就是最新的可用的列表
2、客户端在需要读写数据库的时候首先它去ZooKeeper得到所有可用的DB的连接信息(一张列表)
3、客户端随机选择一个与之建立连接
4、当客户端发现连接不可用的时候可再次从ZK上获取可用的DB连接信息,当然也可以在刚获取的那个列表里移除掉不可用的连接后再随机选择一个DB与之连接

  • 命名服务

顾名思义,就是提供名称的服务,例如数据库表格ID,一般用得比较多的有两种ID,一种是自动增长的ID,一种是UUID(9291d71a-0354-4d8e-acd8-64f7393c64ae),两种ID各自都有缺陷,自动增长的ID局限在单库单表中使用,不能在分布式中使用,UUID可以在分布式中使用但是由于ID没有规律难于理解,我们可以借用ZK来生成一个顺序增长的,可以在集群环境下使用的,命名易于理解的ID

  • 分布式协调/通知

心跳检测
在分布式系统中,我们常常需要知道某个机器是否可用,传统的开发中,可以通过Ping某个主机来实现,Ping得通说明对方是可用的,相反是不可用的,ZK 中我们让所有的机其都注册一个临时节点,我们判断一个机器是否可用,我们只需要判断这个节点在ZK中是否存在就可以了,不需要直接去连接需要检查的机器 ,降低系统的复杂度

Zookeeper的环境搭建

Zookeeper使用java语言编写,所以它的运行环境需要java环境的支持

下载Zookeeper的安装包

下载地址:下载stable路径下的版本
http://mirrors.hust.edu.cn/apache/zookeeper/

Zookeeper有两种运行模式,集群模式和单机模式

zookeeper-端口说明

一、zookeeper有三个端口(可以修改)
1、2181
2、3888
3、2888

二、3个端口的作用
1、2181:对cline端提供服务
2、3888:选举leader使用
3、2888:集群内机器通讯使用(Leader监听此端口)

三、部署时注意
1、单机单实例,只要端口不被占用即可
2、单机伪集群(单机,部署多个实例),三个端口必须修改为组组不一样
如:myid1 : 2181,3888,2888
myid2 : 2182,3788,2788
myid3 : 2183,3688,2688
3、集群(一台机器部署一个实例)

四、集群为大于等于3个基数,如 3、5、7…,不宜太多,集群机器多了选举和数据同步耗时时长长,不稳定。目前觉得,三台选举+N台observe很不错。

zookeeper的安装和配置

Zookeeper的目的是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。Zookeeper有两种运行模式,单机模式(Standalone)和集群模式(Distributed),但是Zookeeper的长处在于可以搭建分布式的Zookeeper集群(一个Leader,多个Follower),从而可以保证集群的高可用性、高稳定性、高可靠性。

下面说明一下Zookeeper两种模式的配置:
在配置Zookeeper之前,下载Zookeeper的安装包:http://zookeeper.apache.org/releases.html#download
我使用的是zookeeper-3.3.6版本的。

Zookeeper的单机模式(standalone)

下载安装包之后,使用Winscp放到Linux的环境中,然后解压安装包:

1.tar zxvf zookeeper-3.3.6.tar.gz
解压后开始配置Zookeeper,进入到配置文件的目录:
2.cd zookeeper-3.3.6/conf/
将目录下面的 zoo_sample.cfg修改为zoo.cfg,然后配置内容为:

1).# The number of milliseconds of each tick
2).tickTime=2000
3).# The number of ticks that the initial
4).# synchronization phase can take
5).initLimit=10
6).# The number of ticks that can pass between
7).# sending a request and getting an acknowledgement
8).syncLimit=5
9).# the directory where the snapshot is stored.
10).dataDir=/tmp/zookeeper
11).# the port at which the clients will connect
12).clientPort=2181

上面各个配置参数的含义:

  • tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
  • dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
  • lientPort:这个端口就是客户端连接
  • Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
  • dataLogDir: log目录, 同样可以是任意目录. 如果没有设置该参数, 将使用和dataDir相同的设置,这个参数我没有设置。

3.配置好后,启动Zookeeper服务器进程:

1).cd zookeeper-3.3.6/
2).bin/zkServer.sh start

4.启动成功后,用jps -m的命令查询,Zookeeper的进程为QuorumPeerMain

5.用客户端进程连接服务器,执行如下命令:
bin/zkCli.sh -server logsrv03:2181
上面的logsrv是我的主机名,后面的2181是连接的端口号
连接成功后,出现以下的连接信息:

1).[root@logsrv03 zookeeper-3.3.6]# bin/zkCli.sh -server logsrv03:2181
2).Connecting to logsrv03:2181
3).2015-08-18 10:23:48,966 - INFO [main:Environment@97] - Client environment:zookeeper.version=3.3.6-1366786, built on 07/29/2012 06:22 GMT
4).2015-08-18 10:23:48,969 - INFO [main:Environment@97] - Client environment:host.name=logsrv03
5).2015-08-18 10:23:48,970 - INFO [main:Environment@97] - Client environment:java.version=1.7.0_71
6).2015-08-18 10:23:48,970 - INFO [main:Environment@97] - Client environment:java.vendor=Oracle Corporation
7).2015-08-18 10:23:48,971 - INFO [main:Environment@97] - Client environment:java.home=/usr/local/jdk1.7.0_71/jre
8).2015-08-18 10:23:48,971 - INFO [main:Environment@97] - Client environment:java.class.path=/usr/local/jiang/zookeeper-3.3.6/bin/…/build/classes:/usr/local/jiang/zookeeper-3.3.6/bin/…/build/lib/.jar:/usr/local/jiang/zookeeper-3.3.6/bin/…/zookeeper-3.3.6.jar:/usr/local/jiang/zookeeper-3.3.6/bin/…/lib/log4j-1.2.15.jar:/usr/local/jiang/zookeeper-3.3.6/bin/…/lib/jline-0.9.94.jar:/usr/local/jiang/zookeeper-3.3.6/bin/…/src/java/lib/.jar:/usr/local/jiang/zookeeper-3.3.6/bin/…/conf:.:/usr/local/jdk1.7.0_71/lib:/usr/local/jdk1.7.0_71/lib/dt.jar:/usr/local/jdk1.7.0_71/lib/tools.jar
9).2015-08-18 10:23:48,972 - INFO [main:Environment@97] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
10).2015-08-18 10:23:48,972 - INFO [main:Environment@97] - Client environment:java.io.tmpdir=/tmp
11).2015-08-18 10:23:48,973 - INFO [main:Environment@97] - Client environment:java.compiler=
12).2015-08-18 10:23:48,973 - INFO [main:Environment@97] - Client environment:os.name=Linux
13).2015-08-18 10:23:48,974 - INFO [main:Environment@97] - Client environment:os.arch=amd64
14).2015-08-18 10:23:48,974 - INFO [main:Environment@97] - Client environment:os.version=2.6.32-431.el6.x86_64
15).2015-08-18 10:23:48,975 - INFO [main:Environment@97] - Client environment:user.name=root
16).2015-08-18 10:23:48,975 - INFO [main:Environment@97] - Client environment:user.home=/root
17).2015-08-18 10:23:48,976 - INFO [main:Environment@97] - Client environment:user.dir=/usr/local/jiang/zookeeper-3.3.6
18).2015-08-18 10:23:48,977 - INFO [main:ZooKeeper@379] - Initiating client connection, connectString=logsrv03:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMainMyWatcher@1698ab0419.WelcometoZooKeeper!20.2015081810:23:48,995INFO[mainSendThread():ClientCnxnMyWatcher@1698ab04 19).Welcome to ZooKeeper! 20).2015-08-18 10:23:48,995 - INFO [main-SendThread():ClientCnxnSendThread@1058] - Opening socket connection to server logsrv03/172.17.6.148:2181
21).2015-08-18 10:23:49,002 - INFO [main-SendThread(logsrv03:2181):ClientCnxnSendThread@947]Socketconnectionestablishedtologsrv03/172.17.6.148:2181,initiatingsession22.JLinesupportisenabled23.2015081810:23:49,020INFO[mainSendThread(logsrv03:2181):ClientCnxnSendThread@947] - Socket connection established to logsrv03/172.17.6.148:2181, initiating session 22).JLine support is enabled 23).2015-08-18 10:23:49,020 - INFO [main-SendThread(logsrv03:2181):ClientCnxnSendThread@736] - Session establishment complete on server logsrv03/172.17.6.148:2181, sessionid = 0x24f3b0a17ea0002, negotiated timeout = 30000

25).WATCHER::
26).
27).WatchedEvent state:SyncConnected type:None path:null
28).[zk: logsrv03:2181(CONNECTED) 0]
到这,Zookeeper Standalone模式就配置完成了。

Zookeeper的集群模式(Distributed)

Zookeeper服务自身组成一个集群(2n+1个服务允许n个失效)。Zookeeper服务有两个角色,一个是leader,负责写服务和数据同步,剩下的是follower,提供读服务,leader失效后会在follower中重新选举新的leader。在整个Zookeeper集群模式下,整个集群是一个整体,在集群中的任何一个Zookeeper节点共享整个集群的服务。

下面介绍集群模式的配置过程:

第一步:配置主机名和ip的映射

在Zookeeper集群运行的过程中,每一个Zookeeper节点是需要相互通信的,并且是通过主机名来相互通信的,集群每个节点需要相互识别,所以,在配置一个Zookeeper节点的时候需要配置其他节点主机名到ip的映射

例如配置我的Zookeeper集群,集群中一共有三台机子:logsrv02、logsrv03、logsrv04,以logsrv03为例子,进入/etc/hosts,内容如下所示:

1.172.17.6.142 logsrv02
2.172.17.6.148 logsrv03
3.172.17.6.149 logsrv04

第二步:配置Zookeeper的配置文件

1.# The number of milliseconds of each tick
2.tickTime=2000
3.# The number of ticks that the initial
4.# synchronization phase can take
5.initLimit=10
6.# The number of ticks that can pass between
7.# sending a request and getting an acknowledgement
8.syncLimit=5
9.# the directory where the snapshot is stored.
10.dataDir=/tmp/zookeeper
11.# the port at which the clients will connect
12.clientPort=2181
13.server.1=logsrv02:2888:3888
14.server.2=logsrv03:2888:3888
15.server.3=logsrv04:2888:3888

以上配置文件与单机模式相比其实也就多了集群中server.id和主机名、端口号的映射信息。

第三步:在logsrv02和logsrv04添加安装文件

我们在logsrv03中配置好了Zookeeper安装文件,在一个集群中,每一个Zookeeper节点只需要使用相同的安装文件就行了,所以需要将配置好的文件复制到另外两台机子上,这里介绍两种方法:

第一种:使用Winscp将文件直接复制出去,然后再复制到另外两台机子上,这种方式需要安装Winscp(用于在本地与远程计算机间安全的复制文件,支持scp协议)
下载地址:http://winscp.net/eng/download.php

第二种:远程命令的方式直接复制到logsrv02和logsrv04上,如下面所示:
1.cd /usr/local/
2.scp -r zookeeper-3.3.6/ root@logsrv02:/usr/local/
3.scp -r zookeeper-3.3.4/ root@logsrv04:/usr/local/

第四步:设置myid

在我们配置的dataDir指定的目录下面,创建一个myid文件,里面内容为一个数字,用来标识当前主机,在conf/zoo.cfg中配置的server.x中x是什么数字就设置id为这个数字,如下面所示:

1.[root@logsrv02 zookeeper]# echo “1” > /tmp/zookeeper/myid
2.[root@logsrv03 zookeeper]# echo “2” > /tmp/zookeeper/myid
3.[root@logsrv04 zookeeper]# echo “3” > /tmp/zookeeper/myid

第五步:配置好后,启动集群

配置好后,进入/usr/local/zookeeper-3.3.6/目录下,然后执行如下命令启动zookeeper:

1.[root@logsrv02 zookeeper-3.3.6]# bin/zkServer start
2.[root@logsrv03 zookeeper-3.3.6]# bin/zkServer start
3.[root@logsrv04 zookeeper-3.3.6]# bin/zkServer start

第六步:安装验证

安装完成后,可以通过zookeeper的脚本来查看zookeeper的启动状态,以及每个Zookeeper节点在集群中的角色(Leader和Follower),下面是我的Zookeeper集群各节点的查询结果:

1.[root@logsrv02 zookeeper-3.3.6]# bin/zkServer.sh status
2.JMX enabled by default
3.Using config: /usr/local/jiang/zookeeper-3.3.6/bin/…/conf/zoo.cfg
4.Mode: follower
5.
6.[root@logsrv03 zookeeper-3.3.6]# bin/zkServer.sh status
7.JMX enabled by default
8.Using config: /usr/local/jiang/zookeeper-3.3.6/bin/…/conf/zoo.cfg
9.Mode: follower
10.
11.[root@logsrv04 zookeeper-3.3.6]# bin/zkServer.sh status
12.JMX enabled by default
13.Using config: /usr/local/zookeeper-3.3.6/bin/…/conf/zoo.cfg
14.Mode: leader

通过上面的信息可以得知,logsrv04是Leader,其余两个都是Follower。

集群配置好后,可以通过其中一个Zookeeper节点连接点集群上,而且通过一个节点可以共享整个集群的服务,例如:当你配置好Zookeeper集群后,再安装中间件KAFKA后,通过zookeeper启动KAFKA,然后通过脚本创建topic,topic的创建时需要指定zookeeper的节点,当许多节点都对应了topic,这个时候在zookeeper集群中,查询一个节点对应的topic列表,可以查询到整个集群的所有节点的topic列表。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章