搜索

zookeeper集群架构详解!

发表于 2025-11-05 03:10:35 来源:益强智未来

  之前的集解文章为大家介绍过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

随机为您推荐
版权声明:本站资源均来自互联网,如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

Copyright © 2016 Powered by zookeeper集群架构详解!,益强智未来  滇ICP备2023006006号-17sitemap

回顶部