领诺科技网站建设,优秀网名,阳江网红打卡点,百度优化网站建设为什么要使用Zookeeper
dubbo需要一个注册中心#xff0c;而Zookeeper是我们在使用Dubbo是官方推荐的注册中心
Zookeeper介绍 Zookeeper的集群机制 Zookeeper是为了其他分布式程序提供服务的#xff0c;所以不能随便就挂了。Zookeeper的集群机制采取的是半数存活机制。也…为什么要使用Zookeeper
dubbo需要一个注册中心而Zookeeper是我们在使用Dubbo是官方推荐的注册中心
Zookeeper介绍 Zookeeper的集群机制 Zookeeper是为了其他分布式程序提供服务的所以不能随便就挂了。Zookeeper的集群机制采取的是半数存活机制。也就是整个集群节点中有半数以上的节点存活那么整个集群环境可用。这也是为什么说zk的集群最好是奇数个节点。
zk的作用
序号功能1为别的分布式程序服务的2本身就是一个分布式程序3主从协调 服务器节点动态上下线 统一配置管理 分布式共享锁 统一名称服务4管理存储读取用户程序提交的数据 并为用户程序提供数据节点监听服务
Zookeeper集群节点的角色
Leader Leader是Zookeeper集群工作的核心其主要工作是
事务请求的唯一调度和处理者保证集群事务处理的顺序性。集群内部各服务器的调度者
Follower Follower是zookeeper集群的跟随者主要工作是
处理客户端非事务性请求读取数据转发事务请求给Leader服务器参与事务请求Proposal的投票参与Leader选举投票
Observer Observer充当观察者的角色观察Zookeeper集群的最小状态变化并将这些状态同步过来其对于非事务请求可以独立处理对于事务请求会转给Leader节点进行处理。Observer不会参与投票包括事务请求Proposal的投票和Leader选举投票
集群环境准备
节点的映射关系
每个节点设置相应的ip和主机名的映射关系方便集群环境的部署 修改hosts配置文件中的信息
配置免密登录 生成公钥和私钥
ssh-keygen输入命令后根据提示四次回车即可
发送公钥给需要免密登录的节点
ssh-copy-id zk01
ssh-copy-id zk02
ssh-copy-id zk03节点和节点发送文件通过scp命令实现 scp -r b.txt bobo01:/root/关闭防火墙 查看防火墙状态
firewall-cmd --state停止防火墙
systemctl stop firewall.service禁止开机启动
systemctl disable firewall.serviceZookeeper的选举机制
Leader主要作用是保证分布式数据一致性即每个节点的存储的数据同步。
服务器初始化时Leader选举 Zookeeper由于自身的性质一般建议选取奇数个节点进行搭建分布式服务器集群。以3个节点组成的服务器集群为例说明服务器初始化时的选举过程。启动第一台安装Zookeeper的节点时无法单独进行选举启动第二台时两节点之间进行通信开始选举Leader。
每个Server投出一票。第一次他们都投给自己作为Leader投票内容未SIDZXID。 SID为Server的id即启动ZK时配置文件中的myid ZXID为事务id为节点的更新程序ZXID越大代表Server对ZK节点的操作越新。由于服务器初始化 每个Sever上的Znode为0所以Server1投的票为1,0Server2为2,0。两Server将各自投票发给集群中其他机器。每个Server接收来自其他Server的投票。集群中的每个Server先判断投票的有效性如检查是不是本轮的投票是不是来Looking状态的服务器投的票。对投票结果进行处理。处理规则为 首先对比ZXID。ZXID大的服务器优先作为Leader若ZXID系统如初始化时每个Server的ZXID都是0就会比较sid即myidmyid大的选出来做Leader。 首次选举对于Server而言他接受到的投票为2,0因为自身的票为1,0所以此时它会选举Server2为Leader 将自己的更新为2,0。而Server2收到的投票为Server1的1,0由于比他自己小 Server2的投票不变。Server1和Server2再次将票投出投出的票都为2,0 统计投票。每次投票后服务器都会统计投票信息如果判定某个Server有过半的票数俺么该Server就是Leader。首次投票对于Server1和Server2而言,统计出已经有两台机器接收了2,0的投票信息此时认为选出了Leader。改变服务器的状态。当确定了Leader之后每个Server更新自己的状态 Leader将状态更新为LeadingFollower将状态更新为Following。 服务器运行期间的Leader选举 ZK运行期间如果有新的Server加入或非Leader节点挂了那么LEader会同步数据给新的Server或寻找其他备用Server替代宕机的Server。若Leader宕机此时集群暂停对外服务开始在内部选举新的Leader。假设当前集群中有Server1、Server2、Server3三台服务器Server2为当前集群的Leader由于意外情况Server2宕机了便开始进入选举状态。过程如下
1 变更状态。其他非Observer服务器将自己的状态改变成Looking开始进入Leader选举。 2. 每个Server投出1张票myidZXID由于集群运行过所以每个Server的ZXID可能不同。 假设Server1的ZXID为145Server3的为122第一轮投票中Server1和Server3都投自己 票分别为1145、3,122,将自己的票发送给集群中所有机器。 3. 每个Server接收接收来自其他Server的投票接下来的步骤与初始化时相同。
Zookeeper客户端使用
配置Zookeeper的环境变量 为了简化我们每次操作Zookeeper而不用进入到Zookeeper的安装目录我们可以将Zookeeper的安装信息配置到系统的环境变量中
vim /etc/profile添加的内容
export ZOOKEPPER_HOME/opt/zookeeper
export PATH$PATH:$ZOOKEEPER_HOME/bin执行source命令
source /etc/profile我们就可以在节点的任意位置操作Zookeeper了通过scp命令将profile文件发送到其他几个节点上
scp /etc/profile zk02:/etc/客户端连接 通过bin目录下的zkCli.sh 命令连接即可 zkCli.shzkCli.sh默认连接的是当前节点的Zookeeper节点如果我们要连接其他节点执行如下命令即可 zkCli.sh -timeout 5000 -server zk02:2181数据操作
Zookeeper的数据结构
层次化的目录结构命名符合常规文件系统规范每个节点在Zookeeper中叫做znode并且有一个唯一的路径标识节点znode可以包含数据和子节点但是EPHEMERAL类型的节点不能有子节点客户端应用可以在节点上设置监听器
节点类型
1).znode有两种类型
短暂性ephemeral断开连接自己删除 持久性persistent断开连接不删除
2).znode有四种形式的目录节点默认是persistent如下
序号节点类型描述1PERSISTENT持久节点2PERSISTENT_SEQUENTIAL持久有序节点顺序节点3EPHEMERAL短暂节点 临时节点4EPHEMERAL_SEQUENTIAL短暂有序节点 临时顺序节点
创建znode时设置顺序标识znode名称后会附加一个值顺序号是一个单调递增的计数器有父节点维护在分布式系统中顺序号可以被用于为所有的事件进行全局排序这样客户端可以通过顺序号推断事件的顺序
常用命令 Zookeeper作为Dubbo的注册中心用来保存我们各个服务的节点信息显示Zookeeper是可以实现输出的存储操作的我们来看下Zookeeper中存储操作的基本命令
ls ls用来查看某个节点下的子节点信息 增强的命令查看节点下的子节点及当前节点的属性信息 ls2或者 ls -s 命令 create 创建节点信息 get
get命令用来查看节点的数据 如果要查看节点的属性信息那么我们可以通过get -s 来实现
delete delete只能删除没有子节点的节点要删除非空节点可以通过 rmr 或者 deleteall 命令实现 set
set命令可以用来修改节点的内容。 事件监听 监听某个节点的数据内容变化通过get命令 带 -w 参数即可在3.4版本的Zookeeper中是通过 get path watch 来说实现监控的 然后我们在其他节点上修改app1节点的数据会触监听事件
Zookeeper Java API使用
pom
dependenciesdependencygroupIdorg.apache.zookeeper/groupIdartifactIdzookeeper/artifactIdversion3.5.9/version/dependencydependencygroupIdcom.github.sgroschupf/groupIdartifactIdzkclient/artifactIdversion0.1/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/version/dependency/dependencies连接ZK服务 private String connectString 192.168.100.121:2181,192.168.122:2181,192.168.100.122:2181;private int sessionTimeOut 5000;/*** 连接Zookeeper服务端*/Testpublic void test1() throws IOException {ZooKeeper zooKeeper new ZooKeeper(connectString, sessionTimeOut, new Watcher() {/*** 触发监听事件的回调方法* param watchedEvent*/Overridepublic void process(WatchedEvent watchedEvent) {System.out.println(触发了.....);}});System.out.println(--- zooKeeper);}/*** 创建节点*/Testpublic void createNode() throws Exception{String path zooKeeper.create(/apptest // 节点路径,HelloZookeeper.getBytes() // 节点的数据, ZooDefs.Ids.OPEN_ACL_UNSAFE // 权限, CreateMode.PERSISTENT // 节点类型);System.out.println(path);}/*** 判断节点是否存在*/Testpublic void exist() throws Exception{// true表示的是使用Zookeeper中的watchStat stat zooKeeper.exists(/apptest, true);if(stat ! null){System.out.println(节点存在 stat.getNumChildren());}else{System.out.println(节点不存在 ....);}}/*** 获取某个节点下面的所有的子节点*/Testpublic void getChildrens() throws Exception{ListString childrens zooKeeper.getChildren(/app1, true);for (String children : childrens) {// System.out.println(children);// 获取子节点中的数据byte[] data zooKeeper.getData(/app1/ children, false, null);System.out.println(children: new String(data));}}/*** 修改节点的内容*/Testpublic void setData() throws Exception{// -1 不指定版本 自动维护Stat stat zooKeeper.setData(/app1/a1, 666666.getBytes(), -1);System.out.println(stat);}/*** 删除节点*/Testpublic void deleteNode() throws Exception{zooKeeper.delete(/app1,-1);}事件监听处理
/*** 监听Node节点下的子节点的变化*/Testpublic void nodeChildrenChange() throws Exception{ListString list zooKeeper.getChildren(/app1, new Watcher() {/*** None(-1),* NodeCreated(1),* NodeDeleted(2),* NodeDataChanged(3),* NodeChildrenChanged(4),* DataWatchRemoved(5),* ChildWatchRemoved(6);* param watchedEvent*/Overridepublic void process(WatchedEvent watchedEvent) {System.out.println(--- watchedEvent.getType());}});for (String s : list) {System.out.println(s);}Thread.sleep(Integer.MAX_VALUE);}/*** 监听节点内容变更*/Testpublic void nodeDataChanged() throws Exception{byte[] data zooKeeper.getData(/app1/a1, new Watcher() {Overridepublic void process(WatchedEvent watchedEvent) {System.out.println(--- watchedEvent.getType());}}, null);System.out.println(--- new String(data));Thread.sleep(Integer.MAX_VALUE);}