使用ZK实现 Cache 通过 Curator

  1. Curator Framework 深入了解
    1. ZooKeeper Cache 实现
      1. Path Cache
      2. Node Cache
      3. Tree Node

Curator Framework 深入了解

本文受到 colobu 前辈文章的指引,深入了解 Curator Framework 的工作流程,十分感谢 colobu 前辈的博文给予的启发和指导。

ZooKeeper Cache 实现

利用 ZooKeeper 在集群的节点上缓存数据。示例代码

Path Cache

Path Cache 使用 ZK 的节点作为 KV 存储系统,在实现上涉及的类:

  • PathChildrenCache
  • PathChildrenCacheEvent
  • PathChildrenCacheListener
  • ChildData

PathChildrenCache 是主要类,他的构造方法是

 public PathChildrenCache(CuratorFramework client, 
                             String path,
                             boolean cacheData /*是否缓存node,会缓存在一个 ConcurrentHashMap内*/)

比较奇特的是,设计上PathChildrenCache 只负责获取数据,也就是只有 listget 的操作,并没有 setremove 操作,需要新增数据之类的都是统一通过 CuratorFramework 构造出的 client 去做对应操作(任何对 zk 节点完成增删的操作都可)。PathChildrenCache 通过对构造函数中填入的 PATH 路径进行监听,这里有两个 Watcher,childrenWatcher 负责监听节点的增加,dataWatcher负责监听节点数据的改动和节点的删除。
构造好一个 PathChildrenCache 后需要 start() 后才能正常使用,调用 close()来结束使用。start() 方法中也可以传入 StartMode,用来为初始的 cache 设置暖场方式(warm):

  1. NORMAL: 初始时为空。
  2. BUILD_INITIAL_CACHE: 在这个方法返回之前调用rebuild(),此方法会将 ZK 的节点 kv 存到本地缓存(ConcurrentHashMap)内。
  3. POST_INITIALIZED_EVENT: 当Cache初始化数据后发送一个PathChildrenCacheEvent.Type#INITIALIZED 事件

获取当前的 Cache 值可以使用如下方法:

// PathChildrenCache.class

// 获取所有的缓存数据
public List<ChildData> getCurrentData() {
        return ImmutableList.copyOf(Sets.<ChildData>newTreeSet(currentData/*这就是本地缓存 concurrentHashMap*/.values()));
}

// 获取指定 PATH 下的缓存数据(实际就是用 key)
public ChildData getCurrentData(String fullPath) {
        return currentData/*这就是本地缓存 concurrentHashMap*/.get(fullPath);
}

可以增加 listener 监听缓存变化:

/*
这里的 Listener 就是 PathChildrenCacheListener 的实例,据此新建自己的监听器。
*/
cache/*PathChildrenCache 的实例*/.getListenable().addListener(listener);

Node Cache

Node Cache 顾名思义就是只对一个 Node 节点做监控,涉及到下面的三个类:

  • NodeCache
  • NodeCacheListener
  • ChildData

Node Cache 在更新数据的时候并不是同步的,也就意味着并发修改数据返回意料之外的结果。使用这个缓存的时候需要自己多加注意。具体的使用方法同 Path Cache,只是 Node Cache 的 getCurrentData() 只会返回一个 ChildData 了。

Tree Node

Tree Node 既可以监控节点的状态,也监控节点的子节点的状态。涉及到下面四个类:

  • TreeCache
  • TreeCacheListener
  • TreeCacheEvent
  • ChildData

TreeCache 使用 Builder 模式来构造:

// TreeCache.Builder.class
private Builder(CuratorFramework client, String path){
    this.client = checkNotNull(client);
    this.path = validatePath(path);
}
// 构造出来一个 builder 后可以配置
private boolean cacheData = true;
private boolean dataIsCompressed = false;
private ExecutorService executorService = null;
private int maxDepth = Integer.MAX_VALUE;
private boolean createParentNodes = false;

TreeCache 也可以使用 getCurrentChildren(String path) 方法获取 path 下一级的所有的 kv 对。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 nickchenyx@gmail.com

Title:使用ZK实现 Cache 通过 Curator

Count:718

Author:nickChen

Created At:2018-04-14, 17:03:31

Updated At:2023-05-08, 23:27:10

Url:http://nickchenyx.github.io/2018/04/14/CuratorFramework-Cache/

Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.