zookeeper 源码阅读(1)
對(duì)于源碼閱讀的幾點(diǎn)建議和方式:
1.盡量本地調(diào)試可以跑起來代碼
2.debug 日志梳理代碼執(zhí)行流程,這樣起到事半功倍的作用
3.干巴巴看代碼毫無意義,難度極大
?
zk 是分別有c語言編寫的和java 編寫的,zk 提供了豐富的api,一般公司中間件團(tuán)隊(duì),將zk api進(jìn)行包裝成jar包放到倉(cāng)庫(kù)供其他團(tuán)隊(duì)使用;同時(shí)封裝jar的時(shí)候,為了使用方便,增加了各種與spring 無縫組裝的方式。例如:在spring.xml中添加zk的配置或者消息隊(duì)列或線程等(其他中間件也是如此,如rsf, redis,kafka)。
zk c 源碼結(jié)構(gòu):
先看下 zk 中hashtable的代碼:
/* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */#include "hashtable.h" #include "hashtable_private.h" #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h>/* Credit for primes table: Aaron Krownehttp://br.endernet.org/~akrowne/http://planetmath.org/encyclopedia/GoodHashTablePrimes.html */ static const unsigned int primes[] = { 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741 }; const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]); const float max_load_factor = 0.65;/*****************************************************************************/ struct hashtable * create_hashtable(unsigned int minsize,unsigned int (*hashf) (void*),int (*eqf) (void*,void*)) {struct hashtable *h;unsigned int pindex, size = primes[0];/* Check requested hashtable isn't too large */if (minsize > (1u << 30)) return NULL;/* Enforce size as prime */for (pindex=0; pindex < prime_table_length; pindex++) {if (primes[pindex] > minsize) { size = primes[pindex]; break; }}h = (struct hashtable *)malloc(sizeof(struct hashtable));if (NULL == h) return NULL; /*oom*/h->table = (struct entry **)malloc(sizeof(struct entry*) * size);if (NULL == h->table) { free(h); return NULL; } /*oom*/memset(h->table, 0, size * sizeof(struct entry *));h->tablelength = size;h->primeindex = pindex;h->entrycount = 0;h->hashfn = hashf;h->eqfn = eqf;h->loadlimit = (unsigned int) ceil(size * max_load_factor);return h; }/*****************************************************************************/ unsigned int hash(struct hashtable *h, void *k) {/* Aim to protect against poor hash functions by adding logic here* - logic taken from java 1.4 hashtable source */unsigned int i = h->hashfn(k);i += ~(i << 9);i ^= ((i >> 14) | (i << 18)); /* >>> */i += (i << 4);i ^= ((i >> 10) | (i << 22)); /* >>> */return i; }/*****************************************************************************/ static int hashtable_expand(struct hashtable *h) {/* Double the size of the table to accomodate more entries */struct entry **newtable;struct entry *e;struct entry **pE;unsigned int newsize, i, index;/* Check we're not hitting max capacity */if (h->primeindex == (prime_table_length - 1)) return 0;newsize = primes[++(h->primeindex)];newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);if (NULL != newtable){memset(newtable, 0, newsize * sizeof(struct entry *));/* This algorithm is not 'stable'. ie. it reverses the list* when it transfers entries between the tables */for (i = 0; i < h->tablelength; i++) {while (NULL != (e = h->table[i])) {h->table[i] = e->next;index = indexFor(newsize,e->h);e->next = newtable[index];newtable[index] = e;}}free(h->table);h->table = newtable;}/* Plan B: realloc instead */else {newtable = (struct entry **)realloc(h->table, newsize * sizeof(struct entry *));if (NULL == newtable) { (h->primeindex)--; return 0; }h->table = newtable;memset(newtable[h->tablelength], 0, newsize - h->tablelength);for (i = 0; i < h->tablelength; i++) {for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {index = indexFor(newsize,e->h);if (index == i){pE = &(e->next);}else{*pE = e->next;e->next = newtable[index];newtable[index] = e;}}}}h->tablelength = newsize;h->loadlimit = (unsigned int) ceil(newsize * max_load_factor);return -1; }/*****************************************************************************/ unsigned int hashtable_count(struct hashtable *h) {return h->entrycount; }/*****************************************************************************/ int hashtable_insert(struct hashtable *h, void *k, void *v) {/* This method allows duplicate keys - but they shouldn't be used */unsigned int index;struct entry *e;if (++(h->entrycount) > h->loadlimit){/* Ignore the return value. If expand fails, we should* still try cramming just this value into the existing table* -- we may not have memory for a larger table, but one more* element may be ok. Next time we insert, we'll try expanding again.*/hashtable_expand(h);}e = (struct entry *)malloc(sizeof(struct entry));if (NULL == e) { --(h->entrycount); return 0; } /*oom*/e->h = hash(h,k);index = indexFor(h->tablelength,e->h);e->k = k;e->v = v;e->next = h->table[index];h->table[index] = e;return -1; }/*****************************************************************************/ void * /* returns value associated with key */ hashtable_search(struct hashtable *h, void *k) {struct entry *e;unsigned int hashvalue, index;hashvalue = hash(h,k);index = indexFor(h->tablelength,hashvalue);e = h->table[index];while (NULL != e){/* Check hash value to short circuit heavier comparison */if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;e = e->next;}return NULL; }/*****************************************************************************/ void * /* returns value associated with key */ hashtable_remove(struct hashtable *h, void *k) {/* TODO: consider compacting the table when the load factor drops enough,* or provide a 'compact' method. */struct entry *e;struct entry **pE;void *v;unsigned int hashvalue, index;hashvalue = hash(h,k);index = indexFor(h->tablelength,hash(h,k));pE = &(h->table[index]);e = *pE;while (NULL != e){/* Check hash value to short circuit heavier comparison */if ((hashvalue == e->h) && (h->eqfn(k, e->k))){*pE = e->next;h->entrycount--;v = e->v;freekey(e->k);free(e);return v;}pE = &(e->next);e = e->next;}return NULL; }/*****************************************************************************/ /* destroy */ void hashtable_destroy(struct hashtable *h, int free_values) {unsigned int i;struct entry *e, *f;struct entry **table = h->table;if (free_values){for (i = 0; i < h->tablelength; i++){e = table[i];while (NULL != e){ f = e; e = e->next; freekey(f->k); free(f->v); free(f); }}}else{for (i = 0; i < h->tablelength; i++){e = table[i];while (NULL != e){ f = e; e = e->next; freekey(f->k); free(f); }}}free(h->table);free(h); }/** Copyright (c) 2002, Christopher Clark* All rights reserved.* * Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:* * * Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* * * Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.* * * Neither the name of the original author; nor the names of any contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.* * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */hashtable_itr 是對(duì)hashtable的操作
/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */#include "hashtable.h" #include "hashtable_private.h" #include "hashtable_itr.h" #include <stdlib.h> /* defines NULL *//*****************************************************************************/ /* hashtable_iterator - iterator constructor */struct hashtable_itr * hashtable_iterator(struct hashtable *h) {unsigned int i, tablelength;struct hashtable_itr *itr = (struct hashtable_itr *)malloc(sizeof(struct hashtable_itr));if (NULL == itr) return NULL;itr->h = h;itr->e = NULL;itr->parent = NULL;tablelength = h->tablelength;itr->index = tablelength;if (0 == h->entrycount) return itr;for (i = 0; i < tablelength; i++){if (NULL != h->table[i]){itr->e = h->table[i];itr->index = i;break;}}return itr; }/*****************************************************************************/ /* advance - advance the iterator to the next element* returns zero if advanced to end of table */int hashtable_iterator_advance(struct hashtable_itr *itr) {unsigned int j,tablelength;struct entry **table;struct entry *next;if (NULL == itr->e) return 0; /* stupidity check */next = itr->e->next;if (NULL != next){itr->parent = itr->e;itr->e = next;return -1;}tablelength = itr->h->tablelength;itr->parent = NULL;if (tablelength <= (j = ++(itr->index))){itr->e = NULL;return 0;}table = itr->h->table;while (NULL == (next = table[j])){if (++j >= tablelength){itr->index = tablelength;itr->e = NULL;return 0;}}itr->index = j;itr->e = next;return -1; }/*****************************************************************************/ /* remove - remove the entry at the current iterator position* and advance the iterator, if there is a successive* element.* If you want the value, read it before you remove:* beware memory leaks if you don't.* Returns zero if end of iteration. */int hashtable_iterator_remove(struct hashtable_itr *itr) {struct entry *remember_e, *remember_parent;int ret;/* Do the removal */if (NULL == (itr->parent)){/* element is head of a chain */itr->h->table[itr->index] = itr->e->next;} else {/* element is mid-chain */itr->parent->next = itr->e->next;}/* itr->e is now outside the hashtable */remember_e = itr->e;itr->h->entrycount--;freekey(remember_e->k);/* Advance the iterator, correcting the parent */remember_parent = itr->parent;ret = hashtable_iterator_advance(itr);if (itr->parent == remember_e) { itr->parent = remember_parent; }free(remember_e);return ret; }/*****************************************************************************/ int /* returns zero if not found */ hashtable_iterator_search(struct hashtable_itr *itr,struct hashtable *h, void *k) {struct entry *e, *parent;unsigned int hashvalue, index;hashvalue = hash(h,k);index = indexFor(h->tablelength,hashvalue);e = h->table[index];parent = NULL;while (NULL != e){/* Check hash value to short circuit heavier comparison */if ((hashvalue == e->h) && (h->eqfn(k, e->k))){itr->index = index;itr->e = e;itr->parent = parent;itr->h = h;return -1;}parent = e;e = e->next;}return 0; }/** Copyright (c) 2002, 2004, Christopher Clark* All rights reserved.* * Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:* * * Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* * * Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.* * * Neither the name of the original author; nor the names of any contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.* * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */看下java 代碼,首先本地創(chuàng)建一個(gè)maven工程,將main 下面代碼放進(jìn)來,然后將lib下面的jar 引入進(jìn)來。
代碼基本上可以運(yùn)行,但是部分有些小的爆粗,主要就是這塊代碼在繼承處理上的問題,只要稍加改動(dòng)就可以了。@override去掉
運(yùn)行結(jié)果:
zk 主入口:
每一個(gè)zk 放到一臺(tái)機(jī)器 上都要執(zhí)行 這個(gè)main啟動(dòng)一個(gè)進(jìn)程:
public static void main(String args[])throws KeeperException, IOException, InterruptedException{ZooKeeperMain main = new ZooKeeperMain(args);main.run();} public ZooKeeperMain(String args[]) throws IOException, InterruptedException {cl.parseOptions(args);System.out.println("Connecting to " + cl.getOption("server"));connectToZK(cl.getOption("server"));//zk = new ZooKeeper(cl.getOption("server"), // Integer.parseInt(cl.getOption("timeout")), new MyWatcher());}cl.getOption("server") 設(shè)置服務(wù)器參數(shù)
static class MyCommandOptions {private Map<String,String> options = new HashMap<String,String>();private List<String> cmdArgs = null;private String command = null;public static final Pattern ARGS_PATTERN = Pattern.compile("\\s*([^\"\']\\S*|\"[^\"]*\"|'[^']*')\\s*");public static final Pattern QUOTED_PATTERN = Pattern.compile("^([\'\"])(.*)(\\1)$");public MyCommandOptions() {options.put("server", "localhost:2181");options.put("timeout", "30000");}public String getOption(String opt) {return options.get(opt);}public String getCommand( ) {return command;}public String getCmdArgument( int index ) {return cmdArgs.get(index);}public int getNumArguments( ) {return cmdArgs.size();}public String[] getArgArray() {return cmdArgs.toArray(new String[0]);}/*** Parses a command line that may contain one or more flags* before an optional command string* @param args command line arguments* @return true if parsing succeeded, false otherwise.*/public boolean parseOptions(String[] args) {List<String> argList = Arrays.asList(args);Iterator<String> it = argList.iterator();while (it.hasNext()) {String opt = it.next();try {if (opt.equals("-server")) {options.put("server", it.next());} else if (opt.equals("-timeout")) {options.put("timeout", it.next());} else if (opt.equals("-r")) {options.put("readonly", "true");}} catch (NoSuchElementException e){System.err.println("Error: no argument found for option "+ opt);return false;}if (!opt.startsWith("-")) {command = opt;cmdArgs = new ArrayList<String>( );cmdArgs.add( command );while (it.hasNext()) {cmdArgs.add(it.next());}return true;}}return true;}/*** Breaks a string into command + arguments.* @param cmdstring string of form "cmd arg1 arg2..etc"* @return true if parsing succeeded.*/public boolean parseCommand( String cmdstring ) {Matcher matcher = ARGS_PATTERN.matcher(cmdstring);List<String> args = new LinkedList<String>();while (matcher.find()) {String value = matcher.group(1);if (QUOTED_PATTERN.matcher(value).matches()) {// Strip off the surrounding quotesvalue = value.substring(1, value.length() - 1);}args.add(value);}if (args.isEmpty()){return false;}command = args.get(0);cmdArgs = args;return true;}}MyCommandOptions這個(gè)類是ZookeeperMain中的子類
接著執(zhí)行到方法:
protected void connectToZK(String newHost) throws InterruptedException, IOException {if (zk != null && zk.getState().isAlive()) {zk.close();}host = newHost;boolean readOnly = cl.getOption("readonly") != null;zk = new ZooKeeper(host,Integer.parseInt(cl.getOption("timeout")),new MyWatcher(), readOnly);}接著調(diào)用ZooKeeper 創(chuàng)建一個(gè)線程服務(wù)
public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,boolean canBeReadOnly)throws IOException{LOG.info("Initiating client connection, connectString=" + connectString+ " sessionTimeout=" + sessionTimeout + " watcher=" + watcher);watchManager.defaultWatcher = watcher;ConnectStringParser connectStringParser = new ConnectStringParser(connectString);HostProvider hostProvider = new StaticHostProvider(connectStringParser.getServerAddresses());cnxn = new ClientCnxn(connectStringParser.getChrootPath(),hostProvider, sessionTimeout, this, watchManager,getClientCnxnSocket(), canBeReadOnly);cnxn.start();}看下ClientCnxn 以及start
public ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,ClientWatchManager watcher, ClientCnxnSocket clientCnxnSocket,long sessionId, byte[] sessionPasswd, boolean canBeReadOnly) {this.zooKeeper = zooKeeper;this.watcher = watcher;this.sessionId = sessionId;this.sessionPasswd = sessionPasswd;this.sessionTimeout = sessionTimeout;this.hostProvider = hostProvider;this.chrootPath = chrootPath;connectTimeout = sessionTimeout / hostProvider.size();readTimeout = sessionTimeout * 2 / 3;readOnly = canBeReadOnly;sendThread = new SendThread(clientCnxnSocket);eventThread = new EventThread();} public void start() {sendThread.start();eventThread.start();} SendThread(ClientCnxnSocket clientCnxnSocket) {super(makeThreadName("-SendThread()"));state = States.CONNECTING;this.clientCnxnSocket = clientCnxnSocket;setDaemon(true);}到這里可以看到zk 創(chuàng)建一個(gè)線程開啟socket服務(wù),端口2181,監(jiān)聽回過頭來看下main.run
void run() throws KeeperException, IOException, InterruptedException {if (cl.getCommand() == null) {System.out.println("Welcome to ZooKeeper!");boolean jlinemissing = false;// only use jline if it's in the classpathtry {Class consoleC = Class.forName("jline.ConsoleReader");Class completorC =Class.forName("org.apache.zookeeper.JLineZNodeCompletor");System.out.println("JLine support is enabled");Object console =consoleC.getConstructor().newInstance();Object completor =completorC.getConstructor(ZooKeeper.class).newInstance(zk);Method addCompletor = consoleC.getMethod("addCompletor",Class.forName("jline.Completor"));addCompletor.invoke(console, completor);String line;Method readLine = consoleC.getMethod("readLine", String.class);while ((line = (String)readLine.invoke(console, getPrompt())) != null) {executeLine(line);}} catch (ClassNotFoundException e) {LOG.debug("Unable to start jline", e);jlinemissing = true;} catch (NoSuchMethodException e) {LOG.debug("Unable to start jline", e);jlinemissing = true;} catch (InvocationTargetException e) {LOG.debug("Unable to start jline", e);jlinemissing = true;} catch (IllegalAccessException e) {LOG.debug("Unable to start jline", e);jlinemissing = true;} catch (InstantiationException e) {LOG.debug("Unable to start jline", e);jlinemissing = true;}if (jlinemissing) {System.out.println("JLine support is disabled");BufferedReader br =new BufferedReader(new InputStreamReader(System.in));String line;while ((line = br.readLine()) != null) {executeLine(line);}}} else {// Command line args non-null. Run what was passed.processCmd(cl);}} protected boolean processCmd(MyCommandOptions co)throws KeeperException, IOException, InterruptedException{try {return processZKCmd(co);} catch (IllegalArgumentException e) {System.err.println("Command failed: " + e);} catch (KeeperException.NoNodeException e) {System.err.println("Node does not exist: " + e.getPath());} catch (KeeperException.NoChildrenForEphemeralsException e) {System.err.println("Ephemerals cannot have children: "+ e.getPath());} catch (KeeperException.NodeExistsException e) {System.err.println("Node already exists: " + e.getPath());} catch (KeeperException.NotEmptyException e) {System.err.println("Node not empty: " + e.getPath());} catch (KeeperException.NotReadOnlyException e) {System.err.println("Not a read-only call: " + e.getPath());}catch (KeeperException.InvalidACLException e) {System.err.println("Acl is not valid : "+e.getPath());}catch (KeeperException.NoAuthException e) {System.err.println("Authentication is not valid : "+e.getPath());}catch (KeeperException.BadArgumentsException e) {System.err.println("Arguments are not valid : "+e.getPath());}catch (KeeperException.BadVersionException e) {System.err.println("version No is not valid : "+e.getPath());}return false;}這塊代碼借助Jline 讀取配置文件中的command
public void executeLine(String line)throws InterruptedException, IOException, KeeperException {if (!line.equals("")) {cl.parseCommand(line);addToHistory(commandCount,line);processCmd(cl);commandCount++;}}把指令添加到一個(gè)容器中--map,然后進(jìn)行分場(chǎng)景處理
protected boolean processZKCmd(MyCommandOptions co)throws KeeperException, IOException, InterruptedException{Stat stat = new Stat();String[] args = co.getArgArray();String cmd = co.getCommand();if (args.length < 1) {usage();return false;}if (!commandMap.containsKey(cmd)) {usage();return false;}boolean watch = args.length > 2;String path = null;List<ACL> acl = Ids.OPEN_ACL_UNSAFE;LOG.debug("Processing " + cmd);if (cmd.equals("quit")) {System.out.println("Quitting...");zk.close();System.exit(0);} else if (cmd.equals("redo") && args.length >= 2) {Integer i = Integer.decode(args[1]);if (commandCount <= i || i < 0){ // don't allow redoing this redoSystem.out.println("Command index out of range");return false;}cl.parseCommand(history.get(i));if (cl.getCommand().equals( "redo" )){System.out.println("No redoing redos");return false;}history.put(commandCount, history.get(i));processCmd( cl);} else if (cmd.equals("history")) {for (int i=commandCount - 10;i<=commandCount;++i) {if (i < 0) continue;System.out.println(i + " - " + history.get(i));}} else if (cmd.equals("printwatches")) {if (args.length == 1) {System.out.println("printwatches is " + (printWatches ? "on" : "off"));} else {printWatches = args[1].equals("on");}} else if (cmd.equals("connect")) {if (args.length >=2) {connectToZK(args[1]);} else {connectToZK(host); }} // Below commands all need a live connectionif (zk == null || !zk.getState().isAlive()) {System.out.println("Not connected");return false;}if (cmd.equals("create") && args.length >= 3) {int first = 0;CreateMode flags = CreateMode.PERSISTENT;if ((args[1].equals("-e") && args[2].equals("-s"))|| (args[1]).equals("-s") && (args[2].equals("-e"))) {first+=2;flags = CreateMode.EPHEMERAL_SEQUENTIAL;} else if (args[1].equals("-e")) {first++;flags = CreateMode.EPHEMERAL;} else if (args[1].equals("-s")) {first++;flags = CreateMode.PERSISTENT_SEQUENTIAL;}if (args.length == first + 4) {acl = parseACLs(args[first+3]);}path = args[first + 1];String newPath = zk.create(path, args[first+2].getBytes(), acl,flags);System.err.println("Created " + newPath);} else if (cmd.equals("delete") && args.length >= 2) {path = args[1];zk.delete(path, watch ? Integer.parseInt(args[2]) : -1);} else if (cmd.equals("rmr") && args.length >= 2) {path = args[1];ZKUtil.deleteRecursive(zk, path);} else if (cmd.equals("set") && args.length >= 3) {path = args[1];stat = zk.setData(path, args[2].getBytes(),args.length > 3 ? Integer.parseInt(args[3]) : -1);printStat(stat);} else if (cmd.equals("aget") && args.length >= 2) {path = args[1];zk.getData(path, watch, dataCallback, path);} else if (cmd.equals("get") && args.length >= 2) {path = args[1];byte data[] = zk.getData(path, watch, stat);data = (data == null)? "null".getBytes() : data;System.out.println(new String(data));printStat(stat);} else if (cmd.equals("ls") && args.length >= 2) {path = args[1];List<String> children = zk.getChildren(path, watch);System.out.println(children);} else if (cmd.equals("ls2") && args.length >= 2) {path = args[1];List<String> children = zk.getChildren(path, watch, stat);System.out.println(children);printStat(stat);} else if (cmd.equals("getAcl") && args.length >= 2) {path = args[1];acl = zk.getACL(path, stat);for (ACL a : acl) {System.out.println(a.getId() + ": "+ getPermString(a.getPerms()));}} else if (cmd.equals("setAcl") && args.length >= 3) {path = args[1];stat = zk.setACL(path, parseACLs(args[2]),args.length > 4 ? Integer.parseInt(args[3]) : -1);printStat(stat);} else if (cmd.equals("stat") && args.length >= 2) {path = args[1];stat = zk.exists(path, watch);if (stat == null) {throw new KeeperException.NoNodeException(path); }printStat(stat);} else if (cmd.equals("listquota") && args.length >= 2) {path = args[1];String absolutePath = Quotas.quotaZookeeper + path + "/" + Quotas.limitNode;byte[] data = null;try {System.err.println("absolute path is " + absolutePath);data = zk.getData(absolutePath, false, stat);StatsTrack st = new StatsTrack(new String(data));System.out.println("Output quota for " + path + " "+ st.toString());data = zk.getData(Quotas.quotaZookeeper + path + "/" +Quotas.statNode, false, stat);System.out.println("Output stat for " + path + " " +new StatsTrack(new String(data)).toString());} catch(KeeperException.NoNodeException ne) {System.err.println("quota for " + path + " does not exist.");}} else if (cmd.equals("setquota") && args.length >= 4) {String option = args[1];String val = args[2];path = args[3];System.err.println("Comment: the parts are " +"option " + option +" val " + val +" path " + path);if ("-b".equals(option)) {// we are setting the bytes quotacreateQuota(zk, path, Long.parseLong(val), -1);} else if ("-n".equals(option)) {// we are setting the num quotacreateQuota(zk, path, -1L, Integer.parseInt(val));} else {usage();}} else if (cmd.equals("delquota") && args.length >= 2) {//if neither option -n or -b is specified, we delete// the quota node for thsi node.if (args.length == 3) {//this time we have an optionString option = args[1];path = args[2];if ("-b".equals(option)) {delQuota(zk, path, true, false);} else if ("-n".equals(option)) {delQuota(zk, path, false, true);}} else if (args.length == 2) {path = args[1];// we dont have an option specified.// just delete whole quota nodedelQuota(zk, path, true, true);} else if (cmd.equals("help")) {usage();}} else if (cmd.equals("close")) {zk.close(); } else if (cmd.equals("sync") && args.length >= 2) {path = args[1];zk.sync(path, new AsyncCallback.VoidCallback() { public void processResult(int rc, String path, Object ctx) { System.out.println("Sync returned " + rc); } }, null );} else if (cmd.equals("addauth") && args.length >=2 ) {byte[] b = null;if (args.length >= 3)b = args[2].getBytes();zk.addAuthInfo(args[1], b);} else if (!commandMap.containsKey(cmd)) {usage();}return watch;}?
?
總結(jié)
以上是生活随笔為你收集整理的zookeeper 源码阅读(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 魔兽世界怀旧服雷布里斯库比格特掉落什么?
- 下一篇: redis源码阅读(1)