之前的集解文章为大家介绍过zookeeper服务部署与基础使用的相关知识,接下来本篇文章为大家介绍一下zookeeper集群架构,群架快跟着小编来学习一下吧。构详 推荐阅读: 【SRE工程师培训】zookeeper服务部署与基础使用! zookeeper服务部署与基础使用(二)!老男孩Linux培训班 zookeeper集群介绍 | 为什么搭建Zookeeper集群 大部分分布式应用需要一个主控、集解协调器或者控制器来管理物理分布的群架子进程 zookeeper作为注册中心,服务器和客户端都要访问,构详如果有大量的集解并发,肯定会有等待 所以可以通过zookeeper集群解决 下面是群架zookeeper集群部署结构图: 
| zookeeper集群的角色 Leader:领导者,一个Zookeeper集群同一时间只能有一个Leader,构详Leader服务器是集解整个Zookeeper集群工作制中的核心,其主要工作有以下: 事务请求的群架唯一调度和处理者,保证集群事务处理的构详顺序性。Zookeeper中所有事务操作都是集解由leader服务器进行处理 集群内部服务器的调用者 接受所有的Follower的提案请求并统一协调发起提案投票,负责与所有Follower进行内部数据交换(同步) Follower:跟随者,群架主要工作: 处理客户端的构详非事务请求,并转发事务请求给Leader服务器 参与事务请求的同步提交投票。同时与Leader进行数据交换(同步) 参与Leader选举投票 Observer:观察者,主要工作: 观察Zookeeper集群的源码下载最新状态变化,并将这些状态变更同步过来 对于非事务请求,可以直接独立处理,而对于事务请求,则会转发给Leader服务器进行处理。这是集群的可选组件 但obServer不参加投票过程,只同步leader的状态。obServer的目的是为了扩展系统,提高读取速度 Client:客户端: 向zookeeper集群发起连接请求的一方 zookeeper的leader选举 | zookeeper服务端状态 zookeeper服务端有以下四种常见的状态: 
| zookeeper集群启动时的leader选举 在集群初始化节点,当有一台服务器zk101启动时,其单独无法进行和完成leader选举,当第二台服务器zk102启动时,此时两台机器就可以相互通信,每台机器都试图找到leader,于是进入leader选举过程 zookeeper集群启动时期的leader选举过程如下所示: 1、每个server发出一个投票,由于初始情况,zk101和zk102都会将自己作为leader服务器来进行投票,每次投票会包含所推举的服务器myid和zxid,如下所示: 使用(myid,zxid)来表示,云南idc服务商此时zk101投票为(101,0),zk102的投票为(102,0),然后各自将跟这个投票发给集群的其它机器; 2、集群中每台服务器接收来自集群中各个服务器的投票; 3、处理投票,针对每一个投票,服务器都需要将别人的的投票和自己的投票进行pk,pk的规则如下: 对于zk101而言,它的投票是"(101,0)",接收zk102的投票为"(102,0)",首先会比较两者的zxid,均为0,再比较myid,此时zk102的myid最大,于是zk101节点需要更新自己的投票为"(102,0)" 对于zk102而言,它的投票是"(102,0)",接收zk101的免费信息发布网投票为"(101,0)",很明显zk101的myid较小,因此zk102无需更新字节的投票,只是再次向集群中所有机器上发送一次投票信息即可; a.优先检查zxid,zxid比较大的服务器优先作为leader; b.如果zxid相同,那么就比较myid,myid较大的服务器作为leader服务器; 综上所述,我们可以针对zk101和zk102选举的过程如下: 4、统计投票,每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接收到相同的投票信息,对于zk101和zk102而言,都统计出集群中已经有两台机器接收了(102,0)的投票信息,此时认为已经选出来leader; 5、改变服务器状态,一旦确定了leader,每个zookeeper服务器就会更新自己的状态,如果是follower,那么就变更为following,如果是leader,就变更为leading 温馨提示: myid:表示当前zookeeper server的server id zxid:表示zookeeper transaction id,即zookeeper事务ID 判断是否已经有过半机器接收到相同的投票信息: 假设集群可参与投票的服务器数量为N,那么过半机器数量计算方式为: (N / 2 + 1) 我们的集群只有3台,那么过半就是2台服务器 | zookeeper集群运行时的leader选举 在zookeeper运行期间,leader与非leader服务器各司其职,即便当有非leader服务器宕机或新加入,此时也不会影响leader 但是一旦leader服务器挂了,那么这个集群将暂停对外服务,当剩余节点数大于原集群半数节点时,则zookeeper集群可以进入新一轮leader选举,其过程和启动时期的leader选举过程基本一致 假设正在运行的有zk101,zk102,zk103这三台服务器,当leader是zk102,若某一时刻leader挂了,此时便开始leader选举,其过程如下: 1、变更状态,leader挂后,余下的服务器都会将自己的服务器状态变更为looking,然后开始进入leader选举过程; 2、每个server会发出一个投票,在运行期间,每个服务器上的zxid可能不同,此时假定zk101的zxid为"996",zk103的zxid为"965",在第一轮投票中,zk101和zk103都会投自己,产生投票(101,996),(103,965),然后各自将投票发送给集群中所有机器; 3、接收来自各个服务器的投票,与启动时过程相同; 4、处理投票,与启动过程相同,此时zk101将会成为leader; 5、统计投票,与启动时过程相同; 6、改变服务器的状态,与启动时过程相同; 实验环境准备 | zookeeper集群搭建概述 单机环境下,zookeeper安装完毕,我们可以基于一台虚拟机,进行zookeeper的伪分布式集群搭建,zookeeper集群中包含3个节点,例如节点对外提供服务端口号分别为2181,2182和2183 但在实际生产环境中,伪分布式并不使用,因此我们还是搭建一个完全分布式集群,这样更贴近生产环境 | 测试环境说明 
| 添加zookeeper集群的映射信息 cat > /etc/hosts <<EOF 10.0.0.101 zk101.oldboyedu.com 10.0.0.102 zk102.oldboyedu.com 10.0.0.103 zk103.oldboyedu.com EOF 
| 拷贝 /etc/hosts 文件到集群的其它节点上 scp /etc/hosts zk102.oldboyedu.com:/etc/hosts scp /etc/hosts zk103.oldboyedu.com:/etc/hosts | 安装JDK并配置环境变量 温馨提示:JDK官方的下载地址: https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html mkdir -pv /oldboyedu/softwares/ # 手动上传jdk软件包 tar xf jdk-8u301-linux-x64.tar.gz -C /oldboyedu/softwares/ ln -sv /oldboyedu/softwares/jdk1.8.0_301/ /oldboyedu/softwares/jdk # 配置jdk环境变量 cat >/etc/profile.d/jdk.sh<<EOF #!/bin/bash JAVA_HOME=/oldboyedu/softwares/jdk PATH=\$PATH:\$JAVA_HOME/bin EOF # 使环境变量生效 chmod +x /etc/profile.d/jdk.sh source /etc/profile.d/jdk.sh | 部署zookeeper并配置环境变量 # 下载zookeeper wget --no-check-certificate https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz # zookeeper软件部署 mkdir -p /oldboyedu/softwares tar xf apache-zookeeper-3.7.1-bin.tar.gz -C /oldboyedu/softwares/ ln -sv /oldboyedu/softwares/apache-zookeeper-3.7.1-bin/ /oldboyedu/softwares/zookeeper # 配置zookeeper环境变量 cat >/etc/profile.d/zookeeper.sh<<EOF #!/bin/bash ZK_HOME=/oldboyedu/softwares/zookeeper PATH=\$PATH:\$ZK_HOME/bin EOF # 使环境变量生效 chmod +x /etc/profile.d/zookeeper.sh source /etc/profile.d/zookeeper.sh # 创建zookeeper用户并指定家目录 mkdir -p /oldboyedu/data useradd -d /oldboyedu/data/zookeeper zookeeper chown -R zookeeper. /oldboyedu/softwares/apache-zookeeper-3.7.1-bin/ # 配置zookeeper服务 cp /oldboyedu/softwares/apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg /oldboyedu/softwares/apache-zookeeper-3.7.1-bin/conf/zoo.cfg sed -ri s#(dataDir=)/tmp/zookeeper#\1/oldboyedu/data/zookeeper# /oldboyedu/softwares/apache-zookeeper-3.7.1-bin/conf/zoo.cfg | 配置免密登录 ssh-keygen -t rsa -f ~/.ssh/id_rsa -P # 拷贝密钥 ssh-copy-id root@zk101.oldboyedu.com ssh-copy-id root@zk102.oldboyedu.com ssh-copy-id root@zk103.oldboyedu.com | 关闭防火墙 sed -i s#SELINUX=enforcing#SELINUX=disabled# /etc/selinux/config systemctl stop firewalld systemctl disable firewalld zookeeper集群构建 | 修改zookeeper的配置文件 zookeeper-101的配置 # egrep -v "^#|^$" /oldboyedu/softwares/zookeeper/conf/zoo.cfg tickTime=2000 initLimit=5 syncLimit=2 dataDir=/oldboyedu/data/zookeeper clientPort=2181 clientPortAddress=10.0.0.101 server.101=zk101.oldboyedu.com:2888:3888 server.102=zk102.oldboyedu.com:2888:3888 server.103=zk103.oldboyedu.com:2888:3888 zookeeper-102的配置 # egrep -v "^#|^$" /oldboyedu/softwares/zookeeper/conf/zoo.cfg tickTime=2000 initLimit=5 syncLimit=2 dataDir=/oldboyedu/data/zookeeper clientPort=2181 clientPortAddress=10.0.0.102 server.101=zk101.oldboyedu.com:2888:3888 server.102=zk102.oldboyedu.com:2888:3888 server.103=zk103.oldboyedu.com:2888:3888 zookeeper-103的配置 # egrep -v "^#|^$" /oldboyedu/softwares/zookeeper/conf/zoo.cfg tickTime=2000 initLimit=5 syncLimit=2 dataDir=/oldboyedu/data/zookeeper clientPort=2181 clientPortAddress=10.0.0.103 server.101=zk101.oldboyedu.com:2888:3888 server.102=zk102.oldboyedu.com:2888:3888 server.103=zk103.oldboyedu.com:2888:3888 | 创建配置zookeeper的堆内存配置文件 cat >/oldboyedu/softwares/zookeeper/conf/java.env<<EOF #!/bin/bash #指定JDK的安装路径 export JAVA_HOME=/oldboyedu/softwares/jdk #指定zookeeper的heap内存大小 export JVMFLAGS="-Xms256m -Xmx256m \$JVMFLAGS" EOF # 查看JDK的堆内存大小: jmap -heap "java进程的PID" | 编写zookeeper的启动脚本 cat >/oldboyedu/softwares/zookeeper/bin/manager-zk.sh<<EOF #!/bin/bash # 判断用户是否传参 if [ \$# -ne 1 ];then echo "无效参数,用法为: \$0 {start|stop|restart|status}" exit fi # 获取用户输入的命令 cmd=\$1 # 定义函数功能 function zookeeperManger(){ case \$cmd in start) echo "启动服务" remoteExecution start ;; stop) echo "停止服务" remoteExecution stop ;; restart) echo "重启服务" remoteExecution restart ;; status) echo "查看状态" remoteExecution status ;; *) echo "无效参数,用法为: \$0 {start|stop|restart|status}" ;; esac } # 定义执行的命令 function remoteExecution(){ for (( i=101 ; i<=103 ; i++ )) ; do tput setaf 2 echo ========== zk\${i}.oldboyedu.com zkServer.sh \$1 ================ tput setaf 9 ssh zk\${i}.oldboyedu.com "source /etc/profile.d/zookeeper.sh; zkServer.sh \$1" done } # 调用函数 zookeeperManger EOF chmod +x /oldboyedu/softwares/zookeeper/bin/manager-zk.sh 温馨提示: 该脚本为串行的脚本,建议改为并行执行的脚本,生产环境中建议改为并行的脚本,或者直接使用ansible来实现管理也可以哟~ | 创建myid文件并写入服务器编号 for (( i=101;i<=103;i++ )) do ssh zk${i}.oldboyedu.com "echo -n $i > /oldboyedu/data/zookeeper/myid" ;done | 查看zookeeper服务 manager-zk.sh status 
| 启动zookeeper服务 manager-zk.sh start manager-zk.sh status 
| 连接zookeeper集群 zkCli.sh -server "leader服务器的IP:2181" observer角色及其配置 | observer角色特点 observer角色特点如下所示: 不参与集群的leader选举; 不参与集群中写数据时的ack反馈; | 修改配置文件 # egrep -v "^#|^$" /oldboyedu/softwares/zookeeper/conf/zoo.cfg tickTime=2000 initLimit=5 syncLimit=2 dataDir=/oldboyedu/data/zookeeper clientPort=2181 clientPortAddress=10.0.0.101 peerType=observer server.101=zk101.oldboyedu.com:2888:3888:observer server.102=zk102.oldboyedu.com:2888:3888 server.103=zk103.oldboyedu.com:2888:3888 温馨提示: 如果我们将某个节点(本案例为zookeeper-101节点)的配置文件中存在"peerType=observer"时,请将"server.101"哪行配置追加":observer" | 重启集群 manager-zk.sh restart 
| 查看集群状态 manager-zk.sh status 
| 连接observer节点 zkCli.sh -server 10.0.0.101:2181 zookeeper监控命令 | zookeeper常用四字命令 
| 部署命令行工具 yum -y install nc telnet | 配置白名单 # egrep -v "^#|^$" /oldboyedu/softwares/zookeeper/conf/zoo.cfg ··· 4lw.commands.whitelist=* ··· # manager-zk.sh restart # 修改以后记得重启服务使之生效! | 基于telnet查看zookeeper集群的状态信息 # telnet zk101.oldboyedu.com 2181 Trying 10.0.0.101... Connected to zk101.oldboyedu.com. Escape character is ^]. conf 
| 基于nc查看zookeeper集群的状态信息 echo conf | nc zk101.oldboyedu.com 2181 
ZkWeb管理zookeeper集群 | 下载zkWeb wget https://github.com/zhitom/zkweb/releases/download/zkWeb-v1.2.1/zkWeb-v1.2.1.jar | 启动zkWeb java -jar zkWeb-v1.2.1.jar | 浏览器访问 浏览器访问启动zkWeb的服务器,端口为8099 http://10.0.0.101:8099 
|