zookeeper ---- Curator 高级应用

监听器

        ZooKeeper原生的API支持通过注册Watcher来进行事件监听,但是Watcher通知是一次性的,因此开发过程中需要反复注册Watcher,比较繁琐。Curator引入了Cache来监听ZooKeeper服务端的事件。Cache对ZooKeeper事件监听进行了封装,能够自动处理反复注册监听,简化了ZooKeeper原生API繁琐的开发过程。

    Curator框架提供了三种Watcher(Cache) 来监听节点的变化.

        1. Path Cache : 监视路径 1) 子节点的创建, 2)删除, 3) 以及节点数据的更新. 产生的事件会传递给注册的PathChildrenCacheListener.

        2. Node Cache : 监视一个节点的创建, 更新, 删除, 并将节点的数据缓存在本地.

        3 Tree Cache : Path Cache 和Node Cache 的"合体", 监视路径下的创建, 更新, 删除事件, 并缓存路径下所有孩子节点的数据.

代码示例

package com.nxcjh.hadoop.examples.zookeeper.curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
import org.apache.curator.retry.RetryNTimes;

/**
 * Curator framework watch test.
 */
public class CuratorWatcherTest {

    /** Zookeeper info */
    private static final String ZK_ADDRESS = "10.17.110.25:2181,10.17.110.32:2181,10.17.110.36:2181";

    private static final String ZK_PATH = "/zktest";

    public static void main(String[] args) throws Exception {
        // 1.Connect to zk
        CuratorFramework client = CuratorFrameworkFactory.newClient(ZK_ADDRESS,new RetryNTimes(10, 5000));
        client.start();
        System.out.println("zk client start successfully!");

        // 2.Register watcher
        PathChildrenCache watcher = new PathChildrenCache(client,ZK_PATH,true);//true 缓存本地
        watcher.getListenable().addListener(new PathChildrenCacheListener() {
			
			@Override
			public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
				ChildData data = event.getData();
	            if (data == null) {
	                System.out.println("No data in event[" + event + "]");
	            } else {
	                System.out.println("Receive event: "
	                        + "type=[" + event.getType() + "]"
	                        + ", path=[" + data.getPath() + "]"
	                        + ", data=[" + new String(data.getData()) + "]"
	                        + ", stat=[" + data.getStat() + "]");
	            }
				
			}
		});
        watcher.start(StartMode.BUILD_INITIAL_CACHE);
        System.out.println("Register zk watcher successfully!");

        Thread.sleep(Integer.MAX_VALUE);
    }

}

实例二

package com.nxcjh.hadoop.examples.zookeeper.curator;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
import org.apache.curator.retry.ExponentialBackoffRetry;
 
/**
 * Curator事件监听
 * @author 
 *
 */
 public class CarutorDemo {
 
	 private static final String ZK_ADDRESS = "10.17.110.25:2181,10.17.110.32:2181,10.17.110.36:2181";
     public static void main(String[] args) throws Exception {
         CuratorFramework client = CuratorFrameworkFactory.builder()
             .connectString(ZK_ADDRESS)
             .sessionTimeoutMs(5000)
             .connectionTimeoutMs(3000)
             .retryPolicy(new ExponentialBackoffRetry(1000, 3))
             .build();
         client.start();
         
         client.create()
             .creatingParentsIfNeeded()
             .forPath("/zktest/cnode", "hello".getBytes());
         
         /**
          * 在注册监听器的时候,如果传入此参数,当事件触发时,逻辑由线程池处理
          */
         ExecutorService pool = Executors.newFixedThreadPool(2);
         
         /**
          * 监听数据节点的变化情况
          */
         final NodeCache nodeCache = new NodeCache(client, "/zktest/cnode", false);
         nodeCache.start(true);
         nodeCache.getListenable().addListener(
             new NodeCacheListener() {
                 @Override
                 public void nodeChanged() throws Exception {
                     System.out.println("Node data is changed, new data: " + 
                         new String(nodeCache.getCurrentData().getData()));
                 }
             }, 
             pool
         );
         
         /**
          * 监听子节点的变化情况
          */
         final PathChildrenCache childrenCache = new PathChildrenCache(client, "/zktest", true);
         childrenCache.start(StartMode.POST_INITIALIZED_EVENT);
         childrenCache.getListenable().addListener(
             new PathChildrenCacheListener() {
                 @Override
                 public void childEvent(CuratorFramework client, PathChildrenCacheEvent event)
                         throws Exception {
                         switch (event.getType()) {
                         case CHILD_ADDED:
                             System.out.println("CHILD_ADDED: " + event.getData().getPath());
                             break;
                         case CHILD_REMOVED:
                             System.out.println("CHILD_REMOVED: " + event.getData().getPath());
                             break;
                         case CHILD_UPDATED:
                             System.out.println("CHILD_UPDATED: " + event.getData().getPath());
                             break;
                         default:
                             break;
                     }
                 }
             },
             pool
         );
         
         client.setData().forPath("/zktest/cnode", "world".getBytes());
         
         Thread.sleep(10 * 1000);
         pool.shutdown();
         client.close();
     }
 }


Curator  "菜谱"           

既然Maven包叫curator-recipes, 那说明Curator有它独特的"菜单".

1. 锁: 包括共享锁, 共享可写入锁, 读写锁等.

2. 选举: Leader选举算法.

3. Barrier: 阻止分布式计算直至某个条件被满足的"栅栏", 可以看做JDK Concurrent包中Barrier的分布式实现.

4. 缓存: 前面提到过的三种Cache及监听机制.

5. 持久化节点: 连接或Session终止后仍然在Zookeeper中存在的节点.

6. 队列: 分布式队列, 分布式优先级队列等.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小狼躲藏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值