大家好,又见面了,我是你们的朋友全栈君。
Zookeeper是主从模式的。
一,zookeeper原理:
Zookeeper是Google的Chubby一个开源的实现,是Hadoop的分布式协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。
在hadoop2.0中通常由两个NameNode组成,一个处于active状态,另一个处于standby状态。Active NameNode对外提供服务,而Standby NameNode则不对外提供服务,仅同步active namenode的状态,以便能够在它失败时快速进行切换。 hadoop2.0官方提供了两种HDFS HA的解决方案,一种是NFS,另一种是QJM。这里我们使用简单的QJM。在该方案中,主备NameNode之间通过一组JournalNode同步元数据信息,一条数据只要成功写入多数JournalNode即认为写入成功。通常配置奇数个JournalNode 这里还配置了一个zookeeper集群,用于ZKFC(DFSZKFailoverController)故障转移,当Active NameNode挂掉了,会自动切换Standby NameNode为Active状态。
所以通过上面的描述,明白为什么Hadoop要用到Zookeeper了,当Active状态的NameNode宕机后,Zookeeper可以自动帮我们实现把备份NameNode切换为Active状态。当然,Zookeeper的功能远不止这一个,它还有数据同步、分布式锁、负载均衡等等强大的功能。下面我们通过图例来说一下Zookeeper在数据同步方面的作用,Zookeeper集群的搭建有个特点就是设备的数量必须是奇数台,像下图就有5台设备作为Zookeeper的集群,之所以搞这么多台机器组成集群来对外提供服务是考虑到了数据的高可靠性,即一台设备宕机后要能够迅速被其它机器所取代,从而提供持续稳定的服务。在奇数台设备当中只有一台设备是“Leader”即领导身份,其它设备都是”Follower”即从属者的身份。Zookeeper集群只要有一半以上的机器正常运行就可以正常提供服务,也就是说,集群允许宕机的数量不能达到机器总量的一半,比如我们拿一个最小的Zookeeper集群来说,从高可靠性还有奇数台两个方面考虑,我们知道集群最少的机器数量是3台,那么这3台组成的集群最大允许的宕机数量是1台,同理,5台组成的集群最大允许的宕机数量是2台,7台组成的集群最大允许的宕机数量是3台等等。我们来说一下数据同步是怎么回事,我们看下图发现有很多Client连向Server,假如第一台Client修改了第一台Server上的某个变量的值,作为Leader的Server能够监测到哪个Server的哪个变量发生了变化,这时Zookeeper会给这个变量加上锁,如果有Client要获取这个变量的值,它就处于等待状态,等这个变量在其它Server之间进行数据的同步完成之后才会返回这个变量的值。
接下来说一下为什么要用到Zookeeper,下图第一条所说的意思,我举个例子,比如我们有个好几百台设备组成的集群,现在我们要更改一下配置,那么我们要一台一台的去改吗?答案显然不是的,因为那样做太浪费时间,我们可以修改一台设备的配置,然后利用Zookeeper的数据同步功能自动实现在所有其他设备上的同步,这样是不是非常好啊。下图所说的第二条、第三条的意思是,在Zookeeper出现之前公司内部开发程序时往往由于不通用而导致大量的人力物力财力的浪费,而Zookeeper却以高通用性和高可靠性很好的解决了这一问题,使程序的通用性大大提高。
Zookeeper能帮我们做什么?如下图所示。
那么Zookeeper的特性是什么呢?如下图所示。之所以说Zookeeper是简单的,是因为我们几乎不用编程,我们只要启动它的服务就可以了,当然它也提供了一些java接口来供我们调用的。说它富有表现力是说它具有非常丰富且强大的功能。高可用性是指Apache在设计该产品之初便考虑了非常多的情况,可以适用于非常多的情况。采用松耦合的交互方式是指采用面向接口编程从而最大限度的降低模块与模块之间的关联。Zookeeper是一个资源库是指它提供服务,你可以让它为你服务,当然也可以不用它,用于不用,它都在那儿。
因为zookeeper是管理集群的,所以我们需要再搭建两个环境。这里就克隆出两个ubuntu系统。
二,克隆两个ubuntu系统
首先关闭现有的虚拟机,右键–》管理–》克隆
下一步:
创建完整克隆,一种“创建链接克隆(L)”,但是会引用原始虚拟机,不能独立运行,另一种“创建完整克隆(F)”,完全克隆当前虚拟机,可以独立于原始虚拟机运行。根据自己的需要创建,我这里选择“创建完整克隆”。点击“下一步”。
选择克隆虚拟机安装地址,不是再系统盘就行,毕竟一个系统很大。
完成,等一会
克隆需要一会时间,我们先下载zookeeper,地址跟hadoop,hive一样,cdh版本:http://archive.cloudera.com/cdh5/cdh/5/
最后这样就完成了
:
下面需要配置克隆好的ip和主机名了。
小编以ubuntu3为例,打开虚拟机,用户名密码跟之前的都一样。切换到root用户,ifconfig 查看现有的ip地址。
vim /etc/hostname 修改永久主机名为ubuntu3
vim /etc/hosts 修改域名与ip对应关系
这里小编准备把ip改为192.168.72.133
/etc/hostname中存放的是主机名
/etc/hosts存放的是域名与ip的对应关系,域名与主机名没有任何关系,
接着修改静态ip 命令:vim /etc/network/interfaces
小编这里把ip改为192.168.72.133
整体如下:
最后reboot重启机器;
重启后,ifconfig 查看ip hostname查看主机名,看看有没有改动。最后ping www.baidu.com看看能不能联网
这些都没问题就可以直接起动hadoop试试看看能不能在这个ip的虚拟机下能不能成功启动。
最后小编这些都是ok的;
cd hadoop 进入到hadoop目录下
./sbin/start-all.sh 启动hadoop
window浏览器访问:192.168.72.133:8100
同理操作ubuntu2就行了。
三,安装使用zookeeper
安装好三台虚拟机后就可以安装zookeeper了。
上传刚才下载zookeeper包,解压,重命名。
现在我们开始安装单节点的zookeeper,我们需要修改conf目录下的zoo_sample.cfg为zoo.cfg,如下图所示。
cd /zookeeper/conf
cp zoo_sample.cfg zoo.cfg 复制文件
好,接下来我们便可以启动zookeeper了,我们回到bin目录下,并使用命令:./zkServer.sh start来启动zookeeper的服务器,如下图所示。
进入到bin目录下,命令:./zkServer.sh start 启动zookeeper服务。可以看到下图,有个QuorumPeerMain进程,说明启动就行了。
接下来我们再启动客户端
命令: ./zkCli.sh
输入help看看有那些命令能够使用:
接下来看看再zk客户端有哪些命令:ls 查看有那些文件, create 创建一个文件,get 获取文件的内容和属性信息。
[zk: localhost:2181(CONNECTED) 1] ls [zk: localhost:2181(CONNECTED) 2] create /ubuntu01 18000 Created /ubuntu01 [zk: localhost:2181(CONNECTED) 5] get /ubuntu01 18000 cZxid = 0x2 ctime = Wed Mar 28 03:39:49 PDT 2018 mZxid = 0x2 mtime = Wed Mar 28 03:39:49 PDT 2018 pZxid = 0x2 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 6
numChildren = 0
上面说了单节点zookeeper的情况,接下来我们搭建一个集群,搭建集群我们需要修改一下zookeeper的配置文件,刚才我们已经把conf目录下的zoo_sample.cfg更名为了zoo.cfg,我们现在进入这个目录下,如下图所示,我们发现zoo.cfg文件当中有几个配置,如tickTime=2000,initLimit=10等等,那么这些配置是什么意思呢?
zookeeper的默认配置文件为zookeeper/conf/zoo_sample.cfg,需要将其修改为zoo.cfg。其中各配置项的含义,解释如下:
1.tickTime:CS通信心跳时间 Zookeeper 服务器之间或客户端(C)与服务器(S)之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。tickTime以毫秒为单位。 tickTime=2000
2.initLimit:LF初始通信时限,就是Zookeeper在启动的时候,Leader等待Follower启动的最长时间,超过这个时间Leader就认为该设备未成功启动。 集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)。 initLimit=5 (意思是最多允许5次心跳的时间,一次心跳时间是2秒,5次心跳时间便是10秒)
3.syncLimit:LF同步通信时限(就是在数据同步的时候,Leader最多能容忍的等待时长,如果超过这个时间Follower还没有响应,那么Leader认为这台Follower同步数据失败了。) 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)。 syncLimit=2 (4秒的时间) 4.dataDir:数据文件目录 Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这个目录里。 dataDir=/home/xiaoye/zookeeper/data
5.clientPort:客户端连接端口 客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。 clientPort=2181
6.服务器名称与地址:集群信息(服务器编号,服务器地址,LF通信端口,选举端口) 这个配置项的书写格式比较特殊,规则如下:
server.1=ubuntu:2888:3888 server.2=ubuntu2:2888:3888 server.3=ubuntu3:2888:3888
上面需要说明的是server必须就叫这个名字,server后面的.1、.2、.3是server的ID,不能重复。2888是通信端口,3888是选举端口。
介绍完了配置的意思之后我 我们现在配完一台设备了,我们接下来只需把这台设备的配置复制到其它设备上即可们正式开始修改配置文件,第一加zookeeper数据保存地址,保存地址:dataDir=/home/xiaoye/zookeeper/data zookeeper下没有data文件夹。创建一个
建好了data目录后,我们进入到该目录下,目前该目录是空的,我们需要在data目录下创建一个myid的文件,这个文件中保存当前zookeeper的id,如下图所示,我们在myid文件中输入一个1(为什么id是1呢?我们不是刚才在配置文件中了server.1=ubuntu:2888:3888吗,现在我们在ubuntu上所以ID是1)然后保存退出。
我们现在配完一台设备了,我们接下来只需把这台设备的配置复制到其它设备上即可.
远程拷贝的命令是: scp -r zookeeper/ xiaoye@192.168.72.132:/home/xiaoye
这时我们别忘了,有一处地方是需要我们修改的,那就是data文件夹下的server的ID,因为每台Server的ID是不一样的,现在既然是在ubuntu2设备上,我们当然要把它的ID改成2了.
同理操作ubuntu3机器。
下面启动ubuntu3的zookeeper
xiaoye@ubuntu3:~ cd zookeeper/ xiaoye@ubuntu3:~/zookeeper cd bin xiaoye@ubuntu3:~/zookeeper/bin ./zkServer.sh start JMX enabled by default Using config: /home/xiaoye/zookeeper/bin/../conf/zoo.cfg Starting zookeeper … STARTED xiaoye@ubuntu3:~/zookeeper/bin ./zkServer.sh status JMX enabled by default Using config: /home/xiaoye/zookeeper/bin/../conf/zoo.cfg Error contacting service. It is probably not running.
xiaoye@ubuntu3:~/zookeeper/bin$
发现在执行./zkServer.sh status命令后的结果是not running ,报错的。不明白是什么情况;我同样启动了,Ubuntu ubuntu2两个机子,出现了同样的错。只能百度了。最后的解决办法是修改/etc/hosts文件,把 三个虚拟机的这个文件都加上三个机子的ip和对应的主机名。如下:
xiaoye@ubuntu3:~/zookeeper/bin cd .. xiaoye@ubuntu3:~/zookeeper cd .. xiaoye@ubuntu3:~ vim /etc/hosts xiaoye@ubuntu3:~ su root Password: root@ubuntu3:/home/xiaoye# vim /etc/hosts
127.0.0.1 localhost 127.0.1.1 ubuntu3 192.168.72.131 ubuntu 192.168.72.132 ubuntu2 192.168.72.133 ubuntu3
# The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ~
把每个虚拟机的这个文件都这样改就行了。然后重新三台机子。可能出现的其他错误可参照这篇博文:https://www.cnblogs.com/xiaohua92/p/5460515.html
再启动zookeeper,出现:
xiaoye@ubuntu:~ cd zookeeper/ xiaoye@ubuntu3:~/zookeeper ./bin/zkServer.sh start JMX enabled by default Using config: /home/xiaoye/zookeeper/bin/../conf/zoo.cfg Starting zookeeper … STARTED xiaoye@ubuntu3:~/zookeeper
就是没问题了。
可以看到最后一行,显示三个机子那个是leader 那个是follower。哪台设备是leader哪台设备是follower是不固定的,是通过选举决定的
5, 接下来我们来演示一下数据同步功能,
这里ubuntu2是leader ,因此我们再ubuntu2这个机子上新建一个文件,看看能不能同步到其他两个从机子上。
ubunut2:
xiaoye@ubuntu2:~/zookeeper cd bin xiaoye@ubuntu2:~/zookeeper/bin ./zkCl zkCleanup.sh zkCli.cmd zkCli.sh xiaoye@ubuntu2:~/zookeeper/bin ./zkCli.sh Connecting to localhost:2181 2018-03-28 19:24:13,988 [myid:] – INFO [main:Environment@100] – Client environment:zookeeper.version=3.4.5-cdh5.10.2–1, built on 06/27/2017 03:58 GMT 2018-03-28 19:24:13,994 [myid:] – INFO [main:Environment@100] – Client environment:host.name=ubuntu2 2018-03-28 19:24:13,995 [myid:] – INFO [main:Environment@100] – Client environment:java.version=1.8.0_151 2018-03-28 19:24:13,999 [myid:] – INFO [main:Environment@100] – Client environment:java.vendor=Oracle Corporation 2018-03-28 19:24:14,000 [myid:] – INFO [main:Environment@100] – Client environment:java.home=/usr/lib/jvm/java-8-openjdk-amd64/jre 2018-03-28 19:24:14,000 [myid:] – INFO [main:Environment@100] – Client environment:java.class.path=/home/xiaoye/zookeeper/bin/../build/classes:/home/xiaoye/zookeeper/bin/../build/lib/*.jar:/home/xiaoye/zookeeper/bin/../share/zookeeper/zookeeper-3.4.5-cdh5.10.2.jar:/home/xiaoye/zookeeper/bin/../share/zookeeper/slf4j-log4j12-1.7.5.jar:/home/xiaoye/zookeeper/bin/../share/zookeeper/slf4j-api-1.7.5.jar:/home/xiaoye/zookeeper/bin/../share/zookeeper/netty-3.10.5.Final.jar:/home/xiaoye/zookeeper/bin/../share/zookeeper/log4j-1.2.16.jar:/home/xiaoye/zookeeper/bin/../share/zookeeper/jline-2.11.jar:/home/xiaoye/zookeeper/bin/../src/java/lib/*.jar:/home/xiaoye/zookeeper/bin/../conf:.:/usr/lib/jvm/java-1.8.0-openjdk-amd64/lib: 2018-03-28 19:24:14,029 [myid:] – INFO [main:Environment@100] – Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib 2018-03-28 19:24:14,029 [myid:] – INFO [main:Environment@100] – Client environment:java.io.tmpdir=/tmp 2018-03-28 19:24:14,030 [myid:] – INFO [main:Environment@100] – Client environment:java.compiler=<NA> 2018-03-28 19:24:14,030 [myid:] – INFO [main:Environment@100] – Client environment:os.name=Linux 2018-03-28 19:24:14,030 [myid:] – INFO [main:Environment@100] – Client environment:os.arch=amd64 2018-03-28 19:24:14,030 [myid:] – INFO [main:Environment@100] – Client environment:os.version=4.13.0-37-generic 2018-03-28 19:24:14,030 [myid:] – INFO [main:Environment@100] – Client environment:user.name=xiaoye 2018-03-28 19:24:14,030 [myid:] – INFO [main:Environment@100] – Client environment:user.home=/home/xiaoye 2018-03-28 19:24:14,031 [myid:] – INFO [main:Environment@100] – Client environment:user.dir=/home/xiaoye/zookeeper/bin 2018-03-28 19:24:14,034 [myid:] – INFO [main:ZooKeeper@438] – Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMainSendThread@975] – Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) JLine support is enabled 2018-03-28 19:24:14,518 [myid:] – INFO [main-SendThread(localhost:2181):ClientCnxnSendThread@852] – Socket connection established, initiating session, client: /127.0.0.1:43804, server: localhost/127.0.0.1:2181 2018-03-28 19:24:14,931 [myid:] – INFO [main-SendThread(localhost:2181):ClientCnxn
WATCHER::
WatchedEvent state:SyncConnected type:None path:null [zk: localhost:2181(CONNECTED) 0] ls [zk: localhost:2181(CONNECTED) 1] help 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) 2] create /hadoop02 i am leader Created /hadoop02 [zk: localhost:2181(CONNECTED) 3] get hadoop02 Command failed: java.lang.IllegalArgumentException: Path must start with / character [zk: localhost:2181(CONNECTED) 4] get /hadoop02 i cZxid = 0x200000002 ctime = Wed Mar 28 19:26:40 PDT 2018 mZxid = 0x200000002 mtime = Wed Mar 28 19:26:40 PDT 2018 pZxid = 0x200000002 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 1 numChildren = 0
ubuntu:
[zk: localhost:2181(CONNECTED) 0] ls [zk: localhost:2181(CONNECTED) 1] ls [zk: localhost:2181(CONNECTED) 2] ls / [zookeeper, hadoop02] [zk: localhost:2181(CONNECTED) 3] get /hadoop02 i cZxid = 0x200000002 ctime = Wed Mar 28 19:26:40 PDT 2018 mZxid = 0x200000002 mtime = Wed Mar 28 19:26:40 PDT 2018 pZxid = 0x200000002 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 1 numChildren = 0 [zk: localhost:2181(CONNECTED) 4]
可以看到ubuntu也有hadoop02这个文件,get /hadoop02内容也跟ubuntu2一样。
好了这样就zookeeper就学习完了
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/106171.html原文链接:https://javaforall.cn