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!
-------------------------------------------------------------------------------------------------------------------------------




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM