伪集群模式

这里我们采用的是伪集群模式,一台机器上三个节点,集群模式是一台机器上一个节点。之所以称伪集群,就是这台机器挂了,集群也就没了。集群与伪集群的方式完全一样的。

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,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么,如图

img

  • 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-01127.0.0.12181
apache-zookeeper-02127.0.0.12182
apache-zookeeper-03127.0.0.12183
# 解压移动重命名
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集群配置成功。

从节点主动升级和接管成为主节点

leaderfollower的自动切换,前面我们知道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作为了从节点。

每天努力一点,每天都在进步。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐