Added: dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperAuditLogs.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperAuditLogs.html 
(added)
+++ dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperAuditLogs.html 
Fri Oct  6 10:00:32 2023
@@ -0,0 +1,268 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>ZooKeeper: Because Coordinating Distributed Systems is a Zoo</title>
+    <link type="text/css" href="skin/basic.css" rel="stylesheet">
+    <link media="screen" type="text/css" href="skin/screen.css" 
rel="stylesheet">
+    <link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
+    <link type="text/css" href="skin/profile.css" rel="stylesheet">
+    <script src="skin/getBlank.js" language="javascript" 
type="text/javascript"></script>
+    <script src="skin/getMenu.js" language="javascript" 
type="text/javascript"></script>
+    <script src="skin/init.js" language="javascript" 
type="text/javascript"></script>
+    <link rel="shortcut icon" href="images/favicon.ico">
+</head>
+<body onload="init();">
+<div id="top">
+    <div class="breadtrail">
+        <a href="http://www.apache.org/";>Apache</a> &gt; <a 
href="http://zookeeper.apache.org/";>ZooKeeper</a>
+    </div>
+    <div class="header">
+        <div class="projectlogo">
+            <a href="http://zookeeper.apache.org/";><img class="logoImage" 
alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed 
coordination"></a>
+        </div>
+        <div class="searchbox">
+            <form action="http://www.google.com/search"; method="get">
+                <input value="zookeeper.apache.org" name="sitesearch" 
type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" 
size="25" name="q" id="query" type="text" value="Search the site with 
google">&nbsp;
+                <input name="Search" value="Search" type="submit">
+            </form>
+        </div>
+        <ul id="tabs">
+            <li>
+                <a class="unselected" 
href="http://zookeeper.apache.org/";>Project</a>
+            </li>
+            <li>
+                <a class="unselected" 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/";>Wiki</a>
+            </li>
+            <li class="current">
+                <a class="selected" href="index.html">ZooKeeper 3.7 
Documentation</a>
+            </li>
+        </ul>
+    </div>
+</div>
+<div id="main">
+    <div id="publishedStrip">
+        <div id="level2tabs"></div>
+        <script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+    </div>
+    <div class="breadtrail">
+        &nbsp;
+    </div>
+    <div id="menu">
+        <div onclick="SwitchMenu('menu_1', 'skin/')" id="menu_1Title" 
class="menutitle">Overview</div>
+        <div id="menu_1" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="index.html">Welcome</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperOver.html">Overview</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperStarted.html">Getting Started</a>
+            </div>
+            <div class="menuitem">
+                <a href="releasenotes.html">Release Notes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_2', 'skin/')" id="menu_2Title" 
class="menutitle">Developer</div>
+        <div id="menu_2" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="apidocs/zookeeper-server/index.html">API Docs</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperProgrammers.html">Programmer's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperUseCases.html">Use Cases</a>
+            </div>
+            <div class="menuitem">
+                <a href="javaExample.html">Java Example</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTutorial.html">Barrier and Queue Tutorial</a>
+            </div>
+            <div class="menuitem">
+                <a href="recipes.html">Recipes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_3', 'skin/')" id="menu_3Title" 
class="menutitle">Admin &amp; Ops</div>
+        <div id="menu_3" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperAdmin.html">Administrator's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperQuotas.html">Quota Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperJMX.html">JMX</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperHierarchicalQuorums.html">Hierarchical 
Quorums</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperObservers.html">Observers Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperReconfig.html">Dynamic Reconfiguration</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperCLI.html">ZooKeeper CLI</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTools.html">ZooKeeper Tools</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperMonitor.html">ZooKeeper Monitor</a>
+            </div>
+                       <div class="menuitem">
+                <a href="zookeeperAuditLogs.html">Audit Logs</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_4', 'skin/')" id="menu_4Title" 
class="menutitle">Contributor</div>
+        <div id="menu_4" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperInternals.html">ZooKeeper Internals</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_5', 'skin/')" id="menu_5Title" 
class="menutitle">Miscellaneous</div>
+        <div id="menu_5" class="menuitemgroup">
+            <div class="menuitem">
+                <a 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER";>Wiki</a>
+            </div>
+            <div class="menuitem">
+                <a 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/FAQ";>FAQ</a>
+            </div>
+            <div class="menuitem">
+                <a 
href="http://zookeeper.apache.org/mailing_lists.html";>Mailing Lists</a>
+            </div>
+        </div>
+    </div>
+    <div id="content">
+<!--
+Copyright 2002-2004 The Apache Software Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+//-->
+<h1>ZooKeeper Audit Logging</h1>
+<ul>
+<li><a href="#ch_auditLogs">ZooKeeper Audit Logs</a></li>
+<li><a href="#ch_reconfig_format">ZooKeeper Audit Log Configuration</a></li>
+<li><a href="#ch_zkAuditUser">Who is taken as user in audit logs?</a> <a 
name="ch_auditLogs"></a></li>
+</ul>
+<h2>ZooKeeper Audit Logs</h2>
+<p>Apache ZooKeeper supports audit logs from version 3.6.0. By default audit 
logs are disabled. To enable audit logs configure audit.enable=true in 
conf/zoo.cfg. Audit logs are not logged on all the ZooKeeper servers, but 
logged only on the servers where client is connected as depicted in below 
figure.</p>
+<p><img src="images/zkAuditLogs.jpg" alt="Audit Logs" /></p>
+<p>The audit log captures detailed information for the operations that are 
selected to be audited. The audit information is written as a set of key=value 
pairs for the following keys</p>
+<table>
+<thead>
+<tr><th> Key   </th><th> Value </th></tr>
+</thead>
+<tbody>
+<tr><td>session </td><td> client session id </td></tr>
+<tr><td>user </td><td> comma separated list of users who are associate with a 
client session. For more on this, see <a href="#ch_zkAuditUser">Who is taken as 
user in audit logs</a>.</td></tr>
+<tr><td>ip </td><td> client IP address</td></tr>
+<tr><td>operation </td><td> any one of the selected operations for audit. 
Possible values are(serverStart, serverStop, create, delete, setData, setAcl, 
multiOperation, reconfig, ephemeralZNodeDeleteOnSessionClose)</td></tr>
+<tr><td>znode </td><td> path of the znode</td></tr>
+<tr><td>znode type </td><td> type of znode in case of creation 
operation</td></tr>
+<tr><td>acl </td><td> String representation of znode ACL like cdrwa(create, 
delete,read, write, admin). This is logged only for setAcl operation</td></tr>
+<tr><td>result </td><td> result of the operation. Possible values are 
(success/failure/invoked). Result &quot;invoked&quot; is used for serverStop 
operation because stop is logged before ensuring that server actually 
stopped.</td></tr>
+</tbody>
+</table>
+<p>Below are sample audit logs for all operations, where client is connected 
from 192.168.1.2, client principal is zk...@hadoop.com, server principal is 
zookeeper/192.168....@hadoop.com</p>
+<pre><code>user=zookeeper/192.168.1.3 operation=serverStart   result=success
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=create    znode=/a    znode_type=persistent  result=success
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=create    znode=/a    znode_type=persistent  result=failure
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=setData   znode=/a    result=failure
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=setData   znode=/a    result=success
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=setAcl    znode=/a    acl=world:anyone:cdrwa  result=failure
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=setAcl    znode=/a    acl=world:anyone:cdrwa  result=success
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=create    znode=/b    znode_type=persistent  result=success
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=setData   znode=/b    result=success
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=delete    znode=/b    result=success
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=multiOperation    result=failure
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=delete    znode=/a    result=failure
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=delete    znode=/a    result=success
+session=0x19344730001   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=create   znode=/ephemral znode_type=ephemral result=success
+session=0x19344730001   user=zookeeper/192.168.1.3   
operation=ephemeralZNodeDeletionOnSessionCloseOrExpire  znode=/ephemral 
result=success
+session=0x19344730000   user=192.168.1.2,zk...@hadoop.com  ip=192.168.1.2    
operation=reconfig  znode=/zookeeper/config result=success
+user=zookeeper/192.168.1.3 operation=serverStop    result=invoked
+</code></pre>
+<p><a name="ch_auditConfig"></a></p>
+<h2>ZooKeeper Audit Log Configuration</h2>
+<p>By default audit logs are disabled. To enable audit logs configure 
audit.enable=true in conf/zoo.cfg. Audit logging is done using log4j. Following 
is the default log4j configuration for audit logs in conf/log4j.properties</p>
+<pre><code>#
+# zk audit logging
+#
+zookeeper.auditlog.file=zookeeper_audit.log
+zookeeper.auditlog.threshold=INFO
+audit.logger=INFO, RFAAUDIT
+log4j.logger.org.apache.zookeeper.audit.Log4jAuditLogger=${audit.logger}
+log4j.additivity.org.apache.zookeeper.audit.Log4jAuditLogger=false
+log4j.appender.RFAAUDIT=org.apache.log4j.RollingFileAppender
+log4j.appender.RFAAUDIT.File=${zookeeper.log.dir}/${zookeeper.auditlog.file}
+log4j.appender.RFAAUDIT.layout=org.apache.log4j.PatternLayout
+log4j.appender.RFAAUDIT.layout.ConversionPattern=%d{ISO8601} %p %c{2}: %m%n
+log4j.appender.RFAAUDIT.Threshold=${zookeeper.auditlog.threshold}
+
+# Max log file size of 10MB
+log4j.appender.RFAAUDIT.MaxFileSize=10MB
+log4j.appender.RFAAUDIT.MaxBackupIndex=10
+</code></pre>
+<p>Change above configuration to customize the auditlog file, number of 
backups, max file size, custom audit logger etc.</p>
+<p><a name="ch_zkAuditUser"></a></p>
+<h2>Who is taken as user in audit logs?</h2>
+<p>By default there are only four authentication provider:</p>
+<ul>
+<li>IPAuthenticationProvider</li>
+<li>SASLAuthenticationProvider</li>
+<li>X509AuthenticationProvider</li>
+<li>DigestAuthenticationProvider</li>
+</ul>
+<p>User is decided based on the configured authentication provider:</p>
+<ul>
+<li>When IPAuthenticationProvider is configured then authenticated IP is taken 
as user</li>
+<li>When SASLAuthenticationProvider is configured then client principal is 
taken as user</li>
+<li>When X509AuthenticationProvider is configured then client certificate is 
taken as user</li>
+<li>When DigestAuthenticationProvider is configured then authenticated user is 
user</li>
+</ul>
+<p>Custom authentication provider can override 
org.apache.zookeeper.server.auth.AuthenticationProvider.getUserName(String id) 
to provide user name. If authentication provider is not overriding this method 
then whatever is stored in org.apache.zookeeper.data.Id.id is taken as user. 
Generally only user name is stored in this field but it is up to the custom 
authentication provider what they store in it. For audit logging value of 
org.apache.zookeeper.data.Id.id would be taken as user.</p>
+<p>In ZooKeeper Server not all the operations are done by clients but some 
operations are done by the server itself. For example when client closes the 
session, ephemeral znodes are deleted by the Server. These deletion are not 
done by clients directly but it is done the server itself these are called 
system operations. For these system operations the user associated with the 
ZooKeeper server are taken as user while audit logging these operations. For 
example if in ZooKeeper server principal is 
zookeeper/hadoop.hadoop....@hadoop.com then this becomes the system user and 
all the system operations will be logged with this user name.</p>
+<pre><code>user=zookeeper/hadoop.hadoop....@hadoop.com operation=serverStart 
result=success
+</code></pre>
+<p>If there is no user associate with ZooKeeper server then the user who 
started the ZooKeeper server is taken as the user. For example if server 
started by root then root is taken as the system user</p>
+<pre><code>user=root operation=serverStart result=success
+</code></pre>
+<p>Single client can attach multiple authentication schemes to a session, in 
this case all authenticated schemes will taken taken as user and will be 
presented as comma separated list. For example if a client is authenticate with 
principal zk...@hadoop.com and ip 127.0.0.1 then create znode audit log will be 
as:</p>
+<pre><code>session=0x10c0bcb0000 user=zk...@hadoop.com,127.0.0.1 ip=127.0.0.1 
operation=create znode=/a result=success
+</code></pre>
+</div>
+<div class="clearboth">&nbsp;</div>
+</div>
+<div id="footer">
+    <div class="lastmodified">
+        <script type="text/javascript">
+        <!--
+            document.write("Last Published: " + document.lastModified);
+        //  -->
+        </script>
+    </div>
+    <div class="copyright">
+        Copyright &copy; <a href="http://www.apache.org/licenses/";>The Apache 
Software Foundation.</a>
+    </div>
+    <div id="logos"></div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperCLI.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperCLI.html (added)
+++ dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperCLI.html Fri Oct 
 6 10:00:32 2023
@@ -0,0 +1,657 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>ZooKeeper: Because Coordinating Distributed Systems is a Zoo</title>
+    <link type="text/css" href="skin/basic.css" rel="stylesheet">
+    <link media="screen" type="text/css" href="skin/screen.css" 
rel="stylesheet">
+    <link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
+    <link type="text/css" href="skin/profile.css" rel="stylesheet">
+    <script src="skin/getBlank.js" language="javascript" 
type="text/javascript"></script>
+    <script src="skin/getMenu.js" language="javascript" 
type="text/javascript"></script>
+    <script src="skin/init.js" language="javascript" 
type="text/javascript"></script>
+    <link rel="shortcut icon" href="images/favicon.ico">
+</head>
+<body onload="init();">
+<div id="top">
+    <div class="breadtrail">
+        <a href="http://www.apache.org/";>Apache</a> &gt; <a 
href="http://zookeeper.apache.org/";>ZooKeeper</a>
+    </div>
+    <div class="header">
+        <div class="projectlogo">
+            <a href="http://zookeeper.apache.org/";><img class="logoImage" 
alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed 
coordination"></a>
+        </div>
+        <div class="searchbox">
+            <form action="http://www.google.com/search"; method="get">
+                <input value="zookeeper.apache.org" name="sitesearch" 
type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" 
size="25" name="q" id="query" type="text" value="Search the site with 
google">&nbsp;
+                <input name="Search" value="Search" type="submit">
+            </form>
+        </div>
+        <ul id="tabs">
+            <li>
+                <a class="unselected" 
href="http://zookeeper.apache.org/";>Project</a>
+            </li>
+            <li>
+                <a class="unselected" 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/";>Wiki</a>
+            </li>
+            <li class="current">
+                <a class="selected" href="index.html">ZooKeeper 3.7 
Documentation</a>
+            </li>
+        </ul>
+    </div>
+</div>
+<div id="main">
+    <div id="publishedStrip">
+        <div id="level2tabs"></div>
+        <script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+    </div>
+    <div class="breadtrail">
+        &nbsp;
+    </div>
+    <div id="menu">
+        <div onclick="SwitchMenu('menu_1', 'skin/')" id="menu_1Title" 
class="menutitle">Overview</div>
+        <div id="menu_1" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="index.html">Welcome</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperOver.html">Overview</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperStarted.html">Getting Started</a>
+            </div>
+            <div class="menuitem">
+                <a href="releasenotes.html">Release Notes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_2', 'skin/')" id="menu_2Title" 
class="menutitle">Developer</div>
+        <div id="menu_2" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="apidocs/zookeeper-server/index.html">API Docs</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperProgrammers.html">Programmer's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperUseCases.html">Use Cases</a>
+            </div>
+            <div class="menuitem">
+                <a href="javaExample.html">Java Example</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTutorial.html">Barrier and Queue Tutorial</a>
+            </div>
+            <div class="menuitem">
+                <a href="recipes.html">Recipes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_3', 'skin/')" id="menu_3Title" 
class="menutitle">Admin &amp; Ops</div>
+        <div id="menu_3" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperAdmin.html">Administrator's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperQuotas.html">Quota Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperJMX.html">JMX</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperHierarchicalQuorums.html">Hierarchical 
Quorums</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperObservers.html">Observers Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperReconfig.html">Dynamic Reconfiguration</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperCLI.html">ZooKeeper CLI</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTools.html">ZooKeeper Tools</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperMonitor.html">ZooKeeper Monitor</a>
+            </div>
+                       <div class="menuitem">
+                <a href="zookeeperAuditLogs.html">Audit Logs</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_4', 'skin/')" id="menu_4Title" 
class="menutitle">Contributor</div>
+        <div id="menu_4" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperInternals.html">ZooKeeper Internals</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_5', 'skin/')" id="menu_5Title" 
class="menutitle">Miscellaneous</div>
+        <div id="menu_5" class="menuitemgroup">
+            <div class="menuitem">
+                <a 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER";>Wiki</a>
+            </div>
+            <div class="menuitem">
+                <a 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/FAQ";>FAQ</a>
+            </div>
+            <div class="menuitem">
+                <a 
href="http://zookeeper.apache.org/mailing_lists.html";>Mailing Lists</a>
+            </div>
+        </div>
+    </div>
+    <div id="content">
+<!--
+Copyright 2002-2021 The Apache Software Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+//-->
+<h1>ZooKeeper-cli: the ZooKeeper command line interface</h1>
+<h2>Pre-requisites</h2>
+<p>Enter into the ZooKeeper-cli</p>
+<pre><code class="language-bash"># connect to the localhost with the default 
port:2181
+bin/zkCli.sh
+# connect to the remote host with timeout:3s
+bin/zkCli.sh -timeout 3000 -server remoteIP:2181
+# connect to the remote host with -waitforconnection option to wait for 
connection success before executing commands
+bin/zkCli.sh -waitforconnection -timeout 3000 -server remoteIP:2181
+# connect with a custom client configuration properties file
+bin/zkCli.sh -client-configuration /path/to/client.properties
+</code></pre>
+<h2>help</h2>
+<p>Showing helps about ZooKeeper commands</p>
+<pre><code class="language-bash">[zkshell: 1] help
+# a sample one
+[zkshell: 2] h
+ZooKeeper -server host:port cmd args
+       addauth scheme auth
+       close
+       config [-c] [-w] [-s]
+       connect host:port
+       create [-s] [-e] [-c] [-t ttl] path [data] [acl]
+       delete [-v version] path
+       deleteall path
+       delquota [-n|-b|-N|-B] path
+       get [-s] [-w] path
+       getAcl [-s] path
+       getAllChildrenNumber path
+       getEphemerals path
+       history
+       listquota path
+       ls [-s] [-w] [-R] path
+       printwatches on|off
+       quit
+       reconfig [-s] [-v version] [[-file path] | [-members 
serverID=host:port1:port2;port3[,...]*]] | [-add 
serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
+       redo cmdno
+       removewatches path [-c|-d|-a] [-l]
+       set [-s] [-v version] path data
+       setAcl [-s] [-v version] [-R] path acl
+       setquota -n|-b|-N|-B val path
+       stat [-w] path
+       sync path
+       version
+</code></pre>
+<h2>addauth</h2>
+<p>Add a authorized user for ACL</p>
+<pre><code class="language-bash">[zkshell: 9] getAcl /acl_digest_test
+    Insufficient permission : /acl_digest_test
+[zkshell: 10] addauth digest user1:12345
+[zkshell: 11] getAcl /acl_digest_test
+    'digest,'user1:+owfoSBn/am19roBPzR1/MfCblE=
+    : cdrwa
+# add a super user
+# Notice:set zookeeper.DigestAuthenticationProvider
+# e.g. 
zookeeper.DigestAuthenticationProvider.superDigest=zookeeper:qW/HnTfCSoQpB5G8LgkwT3IbiFc=
+[zkshell: 12] addauth digest zookeeper:admin
+</code></pre>
+<h2>close</h2>
+<p>Close this client/session.</p>
+<pre><code class="language-bash">[zkshell: 0] close
+       2019-03-09 06:42:22,178 [myid:] - INFO  
[main-EventThread:ClientCnxn$EventThread@528] - EventThread shut down for 
session: 0x10007ab7c550006
+       2019-03-09 06:42:22,179 [myid:] - INFO  [main:ZooKeeper@1346] - 
Session: 0x10007ab7c550006 closed
+</code></pre>
+<h2>config</h2>
+<p>Showing the config of quorum membership</p>
+<pre><code class="language-bash">[zkshell: 17] config
+       server.1=[2001:db8:1:0:0:242:ac11:2]:2888:3888:participant
+       server.2=[2001:db8:1:0:0:242:ac11:2]:12888:13888:participant
+       server.3=[2001:db8:1:0:0:242:ac11:2]:22888:23888:participant
+       version=0
+</code></pre>
+<h2>connect</h2>
+<p>Connect a ZooKeeper server.</p>
+<pre><code class="language-bash">[zkshell: 4] connect
+       2019-03-09 06:43:33,179 [myid:localhost:2181] - INFO  
[main-SendThread(localhost:2181):ClientCnxn$SendThread@986] - Socket connection 
established, initiating session, client: /127.0.0.1:35144, server: 
localhost/127.0.0.1:2181
+       2019-03-09 06:43:33,189 [myid:localhost:2181] - INFO  
[main-SendThread(localhost:2181):ClientCnxn$SendThread@1421] - Session 
establishment complete on server localhost/127.0.0.1:2181, sessionid = 
0x10007ab7c550007, negotiated timeout = 30000
+       connect &quot;localhost:2181,localhost:2182,localhost:2183&quot;
+
+# connect a remote server
+[zkshell: 5] connect remoteIP:2181
+</code></pre>
+<h2>create</h2>
+<p>Create a znode.</p>
+<pre><code class="language-bash"># create a persistent_node
+[zkshell: 7] create /persistent_node
+       Created /persistent_node
+
+# create a ephemeral node
+[zkshell: 8] create -e /ephemeral_node mydata
+       Created /ephemeral_node
+
+# create the persistent-sequential node
+[zkshell: 9] create -s /persistent_sequential_node mydata
+       Created /persistent_sequential_node0000000176
+
+# create the ephemeral-sequential_node
+[zkshell: 10] create -s -e /ephemeral_sequential_node mydata
+       Created /ephemeral_sequential_node0000000174
+
+# create a node with the schema
+[zkshell: 11] create /zk-node-create-schema mydata 
digest:user1:+owfoSBn/am19roBPzR1/MfCblE=:crwad
+       Created /zk-node-create-schema
+[zkshell: 12] addauth digest user1:12345
+[zkshell: 13] getAcl /zk-node-create-schema
+       'digest,'user1:+owfoSBn/am19roBPzR1/MfCblE=
+       : cdrwa
+
+# create the container node.When the last child of a container is deleted,the 
container becomes to be deleted
+[zkshell: 14] create -c /container_node mydata
+       Created /container_node
+[zkshell: 15] create -c /container_node/child_1 mydata
+       Created /container_node/child_1
+[zkshell: 16] create -c /container_node/child_2 mydata
+       Created /container_node/child_2
+[zkshell: 17] delete /container_node/child_1
+[zkshell: 18] delete /container_node/child_2
+[zkshell: 19] get /container_node
+       org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = 
NoNode for /container_node
+
+# create the ttl node.
+# set zookeeper.extendedTypesEnabled=true
+# Otherwise:KeeperErrorCode = Unimplemented for /ttl_node
+[zkshell: 20] create -t 3000 /ttl_node mydata
+       Created /ttl_node
+# after 3s later
+[zkshell: 21] get /ttl_node
+       org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = 
NoNode for /ttl_node
+</code></pre>
+<h2>delete</h2>
+<p>Delete a node with a specific path</p>
+<pre><code class="language-bash">[zkshell: 2] delete /config/topics/test
+[zkshell: 3] ls /config/topics/test
+       Node does not exist: /config/topics/test
+</code></pre>
+<h2>deleteall</h2>
+<p>Delete all nodes under a specific path</p>
+<pre><code class="language-bash">zkshell: 1] ls /config
+       [changes, clients, topics]
+[zkshell: 2] deleteall /config
+[zkshell: 3] ls /config
+       Node does not exist: /config
+</code></pre>
+<h2>delquota</h2>
+<p>Delete the quota under a path</p>
+<pre><code class="language-bash">[zkshell: 1] delquota /quota_test
+[zkshell: 2] listquota /quota_test
+       absolute path is /zookeeper/quota/quota_test/zookeeper_limits
+       quota for /quota_test does not exist.
+[zkshell: 3] delquota -n /c1
+[zkshell: 4] delquota -N /c2
+[zkshell: 5] delquota -b /c3
+[zkshell: 6] delquota -B /c4
+
+</code></pre>
+<h2>get</h2>
+<p>Get the data of the specific path</p>
+<pre><code class="language-bash">[zkshell: 10] get /latest_producer_id_block
+       
{&quot;version&quot;:1,&quot;broker&quot;:0,&quot;block_start&quot;:&quot;0&quot;,&quot;block_end&quot;:&quot;999&quot;}
+
+# -s to show the stat
+[zkshell: 11] get -s /latest_producer_id_block
+       
{&quot;version&quot;:1,&quot;broker&quot;:0,&quot;block_start&quot;:&quot;0&quot;,&quot;block_end&quot;:&quot;999&quot;}
+       cZxid = 0x90000009a
+       ctime = Sat Jul 28 08:14:09 UTC 2018
+       mZxid = 0x9000000a2
+       mtime = Sat Jul 28 08:14:12 UTC 2018
+       pZxid = 0x90000009a
+       cversion = 0
+       dataVersion = 1
+       aclVersion = 0
+       ephemeralOwner = 0x0
+       dataLength = 60
+       numChildren = 0
+
+# -w to set a watch on the data change, Notice: turn on the printwatches
+[zkshell: 12] get -w /latest_producer_id_block
+       
{&quot;version&quot;:1,&quot;broker&quot;:0,&quot;block_start&quot;:&quot;0&quot;,&quot;block_end&quot;:&quot;999&quot;}
+[zkshell: 13] set /latest_producer_id_block mydata
+       WATCHER::
+       WatchedEvent state:SyncConnected type:NodeDataChanged 
path:/latest_producer_id_block
+</code></pre>
+<h2>getAcl</h2>
+<p>Get the ACL permission of one path</p>
+<pre><code class="language-bash">[zkshell: 4] create /acl_test mydata 
ip:127.0.0.1:crwda
+       Created /acl_test
+[zkshell: 5] getAcl /acl_test
+       'ip,'127.0.0.1
+       : cdrwa
+       [zkshell: 6] getAcl /testwatch
+       'world,'anyone
+       : cdrwa
+</code></pre>
+<h2>getAllChildrenNumber</h2>
+<p>Get all numbers of children nodes under a specific path</p>
+<pre><code class="language-bash">[zkshell: 1] getAllChildrenNumber /
+       73779
+[zkshell: 2] getAllChildrenNumber /ZooKeeper
+       2
+[zkshell: 3] getAllChildrenNumber /ZooKeeper/quota
+       0
+</code></pre>
+<h2>getEphemerals</h2>
+<p>Get all the ephemeral nodes created by this session</p>
+<pre><code class="language-bash">[zkshell: 1] create -e /test-get-ephemerals 
&quot;ephemeral node&quot;
+       Created /test-get-ephemerals
+[zkshell: 2] getEphemerals
+       [/test-get-ephemerals]
+[zkshell: 3] getEphemerals /
+       [/test-get-ephemerals]
+[zkshell: 4] create -e /test-get-ephemerals-1 &quot;ephemeral node&quot;
+       Created /test-get-ephemerals-1
+[zkshell: 5] getEphemerals /test-get-ephemerals
+       test-get-ephemerals     test-get-ephemerals-1
+[zkshell: 6] getEphemerals /test-get-ephemerals
+       [/test-get-ephemerals-1, /test-get-ephemerals]
+[zkshell: 7] getEphemerals /test-get-ephemerals-1
+       [/test-get-ephemerals-1]
+</code></pre>
+<h2>history</h2>
+<p>Showing the history about the recent 11 commands that you have executed</p>
+<pre><code class="language-bash">[zkshell: 7] history
+       0 - close
+       1 - close
+       2 - ls /
+       3 - ls /
+       4 - connect
+       5 - ls /
+       6 - ll
+       7 - history
+</code></pre>
+<h2>listquota</h2>
+<p>Listing the quota of one path</p>
+<pre><code class="language-bash">[zkshell: 1] listquota /c1
+             absolute path is /zookeeper/quota/c1/zookeeper_limits
+             Output quota for /c1 
count=-1,bytes=-1=;byteHardLimit=-1;countHardLimit=2
+             Output stat for /c1 count=4,bytes=0
+</code></pre>
+<h2>ls</h2>
+<p>Listing the child nodes of one path</p>
+<pre><code class="language-bash">[zkshell: 36] ls /quota_test
+       [child_1, child_2, child_3]
+
+# -s to show the stat
+[zkshell: 37] ls -s /quota_test
+       [child_1, child_2, child_3]
+       cZxid = 0x110000002d
+       ctime = Thu Mar 07 11:19:07 UTC 2019
+       mZxid = 0x110000002d
+       mtime = Thu Mar 07 11:19:07 UTC 2019
+       pZxid = 0x1100000033
+       cversion = 3
+       dataVersion = 0
+       aclVersion = 0
+       ephemeralOwner = 0x0
+       dataLength = 0
+       numChildren = 3
+
+# -R to show the child nodes recursely
+[zkshell: 38] ls -R /quota_test
+       /quota_test
+       /quota_test/child_1
+       /quota_test/child_2
+       /quota_test/child_3
+
+# -w to set a watch on the child change,Notice: turn on the printwatches
+[zkshell: 39] ls -w /brokers
+       [ids, seqid, topics]
+[zkshell: 40] delete /brokers/ids
+       WATCHER::
+       WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/brokers
+</code></pre>
+<h2>printwatches</h2>
+<p>A switch to turn on/off whether printing watches or not.</p>
+<pre><code class="language-bash">[zkshell: 0] printwatches
+       printwatches is on
+[zkshell: 1] printwatches off
+[zkshell: 2] printwatches
+       printwatches is off
+[zkshell: 3] printwatches on
+[zkshell: 4] printwatches
+       printwatches is on
+</code></pre>
+<h2>quit</h2>
+<p>Quit the CLI windows.</p>
+<pre><code class="language-bash">[zkshell: 1] quit
+</code></pre>
+<h2>reconfig</h2>
+<p>Change the membership of the ensemble during the runtime.</p>
+<p>Before using this cli,read the details in the <a 
href="zookeeperReconfig.html">Dynamic Reconfiguration</a> about the reconfig 
feature,especially the &quot;Security&quot; part.</p>
+<p>Pre-requisites:</p>
+<ol>
+<li>
+<p>set reconfigEnabled=true in the zoo.cfg</p>
+</li>
+<li>
+<p>add a super user or skipAcl,otherwise will get “Insufficient 
permission”. e.g. addauth digest zookeeper:admin</p>
+</li>
+</ol>
+<pre><code class="language-bash"># Change follower 2 to an observer and change 
its port from 2182 to 12182
+# Add observer 5 to the ensemble
+# Remove Observer 4 from the ensemble
+[zkshell: 1] reconfig --add 2=localhost:2781:2786:observer;12182 --add 
5=localhost:2781:2786:observer;2185 -remove 4
+       Committed new configuration:
+       server.1=localhost:2780:2785:participant;0.0.0.0:2181
+       server.2=localhost:2781:2786:observer;0.0.0.0:12182
+       server.3=localhost:2782:2787:participant;0.0.0.0:2183
+       server.5=localhost:2784:2789:observer;0.0.0.0:2185
+       version=1c00000002
+
+# -members to appoint the membership
+[zkshell: 2] reconfig -members 
server.1=localhost:2780:2785:participant;0.0.0.0:2181,server.2=localhost:2781:2786:observer;0.0.0.0:12182,server.3=localhost:2782:2787:participant;0.0.0.0:12183
+       Committed new configuration:
+       server.1=localhost:2780:2785:participant;0.0.0.0:2181
+       server.2=localhost:2781:2786:observer;0.0.0.0:12182
+       server.3=localhost:2782:2787:participant;0.0.0.0:12183
+       version=f9fe0000000c
+
+# Change the current config to the one in the myNewConfig.txt
+# But only if current config version is 2100000010
+[zkshell: 3] reconfig -file 
/data/software/zookeeper/zookeeper-test/conf/myNewConfig.txt -v 2100000010
+       Committed new configuration:
+       server.1=localhost:2780:2785:participant;0.0.0.0:2181
+       server.2=localhost:2781:2786:observer;0.0.0.0:12182
+       server.3=localhost:2782:2787:participant;0.0.0.0:2183
+       server.5=localhost:2784:2789:observer;0.0.0.0:2185
+       version=220000000c
+</code></pre>
+<h2>redo</h2>
+<p>Redo the cmd with the index from history.</p>
+<pre><code class="language-bash">[zkshell: 4] history
+       0 - ls /
+       1 - get /consumers
+       2 - get /hbase
+       3 - ls  /hbase
+       4 - history
+[zkshell: 5] redo 3
+       [backup-masters, draining, flush-table-proc, hbaseid, 
master-maintenance, meta-region-server, namespace, online-snapshot, 
replication, rs, running, splitWAL, switch, table, table-lock]
+</code></pre>
+<h2>removewatches</h2>
+<p>Remove the watches under a node.</p>
+<pre><code class="language-bash">[zkshell: 1] get -w /brokers
+       null
+[zkshell: 2] removewatches /brokers
+       WATCHER::
+       WatchedEvent state:SyncConnected type:DataWatchRemoved path:/brokers
+
+</code></pre>
+<h2>set</h2>
+<p>Set/update the data on a path.</p>
+<pre><code class="language-bash">[zkshell: 50] set /brokers myNewData
+
+# -s to show the stat of this node.
+[zkshell: 51] set -s /quota_test mydata_for_quota_test
+       cZxid = 0x110000002d
+       ctime = Thu Mar 07 11:19:07 UTC 2019
+       mZxid = 0x1100000038
+       mtime = Thu Mar 07 11:42:41 UTC 2019
+       pZxid = 0x1100000033
+       cversion = 3
+       dataVersion = 2
+       aclVersion = 0
+       ephemeralOwner = 0x0
+       dataLength = 21
+       numChildren = 3
+
+# -v to set the data with CAS,the version can be found from dataVersion using 
stat.
+[zkshell: 52] set -v 0 /brokers myNewData
+[zkshell: 53] set -v 0 /brokers myNewData
+       version No is not valid : /brokers
+</code></pre>
+<h2>setAcl</h2>
+<p>Set the Acl permission for one node.</p>
+<pre><code class="language-bash">[zkshell: 28] addauth digest user1:12345
+[zkshell: 30] setAcl /acl_auth_test auth:user1:12345:crwad
+[zkshell: 31] getAcl /acl_auth_test
+       'digest,'user1:+owfoSBn/am19roBPzR1/MfCblE=
+       : cdrwa
+
+# -R to set Acl recursely
+[zkshell: 32] ls /acl_auth_test
+       [child_1, child_2]
+[zkshell: 33] getAcl /acl_auth_test/child_2
+       'world,'anyone
+       : cdrwa
+[zkshell: 34] setAcl -R /acl_auth_test auth:user1:12345:crwad
+[zkshell: 35] getAcl /acl_auth_test/child_2
+       'digest,'user1:+owfoSBn/am19roBPzR1/MfCblE=
+       : cdrwa
+
+# -v set Acl with the acl version which can be found from the aclVersion using 
the stat
+[zkshell: 36] stat /acl_auth_test
+       cZxid = 0xf9fc0000001c
+       ctime = Tue Mar 26 16:50:58 CST 2019
+       mZxid = 0xf9fc0000001c
+       mtime = Tue Mar 26 16:50:58 CST 2019
+       pZxid = 0xf9fc0000001f
+       cversion = 2
+       dataVersion = 0
+       aclVersion = 3
+       ephemeralOwner = 0x0
+       dataLength = 0
+       numChildren = 2
+[zkshell: 37] setAcl -v 3 /acl_auth_test auth:user1:12345:crwad
+</code></pre>
+<h2>setquota</h2>
+<p>Set the quota in one path.</p>
+<pre><code class="language-bash"># -n to limit the number of child 
nodes(included itself)
+[zkshell: 18] setquota -n 2 /quota_test
+[zkshell: 19] create /quota_test/child_1
+       Created /quota_test/child_1
+[zkshell: 20] create /quota_test/child_2
+       Created /quota_test/child_2
+[zkshell: 21] create /quota_test/child_3
+       Created /quota_test/child_3
+# Notice:don't have a hard constraint,just log the warning info
+       2019-03-07 11:22:36,680 [myid:1] - WARN  [SyncThread:0:DataTree@374] - 
Quota exceeded: /quota_test count=3 limit=2
+       2019-03-07 11:22:41,861 [myid:1] - WARN  [SyncThread:0:DataTree@374] - 
Quota exceeded: /quota_test count=4 limit=2
+
+# -b to limit the bytes(data length) of one path
+[zkshell: 22] setquota -b 5 /brokers
+[zkshell: 23] set /brokers &quot;I_love_zookeeper&quot;
+# Notice:don't have a hard constraint,just log the warning info
+       WARN  [CommitProcWorkThread-7:DataTree@379] - Quota exceeded: /brokers 
bytes=4206 limit=5
+
+# -N count Hard quota
+[zkshell: 3] create /c1
+Created /c1
+[zkshell: 4] setquota -N 2 /c1
+[zkshell: 5] listquota /c1
+absolute path is /zookeeper/quota/c1/zookeeper_limits
+Output quota for /c1 count=-1,bytes=-1=;byteHardLimit=-1;countHardLimit=2
+Output stat for /c1 count=2,bytes=0
+[zkshell: 6] create /c1/ch-3
+Count Quota has exceeded : /c1/ch-3
+
+# -B byte Hard quota
+[zkshell: 3] create /c2
+[zkshell: 4] setquota -B 4 /c2
+[zkshell: 5] set /c2 &quot;foo&quot;
+[zkshell: 6] set /c2 &quot;foo-bar&quot;
+Bytes Quota has exceeded : /c2
+[zkshell: 7] get /c2
+foo
+</code></pre>
+<h2>stat</h2>
+<p>Showing the stat/metadata of one node.</p>
+<pre><code class="language-bash">[zkshell: 1] stat /hbase
+       cZxid = 0x4000013d9
+       ctime = Wed Jun 27 20:13:07 CST 2018
+       mZxid = 0x4000013d9
+       mtime = Wed Jun 27 20:13:07 CST 2018
+       pZxid = 0x500000001
+       cversion = 17
+       dataVersion = 0
+       aclVersion = 0
+       ephemeralOwner = 0x0
+       dataLength = 0
+       numChildren = 15
+</code></pre>
+<h2>sync</h2>
+<p>Sync the data of one node between leader and followers(Asynchronous 
sync)</p>
+<pre><code class="language-bash">[zkshell: 14] sync /
+[zkshell: 15] Sync is OK
+</code></pre>
+<h2>version</h2>
+<p>Show the version of the ZooKeeper client/CLI</p>
+<pre><code class="language-bash">[zkshell: 1] version
+ZooKeeper CLI version: 
3.6.0-SNAPSHOT-29f9b2c1c0e832081f94d59a6b88709c5f1bb3ca, built on 05/30/2019 
09:26 GMT
+</code></pre>
+<h2>whoami</h2>
+<p>Gives all authentication information added into the current session.</p>
+<pre><code>[zkshell: 1] whoami
+Auth scheme: User
+ip: 127.0.0.1
+[zkshell: 2] addauth digest user1:12345
+[zkshell: 3] whoami
+Auth scheme: User
+ip: 127.0.0.1
+digest: user1
+</code></pre>
+</div>
+<div class="clearboth">&nbsp;</div>
+</div>
+<div id="footer">
+    <div class="lastmodified">
+        <script type="text/javascript">
+        <!--
+            document.write("Last Published: " + document.lastModified);
+        //  -->
+        </script>
+    </div>
+    <div class="copyright">
+        Copyright &copy; <a href="http://www.apache.org/licenses/";>The Apache 
Software Foundation.</a>
+    </div>
+    <div id="logos"></div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: 
dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperHierarchicalQuorums.html
==============================================================================
--- 
dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperHierarchicalQuorums.html
 (added)
+++ 
dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperHierarchicalQuorums.html
 Fri Oct  6 10:00:32 2023
@@ -0,0 +1,194 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>ZooKeeper: Because Coordinating Distributed Systems is a Zoo</title>
+    <link type="text/css" href="skin/basic.css" rel="stylesheet">
+    <link media="screen" type="text/css" href="skin/screen.css" 
rel="stylesheet">
+    <link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
+    <link type="text/css" href="skin/profile.css" rel="stylesheet">
+    <script src="skin/getBlank.js" language="javascript" 
type="text/javascript"></script>
+    <script src="skin/getMenu.js" language="javascript" 
type="text/javascript"></script>
+    <script src="skin/init.js" language="javascript" 
type="text/javascript"></script>
+    <link rel="shortcut icon" href="images/favicon.ico">
+</head>
+<body onload="init();">
+<div id="top">
+    <div class="breadtrail">
+        <a href="http://www.apache.org/";>Apache</a> &gt; <a 
href="http://zookeeper.apache.org/";>ZooKeeper</a>
+    </div>
+    <div class="header">
+        <div class="projectlogo">
+            <a href="http://zookeeper.apache.org/";><img class="logoImage" 
alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed 
coordination"></a>
+        </div>
+        <div class="searchbox">
+            <form action="http://www.google.com/search"; method="get">
+                <input value="zookeeper.apache.org" name="sitesearch" 
type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" 
size="25" name="q" id="query" type="text" value="Search the site with 
google">&nbsp;
+                <input name="Search" value="Search" type="submit">
+            </form>
+        </div>
+        <ul id="tabs">
+            <li>
+                <a class="unselected" 
href="http://zookeeper.apache.org/";>Project</a>
+            </li>
+            <li>
+                <a class="unselected" 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/";>Wiki</a>
+            </li>
+            <li class="current">
+                <a class="selected" href="index.html">ZooKeeper 3.7 
Documentation</a>
+            </li>
+        </ul>
+    </div>
+</div>
+<div id="main">
+    <div id="publishedStrip">
+        <div id="level2tabs"></div>
+        <script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+    </div>
+    <div class="breadtrail">
+        &nbsp;
+    </div>
+    <div id="menu">
+        <div onclick="SwitchMenu('menu_1', 'skin/')" id="menu_1Title" 
class="menutitle">Overview</div>
+        <div id="menu_1" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="index.html">Welcome</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperOver.html">Overview</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperStarted.html">Getting Started</a>
+            </div>
+            <div class="menuitem">
+                <a href="releasenotes.html">Release Notes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_2', 'skin/')" id="menu_2Title" 
class="menutitle">Developer</div>
+        <div id="menu_2" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="apidocs/zookeeper-server/index.html">API Docs</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperProgrammers.html">Programmer's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperUseCases.html">Use Cases</a>
+            </div>
+            <div class="menuitem">
+                <a href="javaExample.html">Java Example</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTutorial.html">Barrier and Queue Tutorial</a>
+            </div>
+            <div class="menuitem">
+                <a href="recipes.html">Recipes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_3', 'skin/')" id="menu_3Title" 
class="menutitle">Admin &amp; Ops</div>
+        <div id="menu_3" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperAdmin.html">Administrator's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperQuotas.html">Quota Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperJMX.html">JMX</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperHierarchicalQuorums.html">Hierarchical 
Quorums</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperObservers.html">Observers Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperReconfig.html">Dynamic Reconfiguration</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperCLI.html">ZooKeeper CLI</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTools.html">ZooKeeper Tools</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperMonitor.html">ZooKeeper Monitor</a>
+            </div>
+                       <div class="menuitem">
+                <a href="zookeeperAuditLogs.html">Audit Logs</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_4', 'skin/')" id="menu_4Title" 
class="menutitle">Contributor</div>
+        <div id="menu_4" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperInternals.html">ZooKeeper Internals</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_5', 'skin/')" id="menu_5Title" 
class="menutitle">Miscellaneous</div>
+        <div id="menu_5" class="menuitemgroup">
+            <div class="menuitem">
+                <a 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER";>Wiki</a>
+            </div>
+            <div class="menuitem">
+                <a 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/FAQ";>FAQ</a>
+            </div>
+            <div class="menuitem">
+                <a 
href="http://zookeeper.apache.org/mailing_lists.html";>Mailing Lists</a>
+            </div>
+        </div>
+    </div>
+    <div id="content">
+<!--
+Copyright 2002-2004 The Apache Software Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+//-->
+<h1>Introduction to hierarchical quorums</h1>
+<p>This document gives an example of how to use hierarchical quorums. The 
basic idea is very simple. First, we split servers into groups, and add a line 
for each group listing the servers that form this group. Next we have to assign 
a weight to each server.</p>
+<p>The following example shows how to configure a system with three groups of 
three servers each, and we assign a weight of 1 to each server:</p>
+<pre><code>group.1=1:2:3
+group.2=4:5:6
+group.3=7:8:9
+
+weight.1=1
+weight.2=1
+weight.3=1
+weight.4=1
+weight.5=1
+weight.6=1
+weight.7=1
+weight.8=1
+weight.9=1
+</code></pre>
+<p>When running the system, we are able to form a quorum once we have a 
majority of votes from a majority of non-zero-weight groups. Groups that have 
zero weight are discarded and not considered when forming quorums. Looking at 
the example, we are able to form a quorum once we have votes from at least two 
servers from each of two different groups.</p>
+</div>
+<div class="clearboth">&nbsp;</div>
+</div>
+<div id="footer">
+    <div class="lastmodified">
+        <script type="text/javascript">
+        <!--
+            document.write("Last Published: " + document.lastModified);
+        //  -->
+        </script>
+    </div>
+    <div class="copyright">
+        Copyright &copy; <a href="http://www.apache.org/licenses/";>The Apache 
Software Foundation.</a>
+    </div>
+    <div id="logos"></div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperInternals.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperInternals.html 
(added)
+++ dev/zookeeper/zookeeper-3.7.2-candidate-0/website/zookeeperInternals.html 
Fri Oct  6 10:00:32 2023
@@ -0,0 +1,360 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>ZooKeeper: Because Coordinating Distributed Systems is a Zoo</title>
+    <link type="text/css" href="skin/basic.css" rel="stylesheet">
+    <link media="screen" type="text/css" href="skin/screen.css" 
rel="stylesheet">
+    <link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
+    <link type="text/css" href="skin/profile.css" rel="stylesheet">
+    <script src="skin/getBlank.js" language="javascript" 
type="text/javascript"></script>
+    <script src="skin/getMenu.js" language="javascript" 
type="text/javascript"></script>
+    <script src="skin/init.js" language="javascript" 
type="text/javascript"></script>
+    <link rel="shortcut icon" href="images/favicon.ico">
+</head>
+<body onload="init();">
+<div id="top">
+    <div class="breadtrail">
+        <a href="http://www.apache.org/";>Apache</a> &gt; <a 
href="http://zookeeper.apache.org/";>ZooKeeper</a>
+    </div>
+    <div class="header">
+        <div class="projectlogo">
+            <a href="http://zookeeper.apache.org/";><img class="logoImage" 
alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed 
coordination"></a>
+        </div>
+        <div class="searchbox">
+            <form action="http://www.google.com/search"; method="get">
+                <input value="zookeeper.apache.org" name="sitesearch" 
type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" 
size="25" name="q" id="query" type="text" value="Search the site with 
google">&nbsp;
+                <input name="Search" value="Search" type="submit">
+            </form>
+        </div>
+        <ul id="tabs">
+            <li>
+                <a class="unselected" 
href="http://zookeeper.apache.org/";>Project</a>
+            </li>
+            <li>
+                <a class="unselected" 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/";>Wiki</a>
+            </li>
+            <li class="current">
+                <a class="selected" href="index.html">ZooKeeper 3.7 
Documentation</a>
+            </li>
+        </ul>
+    </div>
+</div>
+<div id="main">
+    <div id="publishedStrip">
+        <div id="level2tabs"></div>
+        <script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+    </div>
+    <div class="breadtrail">
+        &nbsp;
+    </div>
+    <div id="menu">
+        <div onclick="SwitchMenu('menu_1', 'skin/')" id="menu_1Title" 
class="menutitle">Overview</div>
+        <div id="menu_1" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="index.html">Welcome</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperOver.html">Overview</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperStarted.html">Getting Started</a>
+            </div>
+            <div class="menuitem">
+                <a href="releasenotes.html">Release Notes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_2', 'skin/')" id="menu_2Title" 
class="menutitle">Developer</div>
+        <div id="menu_2" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="apidocs/zookeeper-server/index.html">API Docs</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperProgrammers.html">Programmer's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperUseCases.html">Use Cases</a>
+            </div>
+            <div class="menuitem">
+                <a href="javaExample.html">Java Example</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTutorial.html">Barrier and Queue Tutorial</a>
+            </div>
+            <div class="menuitem">
+                <a href="recipes.html">Recipes</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_3', 'skin/')" id="menu_3Title" 
class="menutitle">Admin &amp; Ops</div>
+        <div id="menu_3" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperAdmin.html">Administrator's Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperQuotas.html">Quota Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperJMX.html">JMX</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperHierarchicalQuorums.html">Hierarchical 
Quorums</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperObservers.html">Observers Guide</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperReconfig.html">Dynamic Reconfiguration</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperCLI.html">ZooKeeper CLI</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperTools.html">ZooKeeper Tools</a>
+            </div>
+            <div class="menuitem">
+                <a href="zookeeperMonitor.html">ZooKeeper Monitor</a>
+            </div>
+                       <div class="menuitem">
+                <a href="zookeeperAuditLogs.html">Audit Logs</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_4', 'skin/')" id="menu_4Title" 
class="menutitle">Contributor</div>
+        <div id="menu_4" class="menuitemgroup">
+            <div class="menuitem">
+                <a href="zookeeperInternals.html">ZooKeeper Internals</a>
+            </div>
+        </div>
+        <div onclick="SwitchMenu('menu_5', 'skin/')" id="menu_5Title" 
class="menutitle">Miscellaneous</div>
+        <div id="menu_5" class="menuitemgroup">
+            <div class="menuitem">
+                <a 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER";>Wiki</a>
+            </div>
+            <div class="menuitem">
+                <a 
href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/FAQ";>FAQ</a>
+            </div>
+            <div class="menuitem">
+                <a 
href="http://zookeeper.apache.org/mailing_lists.html";>Mailing Lists</a>
+            </div>
+        </div>
+    </div>
+    <div id="content">
+<!--
+Copyright 2002-2004 The Apache Software Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+//-->
+<h1>ZooKeeper Internals</h1>
+<ul>
+<li><a href="#ch_Introduction">Introduction</a></li>
+<li><a href="#sc_atomicBroadcast">Atomic Broadcast</a>
+<ul>
+<li><a href="#sc_guaranteesPropertiesDefinitions">Guarantees, Properties, and 
Definitions</a></li>
+<li><a href="#sc_leaderElection">Leader Activation</a></li>
+<li><a href="#sc_activeMessaging">Active Messaging</a></li>
+<li><a href="#sc_summary">Summary</a></li>
+<li><a href="#sc_comparisons">Comparisons</a></li>
+</ul>
+</li>
+<li><a href="#sc_consistency">Consistency Guarantees</a></li>
+<li><a href="#sc_quorum">Quorums</a></li>
+<li><a href="#sc_logging">Logging</a>
+<ul>
+<li><a href="#sc_developerGuidelines">Developer Guidelines</a>
+<ul>
+<li><a href="#sc_rightLevel">Logging at the Right Level</a></li>
+<li><a href="#sc_slf4jIdioms">Use of Standard slf4j Idioms</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<p><a name="ch_Introduction"></a></p>
+<h2>Introduction</h2>
+<p>This document contains information on the inner workings of ZooKeeper. It 
discusses the following topics:</p>
+<ul>
+<li><a href="#sc_atomicBroadcast">Atomic Broadcast</a></li>
+<li><a href="#sc_consistency">Consistency Guarantees</a></li>
+<li><a href="#sc_quorum">Quorums</a></li>
+<li><a href="#sc_logging">Logging</a></li>
+</ul>
+<p><a name="sc_atomicBroadcast"></a></p>
+<h2>Atomic Broadcast</h2>
+<p>At the heart of ZooKeeper is an atomic messaging system that keeps all of 
the servers in sync.</p>
+<p><a name="sc_guaranteesPropertiesDefinitions"></a></p>
+<h3>Guarantees, Properties, and Definitions</h3>
+<p>The specific guarantees provided by the messaging system used by ZooKeeper 
are the following:</p>
+<ul>
+<li>
+<p><em><em>Reliable delivery</em></em> : If a message <code>m</code>, is 
delivered by one server, message <code>m</code> will be eventually delivered by 
all servers.</p>
+</li>
+<li>
+<p><em><em>Total order</em></em> : If a message <code>a</code> is delivered 
before message <code>b</code> by one server, message <code>a</code> will be 
delivered before <code>b</code> by all servers.</p>
+</li>
+<li>
+<p><em><em>Causal order</em></em> : If a message <code>b</code> is sent after 
a message <code>a</code> has been delivered by the sender of <code>b</code>, 
message <code>a</code> must be ordered before <code>b</code>. If a sender sends 
<code>c</code> after sending <code>b</code>, <code>c</code> must be ordered 
after <code>b</code>.</p>
+</li>
+</ul>
+<p>The ZooKeeper messaging system also needs to be efficient, reliable, and 
easy to implement and maintain. We make heavy use of messaging, so we need the 
system to be able to handle thousands of requests per second. Although we can 
require at least k+1 correct servers to send new messages, we must be able to 
recover from correlated failures such as power outages. When we implemented the 
system we had little time and few engineering resources, so we needed a 
protocol that is accessible to engineers and is easy to implement. We found 
that our protocol satisfied all of these goals.</p>
+<p>Our protocol assumes that we can construct point-to-point FIFO channels 
between the servers. While similar services usually assume message delivery 
that can lose or reorder messages, our assumption of FIFO channels is very 
practical given that we use TCP for communication. Specifically we rely on the 
following property of TCP:</p>
+<ul>
+<li>
+<p><em><em>Ordered delivery</em></em> : Data is delivered in the same order it 
is sent and a message <code>m</code> is delivered only after all messages sent 
before <code>m</code> have been delivered. (The corollary to this is that if 
message <code>m</code> is lost all messages after <code>m</code> will be 
lost.)</p>
+</li>
+<li>
+<p><em><em>No message after close</em></em> : Once a FIFO channel is closed, 
no messages will be received from it.</p>
+</li>
+</ul>
+<p>FLP proved that consensus cannot be achieved in asynchronous distributed 
systems if failures are possible. To ensure that we achieve consensus in the 
presence of failures we use timeouts. However, we rely on time for liveness not 
for correctness. So, if timeouts stop working (e.g., skewed clocks) the 
messaging system may hang, but it will not violate its guarantees.</p>
+<p>When describing the ZooKeeper messaging protocol we will talk of packets, 
proposals, and messages:</p>
+<ul>
+<li>
+<p><em><em>Packet</em></em> : a sequence of bytes sent through a FIFO 
channel.</p>
+</li>
+<li>
+<p><em><em>Proposal</em></em> : a unit of agreement. Proposals are agreed upon 
by exchanging packets with a quorum of ZooKeeper servers. Most proposals 
contain messages, however the NEW_LEADER proposal is an example of a proposal 
that does not contain to a message.</p>
+</li>
+<li>
+<p><em><em>Message</em></em> : a sequence of bytes to be atomically broadcast 
to all ZooKeeper servers. A message put into a proposal and agreed upon before 
it is delivered.</p>
+</li>
+</ul>
+<p>As stated above, ZooKeeper guarantees a total order of messages, and it 
also guarantees a total order of proposals. ZooKeeper exposes the total 
ordering using a ZooKeeper transaction id (<em>zxid</em>). All proposals will 
be stamped with a zxid when it is proposed and exactly reflects the total 
ordering. Proposals are sent to all ZooKeeper servers and committed when a 
quorum of them acknowledge the proposal. If a proposal contains a message, the 
message will be delivered when the proposal is committed. Acknowledgement means 
the server has recorded the proposal to persistent storage. Our quorums have 
the requirement that any pair of quorum must have at least one server in 
common. We ensure this by requiring that all quorums have size (<em>n/2+1</em>) 
where n is the number of servers that make up a ZooKeeper service.</p>
+<p>The zxid has two parts: the epoch and a counter. In our implementation the 
zxid is a 64-bit number. We use the high order 32-bits for the epoch and the 
low order 32-bits for the counter. Because zxid consists of two parts, zxid can 
be represented both as a number and as a pair of integers, (<em>epoch, 
count</em>). The epoch number represents a change in leadership. Each time a 
new leader comes into power it will have its own epoch number. We have a simple 
algorithm to assign a unique zxid to a proposal: the leader simply increments 
the zxid to obtain a unique zxid for each proposal. <em>Leadership activation 
will ensure that only one leader uses a given epoch, so our simple algorithm 
guarantees that every proposal will have a unique id.</em></p>
+<p>ZooKeeper messaging consists of two phases:</p>
+<ul>
+<li>
+<p><em><em>Leader activation</em></em> : In this phase a leader establishes 
the correct state of the system and gets ready to start making proposals.</p>
+</li>
+<li>
+<p><em><em>Active messaging</em></em> : In this phase a leader accepts 
messages to propose and coordinates message delivery.</p>
+</li>
+</ul>
+<p>ZooKeeper is a holistic protocol. We do not focus on individual proposals, 
rather look at the stream of proposals as a whole. Our strict ordering allows 
us to do this efficiently and greatly simplifies our protocol. Leadership 
activation embodies this holistic concept. A leader becomes active only when a 
quorum of followers (The leader counts as a follower as well. You can always 
vote for yourself ) has synced up with the leader, they have the same state. 
This state consists of all of the proposals that the leader believes have been 
committed and the proposal to follow the leader, the NEW_LEADER proposal. 
(Hopefully you are thinking to yourself, <em>Does the set of proposals that the 
leader believes has been committed include all the proposals that really have 
been committed?</em> The answer is <em>yes</em>. Below, we make clear why.)</p>
+<p><a name="sc_leaderElection"></a></p>
+<h3>Leader Activation</h3>
+<p>Leader activation includes leader election 
(<code>FastLeaderElection</code>). ZooKeeper messaging doesn't care about the 
exact method of electing a leader as long as the following holds:</p>
+<ul>
+<li>The leader has seen the highest zxid of all the followers.</li>
+<li>A quorum of servers have committed to following the leader.</li>
+</ul>
+<p>Of these two requirements only the first, the highest zxid among the 
followers needs to hold for correct operation. The second requirement, a quorum 
of followers, just needs to hold with high probability. We are going to recheck 
the second requirement, so if a failure happens during or after the leader 
election and quorum is lost, we will recover by abandoning leader activation 
and running another election.</p>
+<p>After leader election a single server will be designated as a leader and 
start waiting for followers to connect. The rest of the servers will try to 
connect to the leader. The leader will sync up with the followers by sending 
any proposals they are missing, or if a follower is missing too many proposals, 
it will send a full snapshot of the state to the follower.</p>
+<p>There is a corner case in which a follower that has proposals, 
<code>U</code>, not seen by a leader arrives. Proposals are seen in order, so 
the proposals of <code>U</code> will have a zxids higher than zxids seen by the 
leader. The follower must have arrived after the leader election, otherwise the 
follower would have been elected leader given that it has seen a higher zxid. 
Since committed proposals must be seen by a quorum of servers, and a quorum of 
servers that elected the leader did not see <code>U</code>, the proposals of 
<code>U</code> have not been committed, so they can be discarded. When the 
follower connects to the leader, the leader will tell the follower to discard 
<code>U</code>.</p>
+<p>A new leader establishes a zxid to start using for new proposals by getting 
the epoch, e, of the highest zxid it has seen and setting the next zxid to use 
to be (e+1, 0), after the leader syncs with a follower, it will propose a 
NEW_LEADER proposal. Once the NEW_LEADER proposal has been committed, the 
leader will activate and start receiving and issuing proposals.</p>
+<p>It all sounds complicated but here are the basic rules of operation during 
leader activation:</p>
+<ul>
+<li>A follower will ACK the NEW_LEADER proposal after it has synced with the 
leader.</li>
+<li>A follower will only ACK a NEW_LEADER proposal with a given zxid from a 
single server.</li>
+<li>A new leader will COMMIT the NEW_LEADER proposal when a quorum of 
followers has ACKed it.</li>
+<li>A follower will commit any state it received from the leader when the 
NEW_LEADER proposal is COMMIT.</li>
+<li>A new leader will not accept new proposals until the NEW_LEADER proposal 
has been COMMITTED.</li>
+</ul>
+<p>If leader election terminates erroneously, we don't have a problem since 
the NEW_LEADER proposal will not be committed since the leader will not have 
quorum. When this happens, the leader and any remaining followers will timeout 
and go back to leader election.</p>
+<p><a name="sc_activeMessaging"></a></p>
+<h3>Active Messaging</h3>
+<p>Leader Activation does all the heavy lifting. Once the leader is coronated 
he can start blasting out proposals. As long as he remains the leader no other 
leader can emerge since no other leader will be able to get a quorum of 
followers. If a new leader does emerge, it means that the leader has lost 
quorum, and the new leader will clean up any mess left over during her 
leadership activation.</p>
+<p>ZooKeeper messaging operates similar to a classic two-phase commit.</p>
+<p><img src="images/2pc.jpg" alt="Two phase commit" /></p>
+<p>All communication channels are FIFO, so everything is done in order. 
Specifically the following operating constraints are observed:</p>
+<ul>
+<li>The leader sends proposals to all followers using the same order. 
Moreover, this order follows the order in which requests have been received. 
Because we use FIFO channels this means that followers also receive proposals 
in order.</li>
+<li>Followers process messages in the order they are received. This means that 
messages will be ACKed in order and the leader will receive ACKs from followers 
in order, due to the FIFO channels. It also means that if message 
<code>m</code> has been written to non-volatile storage, all messages that were 
proposed before <code>m</code> have been written to non-volatile storage.</li>
+<li>The leader will issue a COMMIT to all followers as soon as a quorum of 
followers have ACKed a message. Since messages are ACKed in order, COMMITs will 
be sent by the leader as received by the followers in order.</li>
+<li>COMMITs are processed in order. Followers deliver a proposal message when 
that proposal is committed.</li>
+</ul>
+<p><a name="sc_summary"></a></p>
+<h3>Summary</h3>
+<p>So there you go. Why does it work? Specifically, why does a set of 
proposals believed by a new leader always contain any proposal that has 
actually been committed? First, all proposals have a unique zxid, so unlike 
other protocols, we never have to worry about two different values being 
proposed for the same zxid; followers (a leader is also a follower) see and 
record proposals in order; proposals are committed in order; there is only one 
active leader at a time since followers only follow a single leader at a time; 
a new leader has seen all committed proposals from the previous epoch since it 
has seen the highest zxid from a quorum of servers; any uncommitted proposals 
from a previous epoch seen by a new leader will be committed by that leader 
before it becomes active.</p>
+<p><a name="sc_comparisons"></a></p>
+<h3>Comparisons</h3>
+<p>Isn't this just Multi-Paxos? No, Multi-Paxos requires some way of assuring 
that there is only a single coordinator. We do not count on such assurances. 
Instead we use the leader activation to recover from leadership change or old 
leaders believing they are still active.</p>
+<p>Isn't this just Paxos? Your active messaging phase looks just like phase 2 
of Paxos? Actually, to us active messaging looks just like 2 phase commit 
without the need to handle aborts. Active messaging is different from both in 
the sense that it has cross proposal ordering requirements. If we do not 
maintain strict FIFO ordering of all packets, it all falls apart. Also, our 
leader activation phase is different from both of them. In particular, our use 
of epochs allows us to skip blocks of uncommitted proposals and to not worry 
about duplicate proposals for a given zxid.</p>
+<p><a name="sc_consistency"></a></p>
+<h2>Consistency Guarantees</h2>
+<p>The <a href="https://jepsen.io/consistency";>consistency</a> guarantees of 
ZooKeeper lie between sequential consistency and linearizability. In this 
section, we explain the exact consistency guarantees that ZooKeeper 
provides.</p>
+<p>Write operations in ZooKeeper are <em>linearizable</em>. In other words, 
each <code>write</code> will appear to take effect atomically at some point 
between when the client issues the request and receives the corresponding 
response. This means that the writes performed by all the clients in ZooKeeper 
can be totally ordered in such a way that respects the real-time ordering of 
these writes. However, merely stating that write operations are linearizable is 
meaningless unless we also talk about read operations.</p>
+<p>Read operations in ZooKeeper are <em>not linearizable</em> since they can 
return potentially stale data. This is because a <code>read</code> in ZooKeeper 
is not a quorum operation and a server will respond immediately to a client 
that is performing a <code>read</code>. ZooKeeper does this because it 
prioritizes performance over consistency for the read use case. However, reads 
in ZooKeeper are <em>sequentially consistent</em>, because <code>read</code> 
operations will appear to take effect in some sequential order that furthermore 
respects the order of each client's operations. A common pattern to work around 
this is to issue a <code>sync</code> before issuing a <code>read</code>. This 
too does <strong>not</strong> strictly guarantee up-to-date data because 
<code>sync</code> is <a 
href="https://issues.apache.org/jira/browse/ZOOKEEPER-1675";>not currently a 
quorum operation</a>. To illustrate, consider a scenario where two servers 
simultaneously think they are the leader, something
  that could occur if the TCP connection timeout is smaller than 
<code>syncLimit * tickTime</code>. Note that this is <a 
href="https://www.amazon.com/ZooKeeper-Distributed-Coordination-Flavio-Junqueira/dp/1449361307";>unlikely</a>
 to occur in practice, but should be kept in mind nevertheless when discussing 
strict theoretical guarantees. Under this scenario, it is possible that the 
<code>sync</code> is served by the “leader” with stale data, thereby 
allowing the following <code>read</code> to be stale as well. The stronger 
guarantee of linearizability is provided if an actual quorum operation (e.g., a 
<code>write</code>) is performed before a <code>read</code>.</p>
+<p>Overall, the consistency guarantees of ZooKeeper are formally captured by 
the notion of <a 
href="http://webee.technion.ac.il/people/idish/ftp/OSC-IPL17.pdf";>ordered 
sequential consistency</a> or <code>OSC(U)</code> to be exact, which lies 
between sequential consistency and linearizability.</p>
+<p><a name="sc_quorum"></a></p>
+<h2>Quorums</h2>
+<p>Atomic broadcast and leader election use the notion of quorum to guarantee 
a consistent view of the system. By default, ZooKeeper uses majority quorums, 
which means that every voting that happens in one of these protocols requires a 
majority to vote on. One example is acknowledging a leader proposal: the leader 
can only commit once it receives an acknowledgement from a quorum of 
servers.</p>
+<p>If we extract the properties that we really need from our use of 
majorities, we have that we only need to guarantee that groups of processes 
used to validate an operation by voting (e.g., acknowledging a leader proposal) 
pairwise intersect in at least one server. Using majorities guarantees such a 
property. However, there are other ways of constructing quorums different from 
majorities. For example, we can assign weights to the votes of servers, and say 
that the votes of some servers are more important. To obtain a quorum, we get 
enough votes so that the sum of weights of all votes is larger than half of the 
total sum of all weights.</p>
+<p>A different construction that uses weights and is useful in wide-area 
deployments (co-locations) is a hierarchical one. With this construction, we 
split the servers into disjoint groups and assign weights to processes. To form 
a quorum, we have to get a hold of enough servers from a majority of groups G, 
such that for each group g in G, the sum of votes from g is larger than half of 
the sum of weights in g. Interestingly, this construction enables smaller 
quorums. If we have, for example, 9 servers, we split them into 3 groups, and 
assign a weight of 1 to each server, then we are able to form quorums of size 
4. Note that two subsets of processes composed each of a majority of servers 
from each of a majority of groups necessarily have a non-empty intersection. It 
is reasonable to expect that a majority of co-locations will have a majority of 
servers available with high probability.</p>
+<p>With ZooKeeper, we provide a user with the ability of configuring servers 
to use majority quorums, weights, or a hierarchy of groups.</p>
+<p><a name="sc_logging"></a></p>
+<h2>Logging</h2>
+<p>Zookeeper uses <a href="http://www.slf4j.org/index.html";>slf4j</a> as an 
abstraction layer for logging. <a 
href="http://logging.apache.org/log4j";>log4j</a> in version 1.2 is chosen as 
the final logging implementation for now. For better embedding support, it is 
planned in the future to leave the decision of choosing the final logging 
implementation to the end user. Therefore, always use the slf4j api to write 
log statements in the code, but configure log4j for how to log at runtime. Note 
that slf4j has no FATAL level, former messages at FATAL level have been moved 
to ERROR level. For information on configuring log4j for ZooKeeper, see the <a 
href="zookeeperAdmin.html#sc_logging">Logging</a> section of the <a 
href="zookeeperAdmin.html">ZooKeeper Administrator's Guide.</a></p>
+<p><a name="sc_developerGuidelines"></a></p>
+<h3>Developer Guidelines</h3>
+<p>Please follow the  <a href="http://www.slf4j.org/manual.html";>slf4j 
manual</a> when creating log statements within code. Also read the <a 
href="http://www.slf4j.org/faq.html#logging_performance";>FAQ on 
performance</a>, when creating log statements. Patch reviewers will look for 
the following:</p>
+<p><a name="sc_rightLevel"></a></p>
+<h4>Logging at the Right Level</h4>
+<p>There are several levels of logging in slf4j.</p>
+<p>It's important to pick the right one. In order of higher to lower 
severity:</p>
+<ol>
+<li>ERROR level designates error events that might still allow the application 
to continue running.</li>
+<li>WARN level designates potentially harmful situations.</li>
+<li>INFO level designates informational messages that highlight the progress 
of the application at coarse-grained level.</li>
+<li>DEBUG Level designates fine-grained informational events that are most 
useful to debug an application.</li>
+<li>TRACE Level designates finer-grained informational events than the 
DEBUG.</li>
+</ol>
+<p>ZooKeeper is typically run in production such that log messages of INFO 
level severity and higher (more severe) are output to the log.</p>
+<p><a name="sc_slf4jIdioms"></a></p>
+<h4>Use of Standard slf4j Idioms</h4>
+<p><em>Static Message Logging</em></p>
+<pre><code>LOG.debug(&quot;process completed successfully!&quot;);
+</code></pre>
+<p>However when creating parameterized messages are required, use formatting 
anchors.</p>
+<pre><code>LOG.debug(&quot;got {} messages in {} minutes&quot;,new 
Object[]{count,time});
+</code></pre>
+<p><em>Naming</em></p>
+<p>Loggers should be named after the class in which they are used.</p>
+<pre><code>public class Foo {
+    private static final Logger LOG = LoggerFactory.getLogger(Foo.class);
+    ....
+    public Foo() {
+        LOG.info(&quot;constructing Foo&quot;);
+</code></pre>
+<p><em>Exception handling</em></p>
+<pre><code>try {
+    // code
+} catch (XYZException e) {
+    // do this
+    LOG.error(&quot;Something bad happened&quot;, e);
+    // don't do this (generally)
+    // LOG.error(e);
+    // why? because &quot;don't do&quot; case hides the stack trace
+
+    // continue process here as you need... recover or (re)throw
+}
+</code></pre>
+</div>
+<div class="clearboth">&nbsp;</div>
+</div>
+<div id="footer">
+    <div class="lastmodified">
+        <script type="text/javascript">
+        <!--
+            document.write("Last Published: " + document.lastModified);
+        //  -->
+        </script>
+    </div>
+    <div class="copyright">
+        Copyright &copy; <a href="http://www.apache.org/licenses/";>The Apache 
Software Foundation.</a>
+    </div>
+    <div id="logos"></div>
+</div>
+</body>
+</html>
\ No newline at end of file


Reply via email to