• 08.Curator缓存


        可以利用ZooKeeper在集群的各个节点之间缓存数据。每个节点都可以得到最新的缓存的数据。Curator提供了三种类型的缓存方式:Path Cache,Node Cache 和Tree Cache。

    1.Path Cache

        Path Cache用来监控一个ZNode的子节点。当一个子节点增加,更新,删除时,Path Cache会改变它的状态,会包含最新的子节点,子节点的数据和状态。
    1.Path Cache介绍
        Path Cache的主要用途是监控某个节点的子节点,由于Zookeeper原生API的watch监控节点时注册一次只能触发一次,而Path Cache弥补了这个不足,它注册一次可以一直监控触发。
    实际使用时会涉及到四个类:
    • PathChildrenCache - Path Cache主要实现类
    • PathChildrenCacheEvent - 监听触发时的事件对象,包含事件相关信息
    • PathChildrenCacheListener - 监听器接口
    • ChildData - 子节点数据封装类
    通过下面的构造函数创建Path Cache:
    1. public PathChildrenCache(CuratorFramework client, String path, boolean cacheData)
    注意:使用cache,必须调用它的start方法,不用之后调用close方法。其中的cacheData参数用来设置是否缓存节点数据。
    start有两个,其中一个可以传入StartMode,用来为初始的cache设置暖场方式(warm):
        1.NORMAL: 初始时为空。
        2.BUILD_INITIAL_CACHE: 在这个方法返回之前调用rebuild()。
        3.POST_INITIALIZED_EVENT: 当Cache初始化数据后发送一个PathChildrenCacheEvent.Type#INITIALIZED事件

    PathChildrenCache.getListenable().addListener(PathChildrenCacheListener listener)可以增加listener监听缓存的改变。
    getCurrentData()方法返回一个List对象,可以遍历所有的子节点。
    2.编写示例程序
    1. public class PathCacheTest
    2. {
    3. private static final String PATH = "/example/cache";
    4. public static void main(String[] args) throws Exception
    5. {
    6. CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));
    7. client.start();
    8. PathChildrenCache cache = new PathChildrenCache(client, PATH, true);
    9. cache.start();
    10. PathChildrenCacheListener cacheListener = new PathChildrenCacheListener()
    11. {
    12. @Override
    13. public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception
    14. {
    15. System.out.println("事件类型:" + event.getType());
    16. System.out.println("节点数据:" + event.getData().getPath() + " = " + new String(event.getData().getData()));
    17. }
    18. };
    19. cache.getListenable().addListener(cacheListener);
    20. client.create().forPath("/example/cache/test01", "01".getBytes());
    21. Thread.sleep(10);
    22. client.create().forPath("/example/cache/test02", "02".getBytes());
    23. Thread.sleep(10);
    24. client.setData().forPath("/example/cache/test01", "01_V2".getBytes());
    25. Thread.sleep(10);
    26. for (ChildData data : cache.getCurrentData())
    27. {
    28. System.out.println("getCurrentData:" + data.getPath() + " = " + new String(data.getData()));
    29. }
    30. client.delete().forPath("/example/cache/test01");
    31. Thread.sleep(10);
    32. client.delete().forPath("/example/cache/test02");
    33. Thread.sleep(1000 * 5);
    34. cache.close();
    35. client.close();
    36. System.out.println("OK!");
    37. }
    38. }
    注意:如果new PathChildrenCache(client, PATH, true)中的参数cacheData值设置为false,则示例中的event.getData().getData()data.getData()将返回null,cache将不会缓存节点数据。
    注意:示例中的Thread.sleep(10)可以注释,但是注释后事件监听的触发次数会不全,这可能与cache的实现原理有关,不能太过频繁的触发事件!
    3.示例程序运行结果
        运行结果控制台:
    1. 事件类型:CHILD_ADDED
    2. 节点数据:/example/cache/test01 = 01
    3. 事件类型:CHILD_ADDED
    4. 节点数据:/example/cache/test02 = 02
    5. 事件类型:CHILD_UPDATED
    6. 节点数据:/example/cache/test01 = 01_V2
    7. getCurrentData:/example/cache/test01 = 01_V2
    8. getCurrentData:/example/cache/test02 = 02
    9. 事件类型:CHILD_REMOVED
    10. 节点数据:/example/cache/test01 = 01_V2
    11. 事件类型:CHILD_REMOVED
    12. 节点数据:/example/cache/test02 = 02
    13. OK!

    2.Node Cache

        Path Cache用来监控一个节点的子节点。当节点的数据修改或者删除时,Node Cache能更新它的状态包含最新的改变。
    1.Node Cache介绍
    Node Cache与Path Cache类似,Node Cache只是监听某一个特定的节点。它涉及到下面的三个类:
    • NodeCache - Node Cache实现类
    • NodeCacheListener - 节点监听器
    • ChildData - 节点数据
    注意:使用cache,依然要调用它的start方法,不用之后调用close方法。
    getCurrentData()将得到节点当前的状态,通过它的状态可以得到当前的值。
    2.编写示例程序
    1. public class NodeCacheExample
    2. {
    3. private static final String PATH = "/example/cache";
    4. public static void main(String[] args) throws Exception
    5. {
    6. CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));
    7. client.start();
    8. final NodeCache cache = new NodeCache(client, PATH);
    9. cache.start();
    10. NodeCacheListener listener = new NodeCacheListener()
    11. {
    12. @Override
    13. public void nodeChanged() throws Exception
    14. {
    15. ChildData data = cache.getCurrentData();
    16. if (null != data)
    17. {
    18. System.out.println("节点数据:" + new String(cache.getCurrentData().getData()));
    19. }
    20. else
    21. {
    22. System.out.println("节点被删除!");
    23. }
    24. }
    25. };
    26. cache.getListenable().addListener(listener);
    27. client.create().creatingParentsIfNeeded().forPath(PATH, "01".getBytes());
    28. Thread.sleep(10);
    29. client.setData().forPath(PATH, "02".getBytes());
    30. Thread.sleep(10);
    31. client.delete().deletingChildrenIfNeeded().forPath(PATH);
    32. Thread.sleep(1000 * 2);
    33. cache.close();
    34. client.close();
    35. System.out.println("OK!");
    36. }
    37. }
    注意:示例中的Thread.sleep(10)可以注释,但是注释后事件监听的触发次数会不全,这可能与cache的实现原理有关,不能太过频繁的触发事件!
    3.示例程序运行结果
        运行结果控制台:
    1. 节点数据:01
    2. 节点数据:02
    3. 节点被删除!
    4. OK!

    3.Tree Node

        这种类型的即可以监控节点的状态,还监控节点的子节点的状态,类似上面两种cache的组合。这也就是Tree的概念。它监控整个树中节点的状态。
    1.Tree Node介绍
    Tree Node可以监控整个树上的所有节点,涉及到下面四个类。
    • TreeCache - Tree Cache实现类
    • TreeCacheListener - 监听器类
    • TreeCacheEvent - 触发的事件类
    • ChildData - 节点数据
    注意:使用cache,依然要调用它的start方法,不用之后调用close方法。
    getCurrentChildren(path)返回监控节点下的某个节点的直接子节点数据,类型为Map。 而getCurrentData()返回监控节点的数据。
    2.编写示例程序
    1. public class TreeCacheExample
    2. {
    3. private static final String PATH = "/example/cache";
    4. public static void main(String[] args) throws Exception
    5. {
    6. CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));
    7. client.start();
    8. TreeCache cache = new TreeCache(client, PATH);
    9. cache.start();
    10. TreeCacheListener listener = new TreeCacheListener()
    11. {
    12. @Override
    13. public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception
    14. {
    15. System.out.println("事件类型:" + event.getType() + " | 路径:" + event.getData().getPath());
    16. }
    17. };
    18. cache.getListenable().addListener(listener);
    19. client.create().creatingParentsIfNeeded().forPath("/example/cache/test01/child01");
    20. client.setData().forPath("/example/cache/test01", "12345".getBytes());
    21. client.delete().deletingChildrenIfNeeded().forPath(PATH);
    22. Thread.sleep(1000 * 2);
    23. cache.close();
    24. client.close();
    25. System.out.println("OK!");
    26. }
    27. }
    注意:在此示例中没有使用Thread.sleep(10),但是事件触发次数也是正常的。
    3.示例程序运行结果
        运行结果控制台:
    1. 事件类型:NODE_ADDED | 路径:/example/cache
    2. 事件类型:NODE_ADDED | 路径:/example/cache/test01
    3. 事件类型:NODE_ADDED | 路径:/example/cache/test01/child01
    4. 事件类型:NODE_UPDATED | 路径:/example/cache/test01
    5. 事件类型:NODE_REMOVED | 路径:/example/cache/test01/child01
    6. 事件类型:NODE_REMOVED | 路径:/example/cache/test01
    7. 事件类型:NODE_REMOVED | 路径:/example/cache
    8. OK!
    -------------------------------------------------------------------------------------------------------------------------------



  • 相关阅读:
    SpringMVC学习笔记----常用注解
    python常用模块学习1
    python基础模块,包
    python-验证功能的装饰器示例
    python闭包及装饰器
    关于windows服务器配置
    python高阶函数
    python-生成器和迭代器
    linux--基础知识5
    python基础-文件操作的其他方法
  • 原文地址:https://www.cnblogs.com/LiZhiW/p/4942600.html
Copyright © 2020-2023  润新知