You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by ar...@apache.org on 2022/04/25 01:07:46 UTC

svn commit: r54054 [6/11] - in /dev/zookeeper/zookeeper-3.7.1-rc0: ./ website/ website/images/ website/skin/

Added: dev/zookeeper/zookeeper-3.7.1-rc0/website/zookeeperAuditLogs.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc0/website/zookeeperAuditLogs.html (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc0/website/zookeeperAuditLogs.html Mon Apr 25 01:07:46 2022
@@ -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 zkcli@HADOOP.COM, server principal is zookeeper/192.168.1.3@HADOOP.COM</p>
+<pre><code>user=zookeeper/192.168.1.3 operation=serverStart   result=success
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=create    znode=/a    znode_type=persistent  result=success
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=create    znode=/a    znode_type=persistent  result=failure
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=setData   znode=/a    result=failure
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=setData   znode=/a    result=success
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=setAcl    znode=/a    acl=world:anyone:cdrwa  result=failure
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=setAcl    znode=/a    acl=world:anyone:cdrwa  result=success
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=create    znode=/b    znode_type=persistent  result=success
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=setData   znode=/b    result=success
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=delete    znode=/b    result=success
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=multiOperation    result=failure
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=delete    znode=/a    result=failure
+session=0x19344730000   user=192.168.1.2,zkcli@HADOOP.COM  ip=192.168.1.2    operation=delete    znode=/a    result=success
+session=0x19344730001   user=192.168.1.2,zkcli@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,zkcli@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.com@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.com@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 zkcli@HADOOP.COM and ip 127.0.0.1 then create znode audit log will be as:</p>
+<pre><code>session=0x10c0bcb0000 user=zkcli@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.1-rc0/website/zookeeperCLI.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc0/website/zookeeperCLI.html (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc0/website/zookeeperCLI.html Mon Apr 25 01:07:46 2022
@@ -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.1-rc0/website/zookeeperHierarchicalQuorums.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc0/website/zookeeperHierarchicalQuorums.html (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc0/website/zookeeperHierarchicalQuorums.html Mon Apr 25 01:07:46 2022
@@ -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.1-rc0/website/zookeeperInternals.html
==============================================================================
--- dev/zookeeper/zookeeper-3.7.1-rc0/website/zookeeperInternals.html (added)
+++ dev/zookeeper/zookeeper-3.7.1-rc0/website/zookeeperInternals.html Mon Apr 25 01:07:46 2022
@@ -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