ZooKeeper 数据持久化---ZKDatabase
ZKDatabase 主要维持了一个 DataTree的内存数据结构,通过序列化到本地磁盘的快照文件,以及Redo日志文件。
核心是DataTree。
先看看这棵树的节点: DataNode.java
public interface Record { //这个接口应该是类似于java里的Serializable 接口 public void serialize(OutputArchive archive, String tag) throws IOException; public void deserialize(InputArchive archive, String tag) throws IOException; }
DataTree上的节点结构:
/** * A data node contains a reference to its parent,
* a byte array as its data, at most 1M * an array of ACLs,
* a stat object,
* and a set of its children's paths. */ public class DataNode implements Record { /** the parent of this datanode */ DataNode parent;
/** the data for this datanode */ byte data[]; // the acl map long for this datanode. the datatree has the map Long acl; //the stat for this node that is persisted to disk. public StatPersisted stat; /** * the list of children for this node. note that the list of children string * does not contain the parent path -- just the last part of the path. This * should be synchronized on except deserializing (for speed up issues). */ private Set<String> children = null;
... ... }
再先先看DataTree 的描述:
/**
* This class maintains the tree data structure. It doesn't have any networking
* or client connection code in it so that it can be tested in a stand alone way.
*
* The tree maintains two parallel data structures: a hashtable that maps from
* full paths to DataNodes and a tree of DataNodes. All accesses to a path is
* through the hashtable. The tree is traversed only when serializing to disk.
*/
DataTree 主要数据成员:
public class DataTree { /** * This hashtable provides a fast lookup to the datanodes. The tree is the * source of truth and is where all the locking occurs */ private final ConcurrentHashMap<String, DataNode> nodes = new ConcurrentHashMap<String, DataNode>(); private final WatchManager dataWatches = new WatchManager(); private final WatchManager childWatches = new WatchManager(); /** the root of zookeeper tree */ private static final String rootZookeeper = "/"; /** the zookeeper nodes that acts as the management and status node **/ private static final String procZookeeper = Quotas.procZookeeper; // “/zookeeper” /** this will be the string thats stored as a child of root */ private static final String procChildZookeeper = procZookeeper.substring(1); /** * the zookeeper quota node that acts as the quota management node for * zookeeper */ private static final String quotaZookeeper = Quotas.quotaZookeeper; // "/zookeeper/quota" /** this will be the string thats stored as a child of /zookeeper */ private static final String quotaChildZookeeper = quotaZookeeper .substring(procZookeeper.length() + 1); /** * the path trie that keeps track fo the quota nodes in this datatree */ private final PathTrie pTrie = new PathTrie(); /** * This hashtable lists the paths of the ephemeral nodes of a session. */ private final Map<Long, HashSet<String>> ephemerals = new ConcurrentHashMap<Long, HashSet<String>>(); 。。。 。。。 }