Zookeeper部署与使用

1 分布式安装部署

配置服务器编号

在.../zkData文件目录下创建myid文件,并写入服务器编号

[root@hadoop101 apache-zookeeper-3.5.10-bin]# cd zkData/
[root@hadoop101 zkData]# 1 > myid
bash: 1: 未找到命令...
[root@hadoop101 zkData]# echo 1 > myid

其他的两台服务器分别写为2 3

增加zoo.cfg集群配置参数
##############cluster##############
server.1=192.168.60.101:2888:3888
server.2=192.168.60.102:2888:3888
server.3=192.168.60.103:2888:3888

配置参数解读 server.A=B:C:D

  • A是一个数字,表示是第几号服务器。

    Zookeeper启动的时候会先读取dataDir目录下的myid文件,拿到里面的数据与zoo.cfg里面的配置信息对比从而判断到底是那个server

  • B是这个服务器的ip地址。

  • C是这个服务器与Leader服务器交换同步副本信息的端口号。

  • D是当Leader宕机后,这个服务器与其他服务器通信交换选举信息的端口号。

2 启动集群服务器

先启动一台服务器,会发现由于半数机制,Zookeeper没有启动成功

[root@hadoop101 bin]# ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/module/apache-zookeeper-3.5.10-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@hadoop101 bin]# jps
33904 QuorumPeerMain
34066 Jps
[root@hadoop101 bin]# ./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/module/apache-zookeeper-3.5.10-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Error contacting service. It is probably not running.

这时候再启动二号机,一号机就会变成Follower,二号机成为Leader

[root@hadoop101 bin]# ./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/module/apache-zookeeper-3.5.10-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower

3 启动集群客户端和命令

./zkcli.sh

shell命令

  • 显示所有操作: help

  • 查看当前znode中包含的内容:ls

  • 查看当前znode中包含的详细内容:ls2

  • 创建普通节点:create

    [zk: localhost:2181(CONNECTED) 5] create /sanguo
    Created /sanguo
    [zk: localhost:2181(CONNECTED) 6] create /sanguo/shuguo "liubei"
    Created /sanguo/shuguo
    [zk: localhost:2181(CONNECTED) 7] get /sanguo
    null
    [zk: localhost:2181(CONNECTED) 8] get /sanguo/shuguo
    liubei
  • 获取节点内容:get

  • 创建短暂节点:create -e,客户端退出后则消失:

    [zk: localhost:2181(CONNECTED) 9] create -e /sanguo/wuguo "sunquan"
    Created /sanguo/wuguo
    [zk: localhost:2181(CONNECTED) 10] get /sanguo/wuguo
    sunquan
    [zk: localhost:2181(CONNECTED) 11] quit
    [zk: localhost:2181(CONNECTED) 0] ls /sanguo
    [shuguo]
  • 创建带序号的节点:create -s

    [zk: localhost:2181(CONNECTED) 0] ls /sanguo
    [shuguo]
    [zk: localhost:2181(CONNECTED) 1] create /sanguo/weiguo "caocao"
    Created /sanguo/weiguo
    [zk: localhost:2181(CONNECTED) 2] create -s /sanguo/weiguo "caocao"
    Created /sanguo/weiguo0000000003
    [zk: localhost:2181(CONNECTED) 3] create -s /sanguo/weiguo "caocao"
    Created /sanguo/weiguo0000000004
    [zk: localhost:2181(CONNECTED) 4] create -s /sanguo/weiguo "caocao"
    Created /sanguo/weiguo0000000005
    [zk: localhost:2181(CONNECTED) 5] ls /sanguo
    [shuguo, weiguo, weiguo0000000003, weiguo0000000004, weiguo0000000005]

    会自动为节点添加编号,没有则从0开始,否则编号顺序添加后有几个节点则编号就为几

  • 修改节点的值:set

    [zk: localhost:2181(CONNECTED) 6] set /sanguo/weiguo "simayi"
    [zk: localhost:2181(CONNECTED) 7] get /sanguo/weiguo
    weiguo weiguo0000000003 weiguo0000000004 weiguo0000000005
    [zk: localhost:2181(CONNECTED) 7] get /sanguo/weiguo
    simayi
  • 节点值的变化监听:get -w

    [zk: localhost:2181(CONNECTED) 4] get -w /sanguo
    null
    [zk: localhost:2181(CONNECTED) 5]
    WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/sanguo

    watch监听只能生效一次

  • 节点路径监听:ls -w

    [zk: localhost:2181(CONNECTED) 8] ls -w /sanguo
    [shuguo, weiguo, weiguo0000000003, weiguo0000000004, weiguo0000000005, wuguo]
    [zk: localhost:2181(CONNECTED) 9]
    WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo

    如果只创建节点而不存值的话是监听不到的

  • 删除节点:delete

    [zk: localhost:2181(CONNECTED) 11] delete /sanguo/weiguo
    weiguo weiguo0000000003 weiguo0000000004 weiguo0000000005
    [zk: localhost:2181(CONNECTED) 11] delete /sanguo/weiguo
  • 递归删除:deleteall

    [zk: localhost:2181(CONNECTED) 12] delete /sanguo
    Node not empty: /sanguo
    [zk: localhost:2181(CONNECTED) 13] rmr /sanguo
    The command 'rmr' has been deprecated. Please use 'deleteall' instead.
    [zk: localhost:2181(CONNECTED) 14] deleteall /sanguo
    Node does not exist: /sanguo
    [zk: localhost:2181(CONNECTED) 15] ls /
    [zookeeper]

4 ️API的使用

引入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.8.1</version>
</dependency> </dependencies>
创建客户端

使用构造函数创建Zookeeper客户端对象,参数为:

  1. ip地址+端口号(集群之间使用逗号隔开,不能添加空格)
  2. 会话超时时间
  3. watcher匿名内部类,包含一个process方法,即一个监听器对象
public class ZookeeperTest {

    // Zookeeper客户端器的ip和端口号
private String connectString = "192.168.60.101:2181,192.168.60.102:2181,192.168.60.103:2181";
// 会话超时时间
private int sessionTimeOut = 2000; @Test
public void test1() throws IOException {
ZooKeeper zkCli = new ZooKeeper(connectString, sessionTimeOut, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) { }
});
}
}
20:08:20.001 [main] INFO org.apache.zookeeper.ZooKeeper - Initiating client connection, connectString=192.168.60.101:2181,192.168.60.102:2181,192.168.60.103:2181 sessionTimeout=2000 watcher=com.hikaru.ZookeeperTest$1@50cbc42f
创建节点
public class ZookeeperTest {

    // Zookeeper客户端器的ip和端口号
private String connectString = "192.168.60.101:2181,192.168.60.102:2181,192.168.60.103:2181";
// 会话超时时间
private int sessionTimeOut = 2000; private ZooKeeper zkCli; @Before
public void test1() throws IOException {
zkCli = new ZooKeeper(connectString, sessionTimeOut, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) { }
});
} @Test
public void createNodeTest() throws KeeperException, InterruptedException {
String path = zkCli.create("/zhanguo", "ZhenTianXingCun".getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(path);
}
}
[zk: localhost:2181(CONNECTED) 11] get /zhanguo
ZhenTianXingCun
获取子节点并监听数据变化

查询节点

    @Test
public void getDataAndWatchTest() throws KeeperException, InterruptedException {
List<String> children = zkCli.getChildren("/", false);
for(String child : children) {
System.out.println(child);
}
}
zookeeper
zhanguo

查询并监控

@Test
public void getDataAndWatchTest() throws KeeperException, InterruptedException {
List<String> children = zkCli.getChildren("/", true);
for(String child : children) {
System.out.println(child);
} Thread.sleep(Long.MAX_VALUE);
}
21:09:45.568 [main-SendThread(192.168.60.101:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Got notification session id: 0x100001a97080003
21:09:45.569 [main-SendThread(192.168.60.101:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Got WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/ for session id 0x100001a97080003
判断节点是否存在
@Test
public void exist() throws KeeperException, InterruptedException {
Stat exists = zkCli.exists("/zhanguo", false);
System.out.println(exists);
}

️服务器节点动态上下线案例分析

  • 需求:客户端能实时洞察到服务器上下线的变化

  • 分析:相对于Zookeeper集群,服务器端和客户端都是“客户端”:服务端需要向集群写数据,客户端则需要监视数据

  • 服务器启动的时候就去注册信息,此时在Zookeeper创建的都是临时节点
  • 客户端启动就去getChildren,获取当前在线服务器列表,并注册监听(注册实际上就是创建一个节点)
  • 服务器下线的时候就会通知客户端

️代码实现

如上面所说的,这里的服务器和客户端是相对于我们开发人员接触到的分布式微服务而言的,下面实现的本质是依靠Zookeeper客户端实现server注册(本质即在Zookeeper集群创建节点)和数据监听(本质监听Zookeeper集群)

  • 服务器注册代码实现,比较简单不再赘述,需要注意一点创建的节点应该是带序号的临时节点
public class DistributeServer {
// Zookeeper客户端器的ip和端口号
private String connectString = "192.168.60.101:2181,192.168.60.102:2181,192.168.60.103:2181";
// 会话超时时间
private int sessionTimeOut = 2000; private ZooKeeper zkCli; public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
DistributeServer distributeServer = new DistributeServer();
// 1 server连接集群
distributeServer.connect(); // 2 server注册
distributeServer.register(args); // 3 业务逻辑
distributeServer.services();
} private void services() throws InterruptedException {
Thread.sleep(Long.MAX_VALUE);
} private void register(String[] hosts) throws KeeperException, InterruptedException {
for(String host : hosts) {
zkCli.create("/servers/server", host.getBytes(StandardCharsets.UTF_8),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
}
} private void connect() throws IOException {
this.zkCli = new ZooKeeper(connectString, sessionTimeOut, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) { }
});
}
}
  • 客户端监听代码实现

    1. 首先客户端连接Zookeeper集群,并进行注册监听
    2. 注册监听会首先利用Zookeeper客户端获取并监听持久节点/services下面的子节点,子节点的值对应一台服务器,如此便获取到全部节点信息
    3. 每当节点信息发生变动则会触发process()方法,继续注册一次监听并实时获取全部节点信息(这样做的目的是监听只能生效一次)
public class DistributeClient {
// Zookeeper客户端器的ip和端口号
private String connectString = "192.168.60.101:2181,192.168.60.102:2181,192.168.60.103:2181";
// 会话超时时间
private int sessionTimeOut = 3000; private ZooKeeper zkCli; public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
DistributeClient distributeClient = new DistributeClient();
// 1 客户端连接集群
distributeClient.connect(); // 2 Client注册监听
distributeClient.watch(); // 3 业务逻辑
distributeClient.services();
} private void services() throws InterruptedException {
Thread.sleep(Long.MAX_VALUE);
} private void watch() throws KeeperException, InterruptedException {
List<String> children = zkCli.getChildren("/servers", true); List<String> serversOnline = new ArrayList<>(); for(String child : children) {
byte[] host = zkCli.getData("/servers/" + child, false, null);
serversOnline.add(new String(host));
} System.out.println(serversOnline);
} private void connect() throws IOException {
this.zkCli = new ZooKeeper(connectString, sessionTimeOut, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
try {
watch();
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
});
}
}

【Zookeeper】(三)部署与使用、服务器节点动态上下线案例分析的更多相关文章

  1. ZooKeeper之服务器动态上下线案例

    需求 某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线. 需求分析 具体实现 先在集群上创建/servers节点 create /servers &q ...

  2. 大数据学习day11------hbase_day01----1. zk的监控机制,2动态感知服务上下线案例 3.HDFS-HA的高可用基本的工作原理 4. HDFS-HA的配置详解 5. HBASE(简介,安装,shell客户端,java客户端)

    1. ZK的监控机制 1.1 监听数据的变化  (1)监听一次 public class ChangeDataWacher { public static void main(String[] arg ...

  3. 基于Nginx dyups模块的站点动态上下线并实现简单服务治理

    简介 今天主要讨论一下,对于分布式服务,站点如何平滑的上下线问题. 分布式服务 在分布式服务下,我们会用nginx做负载均衡, 业务站点访问某服务站点的时候, 统一走nginx, 然后nginx根据一 ...

  4. 第三次个人作业——关于K米(Andorid)的案例分析

    第三次个人作业--关于K米(Andorid)的案例分析 1.K米简介 官方网址:http://www.ktvme.com/ 2.评测 2.1.上手体验 带着找bug的心态,兴致勃勃地开始体验 K米.打 ...

  5. 程序windows上可以上传附件,部署到 linux服务器后出现 “上传目录 不可写” 怎么解决?

    这样的问题一般都是linux  下文件读写权限引起的,用 shell  命名到上传附件的目录(如 cd /data/www/project/upload/),然后执行 shell 文件权限设置: 例如 ...

  6. Zookeeper(三) Zookeeper原理与应用

    一.zookeeper原理解析 1.进群角色描述 2.Paxos 算法概述( ZAB 协议)    分布式一致性算法 3.Zookeeper 的选主(恢复模式) 以一个简单的例子来说明整个选举的过程. ...

  7. 基于nginx实现上游服务器动态自动上下线——不需reload

    网上关于nginx的介绍有很多,这里讲述的是上游服务(如下图的Java1服务)在没有"网关"的情况下,如何通过nginx做到动态上下线. 传统的做法是,手动修改nginx的upst ...

  8. 学习笔记:Zookeeper 应用案例(上下线动态感知)

    1.Zookeeper 应用案例(上下线动态感知) 8.1 案例1--服务器上下线动态感知 8.1.1 需求描述 某分布式系统中,主节点可以有多台,可以动态上下线 任意一台客户端都能实时感知到主节点服 ...

  9. FME2010 案例分析: 动态批量转换

    Link: http://blog.163.com/antufme@126/blog/static/140492492201022545726452/?suggestedreading&wum ...

  10. zookeeper三种模式安装详解(centos 7+zookeeper-3.4.9)

    zookeeper有单机.伪集群.集群三种部署方式,可根据自己实际情况选择合适的部署方式.下边对这三种部署方式逐一进行讲解. 一 单机模式 1.下载 进入要下载的版本的目录,选择.tar.gz文件下载 ...

随机推荐

  1. C语言初级阶段5——函数1

    C语言初级阶段5--函数1 函数的基本概念 1.函数:理解为封装功能的容器. 主函数是函数的入口 2.函数定义的基本格式: 返回值类型:常用的基本数据类型,执行完以后,函数会得到一个什么类型的值,如果 ...

  2. jsp第7个作业

      MailService package mail.service; import java.util.List; import mail.dao.DaoFactory; import mail.d ...

  3. 装了google浏览器不代表就能使用google搜索

    第一步:装google浏览器 第二步:连接外网(FQ的本质就是连接一个服务器) 第三步:输入网址google.com 跳转到此页面即成功 现在的想法是

  4. SQL Server获取连接的IP地址

    来源:http://www.itpub.net/thread-193247-1-1.html 先保存,以后研究一下 1 *--获取连接SQL服务器的信息 2 3 所有连接本机的:操作的数据库名,计算机 ...

  5. SpringBoot多数据源yaml配置

    1.配置多数据源 pom文件 <dependency> <groupId>com.baomidou</groupId> <artifactId>dyna ...

  6. 简介及spring mvc初体验

    一.C\S和B\S C/S C/S 是 Client/Server 的简写,简称客户端/服务器模式.例如 QQ 是客户端和服务器模式,首先安装一个客户端到个人电脑,然后登入到腾讯服务器. 缺点:更新不 ...

  7. Docker部署【项目管理和问题跟踪工具-Redmine】

    创建网络 docker network create redmine-network 启动Mysql数据库 docker run -d --name mysql --network redmine-n ...

  8. 制作带curl命令的容器

    创建一个容器,启动后使用curl命令请求指定的地址 方法一.固定的地址,创建Dockerfile前先修改entrypoint.sh里的地址 vi entrypoint.sh#! /bin/bashcu ...

  9. MarkDown学习day1

    # Markdown学习 ## 标题: #+"空格"+标题名字 为一级为标题 ##+"空格"+标题名字 为二级标题 同理几级标题就是几个#,最多支持6级标题 # ...

  10. Java8-聚合操作

    Java聚合操作(Aggregate Operations)是对一堆数据进行处理的新的操作方法,我们知道,如果想对一堆数据进行处理,比如一个List对象中的数据进行处理,传统的操作就是遍历List数据 ...