Zookeeper 集群模式一共有三种类型的角色
Step1:配置JAVA环境,检验环境:保证是jdk7 及以上即可
java ‐version
Step2:下载并解压zookeeper
wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper‐3.5.9/apache‐zookeep er‐3.5.9‐bin.tar.gz
#如果无法通过wget下载,可以先下载到本地,在上传到服务器上
tar ‐zxvf apache‐zookeeper‐3.5.9‐bin.tar.gz
cd apache‐zookeeper‐3.5.9‐bin
Step3:重命名 zoo_sample.cfg文件
cp conf/zoo_sample.cfg conf/zoo‐1.cfg
Step4:修改配置文件zoo-1.cfg,原配置文件里有的,修改成下面的值,没有的则加上
1 # vim conf/zoo‐1.cfg
2 dataDir=/usr/local/data/zookeeper‐1
3 clientPort=2181
4 server.1=127.0.0.1:2001:3001:participant// participant 可以不用写,默认就是part icipant
5 server.2=127.0.0.1:2002:3002:participant
6 server.3=127.0.0.1:2003:3003:participant
7 server.4=127.0.0.1:2004:3004:observer
server.A=B:C:D:E 其中 A 是一个数字,表示这个是第几号服务器;B 是这个服 务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新 的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给 它们分配不同的端口号。如果需要通过添加不参与集群选举以及事务请求的过半机制的 Observer节点,可以在E的位置,添加observer标识。
Step5:再从zoo-1.cfg复制三个配置文件zoo-2.cfg,zoo-3.cfg和zoo-4.cfg,只需修改 dataDir和clientPort不同即可
1 cp conf/zoo1.cfg conf/zoo2.cfg
2 cp conf/zoo1.cfg conf/zoo3.cfg
3 cp conf/zoo1.cfg conf/zoo4.cfg
4
5 vim conf/zoo2.cfg
6 dataDir=/usr/local/data/zookeeper2
7 clientPort=2182
8 vim conf/zoo3.cfg
9 dataDir=/usr/local/data/zookeeper3
10 clientPort=2183
11 vim conf/zoo4.cfg
12 dataDir=/usr/local/data/zookeeper4
13 clientPort=2184
Step6:标识Server ID
创建四个文件夹/usr/local/data/zookeeper1,/usr/local/data/zookeeper2,/usr/local/data/zookeeper3,/usr/local/data/zookeeper4,在每个目录中创建文件 myid 文件,写入当前实例的server id,即1,2,3,4
1 cd /usr/local/data/zookeeper1
2 vim myid
3 1
4 cd /usr/local/data/zookeeper2
5 vim myid
6 2
7 cd /usr/local/data/zookeeper3
8 vim myid
9 3
10 cd /usr/local/data/zookeeper4
11 vim myid
12 4
Step7:启动三个zookeeper实例
1 bin/zkServer.sh start conf/zoo1.cfg
2 bin/zkServer.sh start conf/zoo2.cfg
3 bin/zkServer.sh start conf/zoo3.cfg
Step8:检测集群状态,也可以直接用命令 zkServer.sh status conf/zoo1.cfg 进行每台服务 的状态查询
bin/zkCli.sh ‐server ip1:port1,ip2:port2,ip3:port3
可以通过 查看/zookeeper/config 节点数据来查看集群配置。
PS:Zookeeper3.5.0添加了新特性:集群动态配置
在"双机热备"高可用(HA)系统中,当联系两个节点的"心跳线"断开时(即两个节点断开联系时),本来为一个整体、动作协调的HA系统,就分裂成为两个独立的节点(即两个独立的个体)。由于相互失去了联系,都以为是对方出了故障,两个节点上的HA软件像"裂脑人"一样,“本能"地争抢"共享资源”、争起"应用服务"。就会发生严重后果:1)或者共享资源被瓜分、两边"服务"都起不来了;2)或者两边"服务"都起来了,但同时读写"共享存储",导致数据损坏(常见如数据库轮询着的联机日志出错)。
zookeeper容错指的是:当宕掉几个zookeeper节点服务器之后,剩下的个数必须大于宕掉的个数,也就是剩下的节点服务数必须大于n/2,这样zookeeper集群才可以继续使用,无论奇偶数都可以选举leader。例如5台zookeeper节点机器最多宕掉2台,还可以继续使用,因为剩下3台大于5/2。至于为什么最好为奇数个节点?这样是为了以最大容错服务器个数的条件下,能节省资源。比如,最大容错为2的情况下,对应的zookeeper服务数,奇数为5,而偶数为6,也就是6个zookeeper服务的情况下最多能宕掉2个服务,所以从节约资源的角度看,没必要部署6(偶数)个zookeeper服务节点。
zookeeper集群有这样一个特性:集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的。也就是说如果有2个zookeeper节点,那么只要有1个zookeeper节点死了,那么zookeeper服务就不能用了,因为1没有过半,所以2个zookeeper的死亡容忍度为0;同理,要是有3个zookeeper,一个死了,还剩下2个正常的,过半了,所以3个zookeeper的容忍度为1;同理也可以多列举几个:2->0; 3->1; 4->1; 5->2; 6->2 就会发现一个规律,2n和2n-1的容忍度是一样的,都是n-1,所以为了更加高效,何必增加那一个不必要的zookeeper呢。所以说,根据以上可以得出结论:从资源节省的角度来考虑,zookeeper集群的节点最好要部署成奇数个!
要解决Split-Brain脑裂的问题,一般有下面几种种方法:
Quorums (法定人数) 方式: 比如3个节点的集群,Quorums = 2, 也就是说集群可以容忍1个节点失效,这时候还能选举出1个lead,集群还可用。比如4个节点的集群,它的Quorums = 3,Quorums要超过3,相当于集群的容忍度还是1,如果2个节点失效,那么整个集群还是无效的。这是zookeeper防止"脑裂"默认采用的方法。
采用Redundant communications (冗余通信)方式:集群中采用多种通信方式,防止一种通信方式失效导致集群中的节点无法通信。
Fencing (共享资源) 方式:比如能看到共享资源就表示在集群中,能够获得共享资源的锁的就是Leader,看不到共享资源的,就不在集群中。
仲裁机制方式。
启动磁盘锁定方式。
要想避免zookeeper"脑裂"情况其实也很简单,在follower节点切换的时候不在检查到老的leader节点出现问题后马上切换,而是在休眠一段足够的时间,确保老的leader已经获知变更并且做了相关的shutdown清理工作了然后再注册成为master就能避免这类问题了,这个休眠时间一般定义为与zookeeper定义的超时时间就够了,但是这段时间内系统可能是不可用的,但是相对于数据不一致的后果来说还是值得的
PS:过半选举和集群服务个数为奇数其实就是为了避免脑裂问题。