大数据技术之Zookeeper概述(第六篇)

前言
传统系统的问题:

系统中的单点的风险,单点崩溃,整个系统就不能用了。
传统单点解决方案:利用协调软件进行双击热备。
传统主备协调方案的认识:
协调软件本身不是分布式的,只能配置一个。
只能一个主一个备
初识Zookeeper
1.概述
1.1 Zookeeper定义
Zookeeper是google的Chubby的一个开源实现
Zookeeper:是Apache组织下的高性能,分布式的应用协调服务框架

Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应,从而实现集群中类似Master/Slave管理模式

Zookeeper=文件系统+监视通知机制

1.2 特点
1)最终一致性

2)原子

3)可靠

4)实时

5)顺序

6)单一视图

1.3 Zookeeper主备协调的实现

1)通过Zookeeper提供的两个重要特性
2)主备协调利用上面提到的临时ZNode与通知
3)支持Zookeeper协调的灵魂
1.3.1 Zookeeper提供的两个重要特性

特性1:文件系统
层级树形结构
每个节点称作ZNode
每个节点由/分割
什么是Znode呢?

定义:Znode是Zookeeper存储数据的数据单元。

Znode用来组织存储数据,它有3种类型。

持久ZNode:在Zookeeper中创建的Znode是永久存在的。
临时ZNode:客户端断开即删除的Znode。
顺序ZNode:是指为避免创建的Znode名字冲突而在名字后追加10位顺序数字的Znode。
ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode。

很显然zookeeper集群自身维护了一套数据结构。这个存储结构是一个树形结构,其上的每一个节点,我们称之为”znode”,每一个znode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识


特性2:通知(监视)
Watcher

定义:watcher是仿效观察者模式实现的Zookeeper的事件通知机制。
监听的内容:
1)ZNode数据变化
2)Znode删除事件
3)子目录节点增加删除事件

1.3.2 主备协调利用上面提到的临时ZNode与通知
1.3.3支持Zookeeper协调的灵魂
Zookeeper的协议

Paxos协议
是什么呢?
一个基于消息传递的一致性算法
基于Paxos实现的Zookeeper特点:
1)最终一致性
是指分布式系统中数据的多个副本在经过一段时间后,最终会达到一致状态的特性。
2)原子
是指更新数据只能成功或者失败,没有中间状态的特性
3)可靠
是指在ZooKeeper中,如果消息被一台服务器接受,那么它将被所有服务器接受的特性。
4)实时
是指Zookeeper能保证客户端得到刚更新的数据的特性。
5)顺序
是指在ZooKeeper中同一个消息发布顺序一致的特性
6)单一视图

基于Paxos实现的Zookeeper角色:
领导者(Leader):是负责进行投票的发起和决议,更新系统状态的Zookeeper角色
学习者(Learner):
跟随者Follower:是接收客户请求并向客户端返回结果且在选主过程中参与投票的Zookeeper角色。
观察者Observer:是接受客户端连接,将写请求转发给Leader节点,不参与投票且同步Leader状态的Zookeeper角色。
客户端(Client):请求发起方

zab协议:
广播模式–选举出来leader,对外提供服务
恢复模式—选举leader,也就是4大状态存在
原子广播:
通过投票确定某一件事能不能做(过半原则—zookeeper最好是奇数)
1.提交请求到follower,follower会将请求发送给leader
2.leader将请求下发给所有的follower,F来判断,并将结果返回给L
3.L将请求写入的文件分发到所有的follower------(最终一致性–及时在写入的过程中有节点连接不上,当恢复的时候还会把节点上写入数据)
选举机制:
id----serverid(设置的myid)
zxid-----(股份)
逻辑时钟------每个一个周期回加1(根据逻辑时钟判断我当前选举的状态)

2. Zookeeper安装与命令操作
2.1 部署Zookeeper服务器的数量要求
    1)小于等于255个节点
    2)奇数节点
1
2
3
2.2 Zookeeper3种安装模式
    1)单级模式
    2)伪分布模式
    3)安全分布模式
1
2
3
4
**2.3 Zookeeper操作**
    1)命令操作
    2)程序操作
1
2
3
2.3.1.1命令操作

默认启动命令客户端—zkCli.sh

启动连接指定的Zookeepeer----zkCli.sh -server ip:port

Zookeeper命令:

Zookeeper状态:

zkServer.sh status
1
显示指定路径下的内容:

ls  路径
1
创建临时节点,用quit命令退出或结束,会话节点消失:

create -e /name1  zhangsan1
1
创建顺序节点:

create -s  /name2 zhangsan2
1
创建临时顺序节点:

creae -e -s  /name3  zhangsan3
1
通过名字获取节点:

get /name2
1
删除指定名字的节点:

delete("/name1",-1);
1
修改节点内容:

set    /name1    lisi
1
2.3.2.1 通过eclipse创建连接
Eclipse开发环境
通过指定端口与ip创建Zookeeper客户端对象

ZooKeeper client = new  ZooKeeper("172.16.245.5:2181",1000, null);
1
创建节点,/name

String create = client.create("/name", "zhangsan".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
1
创建子节点,/name/sex

public class TestZ {
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper client = new ZooKeeper("172.16.245.5:2181"/*链接字符串*/, 1000, null);
byte[] data = client.getData(“/name/sex”/*指定节点*/, true, null);
String db = new String(data);//将获取的数据转换为字符串
System.out.println(db);//打印字符串
}
}

获取节点内容,“/name/sex”的内容

import java.io.IOException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
public class TestZ {
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper client = new ZooKeeper("172.16.245.5:2181"/*链接字符串*/, 1000, null);
byte[] data = client.getData(“/name/sex”/*指定节点*/, true, null);
String db = new String(data);//将获取的数据转换为字符串
System.out.println(db);//打印字符串
}
}

删除指定节点,“/name1111”

import java.io.IOException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
public class TestZ {
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper client = new ZooKeeper("172.16.245.5:2181"/*链接字符串*/, 1000, null);
client.delete("/name1111", -1);
}
}

设定指定节点内容,“/namewjf”的内容为22222

import java.io.IOException;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
public class Testset {
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
// TODO Auto-generated method stub
ZooKeeper zk = new ZooKeeper("172.16.245.5:2181", 1000, null);
zk.setData("/namewjf", "222222".getBytes(), zk.exists("/namewjf", true).getVersion()/*znode当前版本*/);
}
}

获取子节点

import java.io.IOException;
import java.util.List;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
public class testgetchild {public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper client = new ZooKeeper("172.16.245.5:2181"/*链接字符串*/, 1000, null);
List<String> list = client.getChildren("/name", true);
for(String str:list){
System.out.println(str);
}
}
}

设置监听机制:(当的znode发生变化的时候,监听一下,但是只能监听一次)
1、设置 setData getChildren
2、启动 delete exits create、getData

监听指定节点/name

public class TestWatcher implements Watcher{
//watcher只有在长链接的情况下才起作用,而且只能监听一次。
private static final int SESSION_TIMEOUT=1000;
private ZooKeeper zk = null;
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper client = new ZooKeeper("172.16.245.5:2181"/*链接字符串*/, 1000, null);
byte[] bs = client.getData("/name", new TestWatcher(), null);
System.out.println(new String(bs));
Thread.sleep(Long.MAX_VALUE);
}
//监听到指定的目录有变化,会触发此方法
@Override
public void process(WatchedEvent event) {
System.out.println(event.getPath());
}
}
--------------------- 
作者:夜、那么美จุ๊บ 
来源:CSDN 
原文:https://blog.csdn.net/AdamAaron/article/details/92799910 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值