10分钟快速了解zookeeper

1.3 Zookeeper的架构

Zookeeper本身就时一个文件存储系统:Zookeeper内部存储着大量的znode,每一个znode节点都可以有多个子节点,每一个znode都可以单独的存储数据。

  • 持久的znode:永久的保存在Zookeeper
  • 持久有序的znode:永久的保存在Zookeeper。添加节点时,自动在节点名称后追加一个有序的序号。
  • 临时的znode:客户端和Zookeeper服务断开连接后,当前znode自动删除。
  • 临时有序的znode:客户端和Zookeeper服务断开连接后,当前znode自动删除。添加节点时,自动在节点名称后追加一个有序的序号。

Zookeeper提供的监听通知机制:客户端可以监听Zookeeper服务中的znode,在znode改变时,Zookeeper会通知所有监听的客户端。

1.4 Zookeeper常用命令
1.5 Zookeeper集群的架构&投票机制

Zookeeper集群架构:

  • Zookeeper的集群是有Leader的。
  • Leader宕机后,Zookeeper集群不会对外提供功能。
  • Zookeeper内部会存在投票机制,重新选举一个Leader。
  • Leader可以执行读写的操作。
  • Slave可以执行读的操作。

Zookeeper集群节点的解决:

  • Leader:
    • 执行处理读和写的操作。
    • Leader是唯一可以处理写操作的, 并且在执行写操作时,会根据一个FIFO的队列来保证写数据的顺序性。
    • 其他节点的唯一调度者。
  • Follower:
    • 执行读操作。
    • 在执行写操作时,进行投票。
    • 在重新选举Leader时,会参与投票。
  • Observer:
    • 执行读操作。
  • Looking:
    • 在Zookeeper节点刚刚启动时,寻找Leader。

Zookeeper集群的选举策略:

  • 选举数据最新的节点,根据数据的zxid判断。
  • 如果zxid相同,根据myid决定Leader。
1.6 搭建Zookeeper集群
# 当前3.4.14的版本, 不需要指定;2181,如果采用最新zookeeper,需要添加;2181
version: "3.1"
services:
  zk1:
    image: 10.0.134.175:5000/zookeeper:3.4.14
    container_name: zk1
    restart: always
    ports:
      - 2181:2181
    environment:
      ZOO_MY_ID: 1
      ZOO_SERVERS: server.1=zk1:2888:3888 server.2=zk2:2888:3888 server.3=zk3:2888:3888 
  zk2:
    image: 10.0.134.175:5000/zookeeper:3.4.14
    container_name: zk2
    restart: always
    ports:
      - 2182:2181
    environment:
      ZOO_MY_ID: 2
      ZOO_SERVERS: server.1=zk1:2888:3888 server.2=zk2:2888:3888 server.3=zk3:2888:3888 
  zk3:
    image: 10.0.134.175:5000/zookeeper:3.4.14
    container_name: zk3
    restart: always
    ports:
      - 2183:2181
    environment:
      ZOO_MY_ID: 3
      ZOO_SERVERS: server.1=zk1:2888:3888 server.2=zk2:2888:3888 server.3=zk3:2888:3888       
1.7 Java操作Zookeeper
  • 导入依赖

    • <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.4.14</version>
      </dependency>
      <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-recipes</artifactId>
      <version>4.2.0</version>
      </dependency>
      


  • Java连接Zookeeper

    • public static CuratorFramework cf(){
      //1. 指定重试策略   3秒重试一次,一共重试2次.
      RetryPolicy retry = new ExponentialBackoffRetry(1000,2);
      

//2. 成功构建出链接Zookeeper的对象
CuratorFramework cf = CuratorFrameworkFactory.builder()
.connectString("10.0.131.23:2181,10.0.131.23:2182,10.0.131.23:2183")
.retryPolicy(retry)
.build();

//3. 开启cf
cf.start();

//4. 返回
return cf;

}
  • Java操作Zookeeper

    • public class Demo1 {
      

@Test
public void getChildren() throws Exception {
CuratorFramework cf = ZkUtil.cf();

List znodeList = cf.getChildren().forPath("/");

for (String s : znodeList) {
System.out.println(s);
}

cf.close();
}

@Test
public void create() throws Exception {
CuratorFramework cf = ZkUtil.cf();

cf.create().withMode(CreateMode.PERSISTENT).forPath("/qf",“哈哈哈”.getBytes());

cf.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/qf2",“嘿嘿嘿”.getBytes());

cf.create().withMode(CreateMode.EPHEMERAL).forPath("/qf3",“看不见我”.getBytes());

cf.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/qf4",“看不见我”.getBytes());

cf.close();
}

@Test
public void getData() throws Exception {
CuratorFramework cf = ZkUtil.cf();

byte[] bytes = cf.getData().forPath("/qf");
System.out.println(new String(bytes,“UTF-8”));

cf.close();
}



@Test
public void setData() throws Exception {
CuratorFramework cf = ZkUtil.cf();

cf.setData().forPath("/qf","嘻嘻嘻".getBytes());

cf.delete().deletingChildrenIfNeeded().forPath("/qf20000000002");

Stat stat = cf.checkExists().forPath("/cluster");
System.out.println(stat);

cf.close();
}



}
  • Zookeeper的监听通知机制

    • @Test
      public void listener() throws Exception {
      CuratorFramework cf = ZkUtil.cf();
      

NodeCache nodeCache = new NodeCache(cf,"/qf");

nodeCache.getListenable().addListener(new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
// 在监听的节点改变后,获取节点信息
byte[] data = nodeCache.getCurrentData().getData();
String path = nodeCache.getCurrentData().getPath();
Stat stat = nodeCache.getCurrentData().getStat();
System.out.println(“监听的是:” + path + ",现在数据为: " + new String(data,“UTF-8”) + ",当前节点状态信息: " + stat );
}
});

// !!!开始监听!!!
nodeCache.start();
System.out.println(“开始监听!!!”);

System.in.read();

cf.close();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值