大家好,我是杰哥,上周文章
Spring Cloud(一):我与导师的对话:你真的了解zookeeper吗?
通过回忆我与导师关于zookeeper的对话,分别针对以下8点:1、ZooKeeper是什么?
2、zookeeper有哪些特性?
3、zookeeper的数据模型是怎样的?
4、znode节点的了解
5、zookeeper的watch特性
6、zookeeper的集群架构
7、zookeeper的zab协议
8、zookeeper的可靠性
进行了讨论,让大家对于zookeeper服务端的实现机制有了一定的了解
虽然文章以图文并茂的模式,让大家对于zookeeper已经了解的差不多了。但是呢,为了让大家对zookeeper看的更直观,印象更深刻,我们今天会带大家通过集群环境的搭建与具体命令的操作,来真正感受一下zookeeper的这些机制
一 初识 单机环境
单机模式的安装过程比较简单,大家可以参考官网进行搭建即可。也可以直接用docker进行部署,so easy了~
安装完成以后,我们直接进入服务器端和客户端命令实战啦~
进入bin目录,我们会看到有如下几个比较常用的命令脚本:zkServer:Zookeeper服务器的启动、停止、和重启脚本
zkCli:Zookeeper的一个简易客户端
zkCleanup:清理Zookeeper历史数据,包括事务日志文件和快照数据文件的脚本
zkEnv:设置Zookeeper环境变量的脚本
01. 服务端(Server)
1)查看命令
若不清楚服务器端如何执行命令,可以通过./zkServer进行查看
我们看到,它支持如下几个命令:
start|start-foreground|stop|restart|status|upgrade|print-cmd
分别包含启动、停止、查看状态等命令
2)启动
执行./zkServer start启动服务
我们看到,它默认使用的配置文件为/usr/local/etc/zookeeper/zoo.cfg,并且服务已成功启动
3)查看进程
执行 ps -ef|grep zookeeper,查看zookeeper进程
4)查看状态
执行./zkServer status,查看启动状态,显示模式为:standalone,表示当前启动为单机模式
02. 客户端(Client)
1)连接客户端
直接执行.zkCli,连接到zookeeper客户端
2)查看命令
通过命令 help 可以查看zookeeper客户端的所有命令
分别包含新增、查看、修改、删除等命令,各个命令的具体作用与使用也比较简单
我们分别通过演示几个常用命令
3)常用命令
a 查看根目录 ls path(类似于linux命令)
b 创建节点 create path data
c 查看节点 get path
由图中,我们可以看到:
zooKeeper中每个znode的Stat结构由以下字段组成:
czxid:导致创建此znode的更改的zxidmzxid:上次修改此znode的更改的zxidpzxid:上次修改此znode子级的更改的zxidctime:创建此znode时从纪元开始的时间(以毫秒为单位)mtime:自上次修改此znode以来的时间(以纪元为单位)dataVersion: 此znode的数据更改数cversion:此znode的子级更改的数量alcVersion:此znode的ACL的更改数ephemeralOwner:分两种情况。
- 如果当前znode是一个临时节点,则为此znode的所有者的会话ID
- 如果它不是临时节点,则它为零
dataLength:此znode的数据字段的长度numChildren:此znode的子级数
d 修改节点 set path data
再次查看节点,数据已被修改为jiegeData2
4) 验证watch监听机制
我们试试在获取节点数据时,设置监听,即采用 get path watch命令
如图所示,当我们设置获取数据时,增加了watch参数,则当我们执行修改命令 set /jiege jiegeDataForWatch 时,就会收到节点发生变化的通知
在实际生产中,我们可以通过这种监听机制,能够实时获取到某个服务器的故障或者我们比较关心的节点数据的更改(zookeeper的节点znode包含服务器节点和数据节点)
二 进阶 集群环境
01. 集群节点数量
关于zookeeper的集群环境节点,我们建议至少有三个,而且最好是奇数个,那么这是为什么呢?
让我们分析一下,ZooKeeper集群,拥有不同数量的节点时的效果
1) 如果有单个节点,那么该节点发生故障时,ZooKeeper整个集群不就挂掉了?所以说单个节点肯定很不安全。因此这种情况不建议在生产环境中使用
2)如果我们有两个节点,其中一个节点发生了故障。此时呢,剩余一个节点可用,并没有占多数,因此整个集群就不可用了
3)而当我们有三个节点,其中一个节点故障,剩余两个正常节点,即数量满足三台服务器的多数。那么集群将继续保持可用状态
因此呢,ZooKeeper集合在实际生产环境中必须至少有三个节点。
那么如果我们有四个节点,而当其中两个节点故障,它将再次故障。类似于有三个节点的情况(三个节点的集群环境,有两个节点故障,集群同样不可用)。
从成本角度讲,既然效果一样,那肯定就选择三个节点的了。
从性能角度,我们知道写入过程比ZooKeeper集群中的读取过程要贵,因为所有节点都需要在数据库中写入相同的数据。因此,对于平衡的环境拥有较少数量(例如3,5,7)的节点比拥有大量的节点要好。
所以,我们建议至少有三个,而且最好是奇数个
那么我们就来演示一下3节点的集群搭建
首先需要说明一下,我们的zookeeper的服务器节点分为机器节点和数据节点,为了 方便起见,我们分别将其简写为sZnode和 dZnode
1)数据目录配置
a 创建三个目录
在安装目录的data目录(我的电脑的data目录为/usr/local/data)下,分别新建zookeeper1,zookeeper2,zookeeper3三个目录
b 在每个目录分别新建myid文件
c 分别在myid中输入内容 1、2、3即可
2)cfg文件配置
a 分别将原有的zoo.cfg复制为zoo-1.cfg、zoo-2.cfg以及zoo-3.cfg,并删除以前的zoo.cfg文件
b 配置文件属性
分别配置文件的数据目录dataDir、端口ClientPort以及集群服务属性
针对 集群服务属性:
包含三个部分:
server.1=localhost:2887:3887server.2=localhost:2888:3888server.3=localhost:2889:3889
服务id:server.1,server.2以及server.3分别表示三个服务,对应我们在对应的myid文件中的内容
ip地址:各个节点的服务器地址。由于都是在本机进行部署,则ip都为loacalhost
两个端口:分别用来进行数据同步、leader选举
以下分别为zoo-2.cfg和zoo-3.cfg的配置
对其余两个配置文件分别参照zoo-1.cfg的配置以后,进入启动环节
3)sZnode启动
依次执行./zkServer start命令进行启动,只是此时我们将要分别使用三个不同的配置文件,启动三个服务。如要启动节点1,则执行:sudo ./bin/zkServer start /usr/local/etc/zookeeper/zoo-1.cfg进行启动
4)验证启动
执行ps -ef|grep zookeeper,查看zookeeper进程,发现三个节点均已启动
此时,可以执行命令查看各个节点的状态
5)查看状态
分别执行/zkServer status 命令(指定各个节点配置文件),查看各个节点的状态
如节点1 ,执行sudo ./bin/zkServer status /usr/local/etc/zookeeper/zoo-1.cfg进行查看
我们看到,sZnode2为leader,sZnode1和sZnode3分别为follower。也就验证了我们的zookeeper的集群架构,当有更多sZnode时,便会出现第三个角色:observer
03. 客户端连接
可以打开三个终端窗口,分别使用命令连接三个客户端
./zkCli -server 127.0.0.1:2181./zkCli -server 127.0.0.1:2182./zkCli -server 127.0.0.1:21813
第一次连接上时,查看节点,只有一个zookeeper节点
1)新建节点
在服务器节点1,新建dZnode:jiege,赋值其数据为123
分别在三个sZnode,获取该dZnode数据
a 获取sZnode1数据节点数据
b 获取sZnode2数据节点数据
c 获取sZnode3数据节点数据
我们发现,对于新建的节点,在三个服务器节点上的数据结构的各个属性完全相同。分别记录其创建信息、修改信息、子节点事务信息、版本号、数据版本号、权限列表以及数据长度、子节点的个数等。
那么,大家可以想一想,当我们在其中一个sZnode修改了该节点的值,我们的这些属性要如何变化呢?
2)验证集群同步
修改dZnode3:/jiege的数据修改为123456
此时,修改事务标识:mZxid由原来的0x100000006修改为现在的0x100000007,当然dataLength数据长度由2变成了6,数据版本dataVersion由0变成了1
分别查看其他两个sZnode的该节点数据,发现mZxid、dataVersion以及dataLength也同步发生了变化
说明当其中sZnode在节点发生变化时,也会及时把变更信息复制给其他sZnode,以保证其一致性
3)过半机制测试
分别停掉sZnode2、sZnode3两个节点
查看sZnode1的进程,发现依旧存在
但是查看sZnode1的状态,已经是不可用状态了
此时,由于过半的sZnode均已不可用,因此整个集群便会被置为不可用状态,这个时候呢,zooKeeper就会触发监听事件,我们看到sZnode的客户端,会显示为Disconnected的状态
而当我们重新启动其他任何一个sZnode,该集群将会重新恢复可用状态(满足了过半机制条件)。我们看到sZnode的客户端,状态自动重置SysncConnected状态
4)选举机制测试
停掉zookeeper2(leader),分别查看zookeeper1和zookeeper3的状态,发现此时zookeeper3的状态已变为 leader
说明,当leader节点挂掉之后,zookeeper会重新进行leader选举
好了~那么今天的命令操作,就到这里结束了~这些常用的命令很简单,由于主要想为大家演示一下zookeeper的特性,因此就演示了几个~
zookeeper还会涉及到更多的命令操作,大家可以接下来自己研究使用哈~
三 总结 总而言之
1、本篇总结:
1)基本命令
2)集群环境搭建
3)过半成功机制原理理解
4)集群架构验证
5)leader选举验证
相信这种原理加实战的方式,能够帮助大家更进一步学习到zooKeeper服务端机制。
2、服务端工作流总结
通过上一节理论以及这一节的实战操作,我们再回过头来,看一下关于zookeeper的工作流
1)leader接收到写入数据请求(客户端发出写入数据请求给任意Follower,Follower将写入数据请求转发给Leader)
2)进入广播提议的发起
3)发起广播提议给所有Follower
4)Follower接到Propose消息,写入日志
5)返回ACK消息给Leader
6)Leader接到半数以上ACK消息,返回成功给客户端,并且广播Commit请求给Follower;
7)follower接收到消息,则提交事务
是不是更深入理解啦~
温馨提示:若本文看完,对于某些理论不太熟悉的,可以通过查阅上一篇文章
Spring Cloud(一):我与导师的对话:你真的了解zookeeper吗?
吼~
嗯,就这样。每天学习一点,时间会见证你的强大~
下期预告:Spring Cloud(三):注册中心Zookeeper-客户端视角
往期精彩回顾
Spring Cloud(一):我与导师的对话:你真的了解zookeeper吗?
Spring Boot(十):注册中心Eureka-客户端视角
Spring Boot(九):注册中心Eureka-服务端视角
Spring Boot(八):Spring Boot的监控法宝:Actuator
Spring Boot(七):你不能不知道的Mybatis缓存机制!
Spring Boot(六):那些好用的数据库连接池们
Spring Boot(五):春眠不觉晓,Mybatis知多少
Spring Boot(四):让人又爱又恨的JPA
Spring Boot(三):操作数据库-Spring JDBC
SpringBoot(二):第一个Spring Boot项目
SpringBoot(一):特性概览
原创不易,您的转发与点赞是对作者最大的鼓励哦!