伪集群模式
这里我们采用的是伪集群模式,一台机器上三个节点,集群模式是一台机器上一个节点。之所以称伪集群,就是这台机器挂了,集群也就没了。集群与伪集群的方式完全一样的。
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)选举和投票的结果。
选举机制
- 1、半数机制:集群中半数以上机器存活,集群可用。所以Zookeeper适合安装奇数台服务器。
- 2、需要给每个zookeeper 1G左右的内存,如果可能的话,最好有独立的磁盘,因为独立磁盘可以确保zookeeper是高性能的。如果你的集群负载很重,不要把zookeeper和RegionServer运行在同一台机器上面,就像DataNodes和TaskTrackers一样。
- 3、Zookeeper虽然在配置文件中并没有指定Master和Slave。但是,Zookeeper工作时,是有一个节点为Leader,其他则为Follower,Leader是通过内部的选举机制临时产生的。
- 4、以一个简单的例子来说明整个选举的过程。 假设有五台服务器组成的Zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么,如图
- 1、服务器1启动,此时只有它一台服务器启动了,它发出去的报文没有任何响应,所以它的选举状态一直是LOOKING状态。
- 2、服务器2启动,它与最开始启动的服务器1进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以id值较大的服务器2胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例子中的半数以上是3),所以服务器1、2还是继续保持LOOKING状态。
- 3、服务器3启动,根据前面的理论分析,服务器3成为服务器1、2、3中的老大,而与上面不同的是,此时有三台服务器选举了它,所以它成为了这次选举的Leader。
- 4、服务器4启动,根据前面的分析,理论上服务器4应该是服务器1、2、3、4中最大的,但是由于前面已经有半数以上的服务器选举了服务器3,所以它只能接收当小弟的命了。
- 5、服务器5启动,同4一样当小弟。
集群规划
机器编号 | Ip 地址 | 端口 |
apache-zookeeper-01 | 127.0.0.1 | 2181 |
apache-zookeeper-02 | 127.0.0.1 | 2182 |
apache-zookeeper-03 | 127.0.0.1 | 2183 |
# 解压移动重命名
mkdir -p /data/zk/
tar xf apache-zookeeper-3.6.3-bin.tar.gz
mv apache-zookeeper-3.6.3-bin /data/zk/zookeeper1
cp -r /data/zk/zookeeper1 /data/zk/zookeeper2
cp -r /data/zk/zookeeper1 /data/zk/zookeeper3
# 创建节点存放的数据和日志目录和myid标示
mkdir -p /data/zkdata/zkdata1/logs
mkdir -p /data/zkdata/zkdata2/logs
mkdir -p /data/zkdata/zkdata3/logs
echo "1" > /data/zkdata/zkdata1/myid
echo "2" > /data/zkdata/zkdata1/myid
echo "3" > /data/zkdata/zkdata1/myid
# 配置文件(基本默认不动,只用修改数据目录和日志目录和添加下server节点)
cd /data/zk/zookeeper1/
cp conf/zoo_sample.cfg conf/zoo.cfg
cd /data/zk/zookeeper2/
cp conf/zoo_sample.cfg conf/zoo.cfg
cd /data/zk/zookeeper3/
cp conf/zoo_sample.cfg conf/zoo.cfg
节点配置文件修改
# zookeeper3.5版本后提供了jetty默认后台管理8080端口,访问地址为:http://localhost:8081/commands/stat
# 同一台机器上启动多个节点会有冲突,解决办法:
# 启动脚本中修改 -Dzookeeper.admin.serverPort=xxx
# zoo.cfg配置文件中 修改配置admin.serverPort=xxx
# -Dzookeeper.admin.enableServer=false 在启动脚本中关闭管理控制台
# 修改节点1配置文件
vim conf/zoo.cfg
dataDir=/data/zkdata/zkdata1/
dataLogDir=/data/zkdata/zkdata1/logs
clientPort=2181
admin.serverPort=8081
server.1=192.168.16.206:2881:3881
server.2=192.168.16.206:2882:3882
server.3=192.168.16.206:2883:3883
# 修改节点2配置文件
vim conf/zoo.cfg
dataDir=/data/zkdata/zkdata2/
dataLogDir=/data/zkdata/zkdata2/logs
clientPort=2182
admin.serverPort=8082
server.1=192.168.16.206:2881:3881
server.2=192.168.16.206:2882:3882
server.3=192.168.16.206:2883:3883
# 修改节点3配置文件
vim conf/zoo.cfg
dataDir=/data/zkdata/zkdata3/
dataLogDir=/data/zkdata/zkdata3/logs
clientPort=2183
admin.serverPort=8083
server.1=192.168.16.206:2881:3881
server.2=192.168.16.206:2882:3882
server.3=192.168.16.206:2883:3883
分别启动zookeeper的3个节点
# 启动
/data/zk/zookeeper1/bin/zkServer.sh start
/data/zk/zookeeper2/bin/zkServer.sh start
/data/zk/zookeeper3/bin/zkServer.sh start
# 查看状态
/data/zk/zookeeper1/bin/zkServer.sh status
/data/zk/zookeeper2/bin/zkServer.sh status
/data/zk/zookeeper3/bin/zkServer.sh status
# 停止
/data/zk/zookeeper1/bin/zkServer.sh stop
/data/zk/zookeeper2/bin/zkServer.sh stop
/data/zk/zookeeper3/bin/zkServer.sh stop
# 重启
/data/zk/zookeeper1/bin/zkServer.sh restart
/data/zk/zookeeper2/bin/zkServer.sh restart
/data/zk/zookeeper3/bin/zkServer.sh restart
多机联合测试
c1运行结果:
[root@sso conf]# /var/local/server/zookeeper/bin/zkServer.sh status
JMX enabled by default
Using config: /var/local/server/zookeeper/bin/../conf/zoo.cfg
Mode: leader
c2运行结果:
[root@cas zookeeper]# /var/local/server/zookeeper/bin/zkServer.sh status
JMX enabled by default
Using config: /var/local/server/zookeeper/bin/../conf/zoo.cfg
Mode: follower
c3运行结果:
[root@localhost zookeeper]# /var/local/server/zookeeper/bin/zkServer.sh status
JMX enabled by default
Using config: /var/local/server/zookeeper/bin/../conf/zoo.cfg
Mode: follower
同步测试
c1上执行:create /c1project c1projecttest 和
get /c1project
[zk: c1:2181(CONNECTED) 2] create /c1project c1projecttest
Created /c1project
[zk: c1:2181(CONNECTED) 1] get /c1project
c1projecttest
cZxid = 0x100000013
ctime = Thu Aug 25 11:03:49 CST 2016
mZxid = 0x100000013
mtime = Thu Aug 25 11:03:49 CST 2016
pZxid = 0x100000013
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 13
numChildren = 0
c2上查看同步结果:get /c1project
[zk: c2:2181(CONNECTED) 0] get /c1project
c1projecttest
cZxid = 0x100000013
ctime = Thu Aug 25 11:03:49 CST 2016
mZxid = 0x100000013
mtime = Thu Aug 25 11:03:49 CST 2016
pZxid = 0x100000013
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 13
numChildren = 0
c3上查看同步结果: get /c1project
[zk: c3:2181(CONNECTED) 4] get /c1project
c1projecttest
cZxid = 0x100000013
ctime = Thu Aug 25 11:03:49 CST 2016
mZxid = 0x100000013
mtime = Thu Aug 25 11:03:49 CST 2016
pZxid = 0x100000013
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 13
numChildren = 0
此时说明zookeeper集群配置成功。
从节点主动升级和接管成为主节点
leader
和follower
的自动切换,前面我们知道c1是leader
,当leader
down掉后是否有从节点升级为leader
。
c1上执行
/var/local/server/zookeeper/bin/zkServer.sh stop
c2上查看状态
[root@cas ~]# /var/local/server/zookeeper/bin/zkServer.sh status
JMX enabled by default
Using config: /var/local/server/zookeeper/bin/../conf/zoo.cfg
Mode: follower
可以发现c2仍然为从节点
再看看c3
[root@localhost ~]# /var/local/server/zookeeper/bin/zkServer.sh status
JMX enabled by default
Using config: /var/local/server/zookeeper/bin/../conf/zoo.cfg
Mode: leader
此时c3升级为了主节点。
再次启动c1,并查看状态
[root@sso conf]# /var/local/server/zookeeper/bin/zkServer.sh start
JMX enabled by default
Using config: /var/local/server/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@sso conf]#
[root@sso conf]# /var/local/server/zookeeper/bin/zkServer.sh status
JMX enabled by default
Using config: /var/local/server/zookeeper/bin/../conf/zoo.cfg
Mode: follower
发现c1作为了从节点。