ZooKeeper是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。
Zookeeper设计目的
- 最终一致性:client不论连接到那个Server,展示给它的都是同一个视图。
- 可靠性:具有简单、健壮、良好的性能、如果消息m被到一台服务器接收,那么消息m将被所有服务器接收。
- 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
- 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
- 原子性:更新只能成功或者失败,没有中间状态。
- 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
Zookeeper工作原理
在zookeeper的集群中,各个节点共有下面3种角色和4种状态:
角色:leader、follower、observer
状态:leading、following、observing、looking
Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议(ZooKeeper Atomic Broadcast protocol)。Zab协议有两种模式,它们分别是恢复模式(Recovery选主)和广播模式(Broadcast同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。
每个Server在工作过程中有4种状态:
- LOOKING:当前Server不知道leader是谁,正在搜寻。
- LEADING:当前Server即为选举出来的leader。
- FOLLOWING:leader已经选举出来,当前Server与之同步。
- OBSERVING:observer的行为在大多数情况下与follower完全一致,但是他们不参加选举和投票,而仅仅接受(observing)选举和投票的结果。
Zookeeper集群节点
- Zookeeper节点部署越多,服务的可靠性越高,建议部署奇数个节点,因为zookeeper集群是以宕机个数过半才会让整个集群宕机的。
- 需要给每个zookeeper 1G左右的内存,如果可能的话,最好有独立的磁盘,因为独立磁盘可以确保zookeeper是高性能的。如果你的集群负载很重,不要把zookeeper和RegionServer运行在同一台机器上面,就像DataNodes和TaskTrackers一样。
Zookeeper集群部署记录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
1)服务器信息
主机名 系统 IP地址
sign-zk01.wangshibo.cn CentOS release 6.8 172.16.51.198
sign-zk02.wangshibo.cn CentOS release 6.8 172.16.51.199
sign-zk03.wangshibo.cn CentOS release 6.8 172.16.51.200
2)安装过程
先记录sign-zk01.wangshibo.cn节点机的部署过程(其他两个节点的部署过程基本一致)
安装jdk
可以yum安装自带的jdk
[root@sign-zk01 ~]
# yum -y install java-1.7.0-openjdk*
[root@sign-zk01 ~]
# java -version
java version
"1.7.0_151"
OpenJDK Runtime Environment (rhel-2.6.11.0.el6_9-x86_64 u151-b00)
OpenJDK 64-Bit Server VM (build 24.151-b00, mixed mode)
不过建议卸载掉自带的jdk,安装Java OpenJDK
[root@sign-zk01 ~]
# yum -y remove java-1.7.0-openjdk*
[root@sign-zk01 ~]
# yum -y remove tzdata-java.noarch
[root@sign-zk01 ~]
# java -version
-
bash
: java:
command
not found
[root@sign-zk01 ~]
# rpm -ivh jdk-7u79-linux-x64.rpm --force
[root@sign-zk01 ~]
# java -version
java version
"1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
安装并部署zookeeper集群
[app@sign-zk01 ~]$
cd
/usr/local/src/
[app@sign-zk01 src]$ wget http:
//mirror
.bit.edu.cn
/apache/zookeeper/zookeeper-3
.4.11
/zookeeper-3
.4.11.
tar
.gz
[app@sign-zk01 src]$
tar
-zvxf zookeeper-3.4.11.
tar
.gz
[app@sign-zk01 src]$
mv
zookeeper-3.4.11.
tar
.gz
/data/
[app@sign-zk01 src]$
cd
/data/zookeeper-3
.4.11
/conf/
[app@sign-zk01 conf]$
cp
zoo_sample.cfg zoo.cfg
[app@sign-zk01 conf]$
cat
zoo.cfg |
grep
-
v
"#"
tickTime=2000
initLimit=10
syncLimit=5
dataDir=
/data/zookeeper-3
.4.11
/data
dataLogDir=
/data/zookeeper-3
.4.11
/logs
clientPort=2181
server.1=sign-zk01.wangshibo.cn:2888:3888
server.2=sign-zk02.wangshibo.cn:2888:3888
server.3=sign-zk03.wangshibo.cn:2888:3888
参数说明:
tickTime这个时间是作为zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是说每个tickTime时间就会发送一个心跳。
initLimit这个配置项是用来配置zookeeper接受客户端(这里所说的客户端不是用户连接zookeeper服务器的客户端,而是zookeeper服务器集群中连接到leader的follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。
当已经超过10个心跳的时间(也就是tickTime)长度后 zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 10*2000=20秒。
syncLimit这个配置项标识leader与follower之间发送消息,请求和应答时间长度,最长不能超过多少个tickTime的时间长度,总的时间长度就是5*2000=10秒。
dataDir顾名思义就是zookeeper保存数据的目录,默认情况下zookeeper将写数据的日志文件也保存在这个目录里;
clientPort这个端口就是客户端连接Zookeeper服务器的端口,Zookeeper会监听这个端口接受客户端的访问请求;
server.A=B:C:D中的A是一个数字,表示这个是第几号服务器,B是这个服务器的IP地址,C第一个端口用来集群成员的信息交换,表示这个服务器与集群中的leader服务器交换信息的端口,D是在leader挂掉时专门用来进行选举leader所用的端口。
[app@sign-zk01 conf]$
mkdir
/data/zookeeper-3
.4.11
/data
[app@sign-zk01 conf]$
mkdir
/data/zookeeper-3
.4.11
/logs
创建ServerID标识(这是三个节点机器唯一配置不一样的地方,三个节点的myid文件配置的ServerID不能重复,建议分别配置成1、2、3)
除了修改zoo.cfg配置文件外,zookeeper集群模式下还要配置一个myid文件,这个文件需要放在dataDir目录下。
这个文件里面有一个数据就是A的值(该A就是zoo.cfg文件中server.A=B:C:D中的A),在zoo.cfg文件中配置的dataDir路径中创建myid文件。
[app@sign-zk01 ~]$
echo
"1"
>
/data/zookeeper-3
.4.11
/data/myid
[app@sign-zk02 ~]$
echo
"2"
>
/data/zookeeper-3
.4.11
/data/myid
[app@sign-zk03 ~]$
echo
"3"
>
/data/zookeeper-3
.4.11
/data/myid
然后分别重启三个节点机器的zookeeper(stop
/start/restart
)
[app@sign-zk01 ~]$
/data/zookeeper-3
.4.11
/bin/zkServer
.sh start
[app@sign-zk02 ~]$
/data/zookeeper-3
.4.11
/bin/zkServer
.sh start
[app@sign-zk03 ~]$
/data/zookeeper-3
.4.11
/bin/zkServer
.sh start
[app@sign-zk01 ~]$
lsof
-i:2181
COMMAND PID USER FD TYPE DEVICE SIZE
/OFF
NODE NAME
java 7071 app 20u IPv6 30989 0t0 TCP *:eforward (LISTEN)
查看zookeeper集群状态
[app@sign-zk01 ~]$
/data/zookeeper-3
.4.11
/bin/zkServer
.sh status
ZooKeeper JMX enabled by default
Using config:
/data/zookeeper-3
.4.11
/bin/
..
/conf/zoo
.cfg
Mode: follower
[app@sign-zk02 ~]$
/data/zookeeper-3
.4.11
/bin/zkServer
.sh status
ZooKeeper JMX enabled by default
Using config:
/data/zookeeper-3
.4.11
/bin/
..
/conf/zoo
.cfg
Mode: leader
[app@sign-zk03 ~]$
/data/zookeeper-3
.4.11
/bin/zkServer
.sh status
ZooKeeper JMX enabled by default
Using config:
/data/zookeeper-3
.4.11
/bin/
..
/conf/zoo
.cfg
Mode: follower
从上面可以看出,sign-zk01.wangshibo.cn,sign-zk03.wangshibo.cn两台服务器zookeeper的状态是follow模式,
sign-zk02.wangshibo.cn这台服务器zookeeper的状态是leader模式。
Zookeeper集群连接
Zookeeper集群搭建完毕之后,可以通过客户端脚本连接到zookeeper集群上面,对客户端来说,zookeeper集群是一个整体,连接到zookeeper集群实际上感觉在独享整个集群的服务。
[app@sign-zk01 ~]$
/data/zookeeper-3
.4.11
/bin/zkCli
.sh -server sign-zk02.wangshibo.cn:2181
Connecting to sign-zk02.wangshibo.cn:2181
2017-11-22 15:22:55,110 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11
/01/2017
18:06 GMT
2017-11-22 15:22:55,113 [myid:] - INFO [main:Environment@100] - Client environment:host.name=sign-zk01.wangshibo.cn
2017-11-22 15:22:55,113 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.7.0_79
2017-11-22 15:22:55,114 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2017-11-22 15:22:55,114 [myid:] - INFO [main:Environment@100] - Client environment:java.home=
/usr/java/jdk1
.7.0_79
/jre
2017-11-22 15:22:55,114 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=
/data/zookeeper-3
.4.11
/bin/
..
/build/classes
:
/data/zookeeper-3
.4.11
/bin/
..
/build/lib/
*.jar:
/data/zookeeper-3
.4.11
/bin/
..
/lib/slf4j-log4j12-1
.6.1.jar:
/data/zookeeper-3
.4.11
/bin/
..
/lib/slf4j-api-1
.6.1.jar:
/data/zookeeper-3
.4.11
/bin/
..
/lib/netty-3
.10.5.Final.jar:
/data/zookeeper-3
.4.11
/bin/
..
/lib/log4j-1
.2.16.jar:
/data/zookeeper-3
.4.11
/bin/
..
/lib/jline-0
.9.94.jar:
/data/zookeeper-3
.4.11
/bin/
..
/lib/audience-annotations-0
.5.0.jar:
/data/zookeeper-3
.4.11
/bin/
..
/zookeeper-3
.4.11.jar:
/data/zookeeper-3
.4.11
/bin/
..
/src/java/lib/
*.jar:
/data/zookeeper-3
.4.11
/bin/
..
/conf
:
2017-11-22 15:22:55,115 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=
/usr/java/packages/lib/amd64
:
/usr/lib64
:
/lib64
:
/lib
:
/usr/lib
2017-11-22 15:22:55,115 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=
/tmp
2017-11-22 15:22:55,115 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA>
2017-11-22 15:22:55,115 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux
2017-11-22 15:22:55,115 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd64
2017-11-22 15:22:55,115 [myid:] - INFO [main:Environment@100] - Client environment:os.version=2.6.32-696.13.2.el6.x86_64
2017-11-22 15:22:55,115 [myid:] - INFO [main:Environment@100] - Client environment:user.name=app
2017-11-22 15:22:55,115 [myid:] - INFO [main:Environment@100] - Client environment:user.home=
/home/app
2017-11-22 15:22:55,115 [myid:] - INFO [main:Environment@100] - Client environment:user.
dir
=
/home/app
2017-11-22 15:22:55,116 [myid:] - INFO [main:ZooKeeper@441] - Initiating client connection, connectString=sign-zk02.wangshibo.cn:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@594b7042
Welcome to ZooKeeper!
2017-11-22 15:22:55,136 [myid:] - INFO [main-SendThread(sign-zk02.wangshibo.cn:2181):ClientCnxn$SendThread@1035] - Opening socket connection to server sign-zk02.wangshibo.cn
/172
.16.51.199:2181. Will not attempt to authenticate using SASL (unknown error)
2017-11-22 15:22:55,140 [myid:] - INFO [main-SendThread(sign-zk02.wangshibo.cn:2181):ClientCnxn$SendThread@877] - Socket connection established to sign-zk02.wangshibo.cn
/172
.16.51.199:2181, initiating session
JLine support is enabled
[zk: sign-zk02.wangshibo.cn:2181(CONNECTING) 0] 2017-11-22 15:22:55,287 [myid:] - INFO [main-SendThread(sign-zk02.wangshibo.cn:2181):ClientCnxn$SendThread@1302] - Session establishment complete on server sign-zk02.wangshibo.cn
/172
.16.51.199:2181, sessionid = 0x2000495ce4f0000, negotiated timeout = 30000
WATCHER::
WatchedEvent state:SyncConnected
type
:None path:null
//
这一步按Enter
[zk: sign-zk02.wangshibo.cn:2181(CONNECTED) 0]
ls
/
[zookeeper]
[zk: sign-zk02.wangshibo.cn:2181(CONNECTED) 1] quit
Quitting...
2017-11-22 15:23:39,255 [myid:] - INFO [main:ZooKeeper@687] - Session: 0x2000495ce4f0000 closed
2017-11-22 15:23:39,257 [myid:] - INFO [main-EventThread:ClientCnxn$EventThread@520] - EventThread shut down
for
session: 0x2000495ce4f0000
通过上图可以看出整个zookeeper集群已经搭建并测试完成。
|
***************当你发现自己的才华撑不起野心时,就请安静下来学习吧***************
本文转自散尽浮华博客园博客,原文链接:http://www.cnblogs.com/kevingrace/p/7879390.html,如需转载请自行联系原作者