当前位置:主页 > 查看内容

Zookeeper入门

发布时间:2021-06-11 00:00| 位朋友查看

简介:Zookeeper的理解 Zookeeper是开源的高性能的分布式应用协调系统 一个高性能的分布式数据一致性解决方案 为什么使用Zookeeper 集群 可靠 解决了单机不可靠的问题为了保持可靠性 当信息还没有同步完成时 不对外提供服务 提供的数据是最新且准确的同步的时间比……
Zookeeper的理解


Zookeeper是开源的高性能的分布式应用协调系统
一个高性能的分布式数据一致性解决方案


为什么使用Zookeeper


集群 可靠 解决了单机不可靠的问题为了保持可靠性 当信息还没有同步完成时 不对外提供服务 提供的数据是最新且准确的同步的时间比较短 分布式协调好 好像一个“单机”一样


Zookeeper的特点


顺序一致性:发送消息的的顺序一致原子性 集群内同步消息时的原子性单一视图 在一个集群中无论连接哪一个 看到的都是一致的可靠性 直到被改变都保持不变及时性 一定时间内保证客户端能从服务器拿到最新状态


image


当client发送一个请求时 由从节点发给leader处理 然后同步给其他节点


CAP


一致性 C可用性 A分区容错性 可理解为网络错误 一定会发生 P


Zookeeper和CAP的关系


CP 一致性 分区容错性
能得到一致的数据结果 同时系统对网络具备容错性
但是它不能保证每次服务请求的可用性 网络不好时可能会丢弃一些请求


作用


分布式服务注册与订阅统一配置文件 当一个配置修改后可以通过Watcher机制进行通知image生成分布式唯一ID 顺序节点imageMaster节点选举 创捷有编号的节点 且不能重复image分布式锁

目的 数据的最终一致性

访问资源获得锁 判断锁是否已经被占用 是否已经有了一个事先约定好的节点 如果已被占用 等待释放await CountDownLatch 、如果没被占用 创建zk节点 节点使用同一个名字 要是非持久性的锁、当前线程拥有该锁、业务处理完毕 释放锁。



Linux安装


安装一个最新的安装包 wget https://downloads.apache.org/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz

解压 tar zxvf apache-zookeeper-3.7.0-bin.tar.gz


注 不进行配置初次运行会报错

配置 cd apache-z ookeeper-3.7.0-bin cp conf/zoo_sample.cfg conf/zoo.cfg

vi conf/zoo.cfg 把内容修改为 ? ??? ??? ??? ??? ?

?tickTime 2000 默认

dataDir /var/lib/zookeeper

clientPort 2181 默认

启动 ./bin/zkServer.sh start 停止 ./bin/zkServer.sh stop


注 启动和停止都要在Zookeeper的bin目录下

windows 下安装


下载 zookeeper
网址 https://zookeeper.apache.org/releases.html 下载 最新版本 解压 zookeeper
解压运行 zkServer.cmd 初次运行会报错 没有 zoo.cfg 配置文件 修改 zoo.cfg 配置文件
将 conf 下的 zoo_sample.cfg 复制一份改名为 zoo.cfg 即可。


注意几个重要位置
dataDir ./ 临时数据存储的目录 可写相对路径 clientPort 2181 zookeeper 的端口号2181
修改完成后再次启动 zookeeper 运行 zkServer.cmd


节点znode


是一个树结构 类似linux的文件系统


image


每一个节点都是znode 里面可以包含数据 也可以有子节点 节点可以分为永久节点和临时节点 session失效 也就是客户端断开后 临时节点消失 每个znode都有版本号 每当数据变化 版本号会累加 乐观锁
使用中删除或者修改节点 版本号不匹配报错 节点存储的数据不宜过大 ? 会降低性能。比如可以存redis的key或者文件的路径 节点可以设置权限 来限制用户的访问 读和写都是原子操作 每次都是对数据的完整读取和完整写入


节点类型 创建时就已经确定 不可更改类型


持久节点 PERSISTENT临时节点 PERSISTENT_SEQUENTIAL 维护服务发现顺序节点 EPEMERAL 持久和临时节点都可以时顺序或者非顺序的 生成唯一ID


节点版本属性


dataVersion ?: 当数据更改时 1cversion 当子节点改变 1aclVersion 当权限改变 1


常用命令linux下


启动: ./bin/zkServer/.sh start 连接Server ./bin/zkCli.sh -server 127.0.0.1 2181 查看子节点 ls path 查看节点状态 stat path 查看节点的数据 ?get path 创建修改删除节点
create [-s] [-e] path [data] ?不支持创建多级目录 ? -s 顺序 -e 临时
set [-s] [-v version] ?path data ? -v version 乐观锁 多线程操作时
delete [-v version] path ?有子节点不允许删除


Watcher机制


触发器。监督者 当客户端注册以后 如果触发了Watcher机制 zookeeper将自动进行对客户端的通知 而不是需要客户端对服务端进行轮询确认。 image使用场景 统一资源配置Watcher的监听类型如下 image


ACL权限控制


access control list权限控制 类似shiro它使用权限位来允许/禁止对节list点及其所作用域的各种操作ACL仅与特定的znode有关 与子节点无关

ACL权限控制格式


[scheme采用的权限机制:id用户:permissions权限组合字符串]
权限机制 world、auth 明文 、digest 加密 、ip 常用 、super 最高权限
权限字符串crdwa
Create、Read、Delete、Write、Admin 最高


使用场景


区分开发 测试 运维环境 防止误操作可以针对不同的IP而产生具体的配置 更安全


Demo


原生Java的Api的缺点


不支持连接超时后的自动重连Watcher注册一次后会失效 触发后不支持递归创建节点


使用Apache Curator工具类


解决Watcher注册一次后失效的问题API更加简单易用


1.引入依赖


 dependency 
 groupId org.apache.zookeeper /groupId 
 artifactId zookeeper /artifactId 
 /dependency 
 dependency 
 groupId org.apache.curator /groupId 
 artifactId curator-framework /artifactId 
 /dependency 
 dependency 
 groupId org.apache.curator /groupId 
 artifactId curator-recipes /artifactId 
 /dependency 


2.测试demo


/**
 * 描述 用Curator来操作ZK
public class CuratorTests {
 public static void main(String[] args) throws Exception {
 // 配置zookeeper地址
 String connectString 127.0.0.1:2181 ;
 // 节点路径
 String path test/curator ;
 // 连接重试策略
 RetryPolicy retry new ExponentialBackoffRetry(1000, 3);
 CuratorFramework client CuratorFrameworkFactory.newClient(connectString, retry);
 // 启动 服务
 client.start();
 // 设置watcher 监听机制
 client.getCuratorListenable().addListener((CuratorFramework c, CuratorEvent event) - {
 switch (event.getType()) {
 case WATCHED:
 WatchedEvent watchedEvent event.getWatchedEvent();
 if (watchedEvent.getType() EventType.NodeDataChanged) {
 System.out.println(new String(c.getData().forPath(path)));
 String data test ;
 String data2 test2 ;
 // 创建一个节点
 client.create().withMode(CreateMode.PERSISTENT).forPath(path, data.getBytes());
 // 获取节点数据
 byte[] bytes client.getData().watched().forPath(path);
 System.out.println(new String(bytes));
 // 修改一个节点
 client.setData().forPath(path, data2.getBytes());
 // 删除一个节点
 client.delete().forPath(path);
 Thread.sleep(2000);
}

本文转自网络,原文链接:https://developer.aliyun.com/article/784648
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文

  • 周排行
  • 月排行
  • 总排行

随机推荐