浏览代码

ZOOKEEPER-1703: Added instructions on how to run the example code

Author: Andor Molnar <andor@cloudera.com>

Reviewers: Patrick Hunt <phunt@apache.org>

Closes #400 from dolphy17/master and squashes the following commits:

16e26f92 [Andor Molnar] ZOOKEEPER-1703: Set classpath the way that the book suggests
45ff9816 [Andor Molnar] ZOOKEEPER-1703: Added instructions on how to run the example code

Change-Id: I08467785ae3cdd75fd38c1e6d82439e4718d83fe
Andor Molnar 7 年之前
父节点
当前提交
98ff4f9dd9

二进制
docs/index.pdf


二进制
docs/javaExample.pdf


二进制
docs/linkmap.pdf


二进制
docs/recipes.pdf


+ 53 - 19
docs/zookeeperAdmin.html

@@ -852,7 +852,7 @@ server.3=zoo3:2888:3888</pre>
 </ul>
 <a name="sc_designing"></a>
 <h3 class="h4">Designing a ZooKeeper Deployment</h3>
-<p>The reliablity of ZooKeeper rests on two basic assumptions.</p>
+<p>The reliability of ZooKeeper rests on two basic assumptions.</p>
 <ol>
         
 <li>
@@ -958,7 +958,7 @@ server.3=zoo3:2888:3888</pre>
           made to the znodes these changes are appended to a
           transaction log, occasionally, when a log grows large, a
           snapshot of the current state of all znodes will be written
-          to the filesystem. This snapshot supercedes all previous
+          to the filesystem. This snapshot supersedes all previous
           logs.
         </p>
 <p>A ZooKeeper server <strong>will not remove
@@ -1167,13 +1167,13 @@ server.3=zoo3:2888:3888</pre>
 <p>This option will direct the machine to write the
               transaction log to the <strong>dataLogDir</strong> rather than the <strong>dataDir</strong>. This allows a dedicated log
               device to be used, and helps avoid competition between logging
-              and snaphots.</p>
+              and snapshots.</p>
 <div class="note">
 <div class="label">Note</div>
 <div class="content">
                 
 <p>Having a dedicated log device has a large impact on
-                throughput and stable latencies. It is highly recommened to
+                throughput and stable latencies. It is highly recommended to
                 dedicate a log device and set <strong>dataLogDir</strong> to point to a directory on
                 that device, and then make sure to point <strong>dataDir</strong> to a directory
                 <em>not</em> residing on that device.</p>
@@ -1215,11 +1215,15 @@ server.3=zoo3:2888:3888</pre>
 </dt>
 <dd>
 <p>(Java system property: <strong>zookeeper.snapCount</strong>)</p>
-<p>ZooKeeper logs transactions to a transaction
-              log. After snapCount transactions are written to a log
-              file a snapshot is started and a new transaction log
-              file is created. The default snapCount is
-              100,000.</p>
+<p>ZooKeeper records its transactions using snapshots and
+              a transaction log (think write-ahead log).The number of
+              transactions recorded in the transaction log before a snapshot
+              can be taken (and the transaction log rolled) is determined
+              by snapCount. In order to prevent all of the machines in the quorum
+              from taking a snapshot at the same time, each ZooKeeper server
+              will take a snapshot when the number of transactions in the transaction log
+              reaches a runtime generated random value in the [snapCount/2+1, snapCount] 
+              range.The default snapCount is 100,000.</p>
 </dd>
 
           
@@ -1347,17 +1351,16 @@ server.3=zoo3:2888:3888</pre>
 </dt>
 <dd>
 <p>(No Java system property)</p>
-<p>Election implementation to use. A value of "0" corresponds
-              to the original UDP-based version, "1" corresponds to the
+<p>Election implementation to use. A value of "1" corresponds to the
               non-authenticated UDP-based version of fast leader election, "2"
               corresponds to the authenticated UDP-based version of fast
               leader election, and "3" corresponds to TCP-based version of
-              fast leader election. Currently, algorithm 3 is the default</p>
+              fast leader election. Currently, algorithm 3 is the default.</p>
 <div class="note">
 <div class="label">Note</div>
 <div class="content">
               
-<p> The implementations of leader election 0, 1, and 2 are now 
+<p> The implementations of leader election 1, and 2 are now
               <strong> deprecated </strong>. We have the intention
               of removing them in the next release, at which point only the 
               FastLeaderElection will be available. 
@@ -1386,7 +1389,7 @@ server.3=zoo3:2888:3888</pre>
 <p>(Java system property: zookeeper.<strong>leaderServes</strong>)</p>
 <p>Leader accepts client connections. Default value is "yes".
               The leader machine coordinates updates. For higher update
-              throughput at thes slight expense of read throughput the leader
+              throughput at the slight expense of read throughput the leader
               can be configured to not accept clients and focus on
               coordination. The default to this option is yes, which means
               that a leader will accept client connections.</p>
@@ -1418,9 +1421,7 @@ server.3=zoo3:2888:3888</pre>
               that each ZooKeeper server has.</p>
 <p>There are two port numbers <strong>nnnnn</strong>. 
               The first followers use to connect to the leader, and the second is for 
-              leader election. The leader election port is only necessary if electionAlg 
-              is 1, 2, or 3 (default). If electionAlg is 0, then the second port is not 
-              necessary. If you want to test multiple servers on a single machine, then 
+              leader election. If you want to test multiple servers on a single machine, then
               different ports can be used for each server.</p>
 </dd>
 
@@ -1571,6 +1572,27 @@ server.3=zoo3:2888:3888</pre>
               </pre>
 </dd>
 
+          
+<dt>
+<term>tcpKeepAlive</term>
+</dt>
+<dd>
+<p>(Java system property: <strong>zookeeper.tcpKeepAlive</strong>)</p>
+<p>
+<strong>New in 3.5.4:</strong>
+                Setting this to true sets the TCP keepAlive flag on the
+                sockets used by quorum members to perform elections.
+                This will allow for connections between quorum members to
+                remain up when there is network infrastructure that may
+                otherwise break them. Some NATs and firewalls may terminate
+                or lose state for long running or idle connections.</p>
+<p> Enabling this option relies on OS level settings to work
+                properly, check your operating system's options regarding TCP
+                keepalive for more information.  Defaults to
+                <strong>false</strong>.
+              </p>
+</dd>
+
         
 </dl>
 <p></p>
@@ -1621,6 +1643,18 @@ server.3=zoo3:2888:3888</pre>
 </dd>
 
           
+<dt>
+<term>zookeeper.superUser</term>
+</dt>
+<dd>
+<p>(Java system property: <strong>zookeeper.superUser</strong>)</p>
+<p>Similar to <strong>zookeeper.X509AuthenticationProvider.superUser</strong>
+              but is generic for SASL based logins. It stores the name of 
+              a user that can access the znode hierarchy as a "super" user.
+              </p>
+</dd>
+
+          
 <dt>
 <term>ssl.keyStore.location and ssl.keyStore.password</term>
 </dt>
@@ -2489,7 +2523,7 @@ server.3=zoo3:2888:3888</pre>
 
         
 <dt>
-<term>incorrect placement of transasction log</term>
+<term>incorrect placement of transaction log</term>
 </dt>
 <dd>
 <p>The most performance critical part of ZooKeeper is the
@@ -2537,7 +2571,7 @@ server.3=zoo3:2888:3888</pre>
 <h3 class="h4">Best Practices</h3>
 <p>For best results, take note of the following list of good
       Zookeeper practices:</p>
-<p>For multi-tennant installations see the <a href="zookeeperProgrammers.html#ch_zkSessions">section</a>
+<p>For multi-tenant installations see the <a href="zookeeperProgrammers.html#ch_zkSessions">section</a>
       detailing ZooKeeper "chroot" support, this can be very useful
       when deploying many applications/services interfacing to a
       single ZooKeeper cluster.</p>

二进制
docs/zookeeperAdmin.pdf


二进制
docs/zookeeperHierarchicalQuorums.pdf


二进制
docs/zookeeperInternals.pdf


二进制
docs/zookeeperJMX.pdf


二进制
docs/zookeeperObservers.pdf


二进制
docs/zookeeperOver.pdf


+ 114 - 1
docs/zookeeperProgrammers.html

@@ -2358,7 +2358,120 @@ public abstract class ServerAuthenticationProvider implements AuthenticationProv
 <p>Both the Java and C client bindings may report errors. The Java client binding does so by throwing KeeperException, calling code() on the exception will return the specific error code. The C client binding returns an error code as defined in the enum ZOO_ERRORS. API callbacks indicate result code for both language bindings. See the API documentation (javadoc for Java, doxygen for C) for full details on the possible errors and their meaning.</p>
 <a name="sc_connectingToZk"></a>
 <h3 class="h4">Connecting to ZooKeeper</h3>
-<p></p>
+<p>Before we begin, you will have to set up a running Zookeeper server so that we can start developing the client. For C client bindings, we will be using the multithreaded library(zookeeper_mt) with a simple example written in C. To establish a connection with Zookeeper server, we make use of C API - <em>zookeeper_init</em> with the following signature:</p>
+<pre class="code">
+<em>int</em> <em>zookeeper_init</em>(<em>const</em> <em>char</em> *host, watcher_fn fn, <em>int</em> recv_timeout, <em>const</em> clientid_t *clientid, <em>void</em> *context, <em>int</em> flags);</pre>
+<dl>
+        
+<dt>
+<term>*host</term>
+</dt>
+<dd>
+<p>Connection string to zookeeper server in the format of host:port. If there are multiple servers, use comma as separator after specifying the host:port pairs. Eg: "127.0.0.1:2181,127.0.0.1:3001,127.0.0.1:3002"</p>
+</dd>
+
+        
+<dt>
+<term>fn</term>
+</dt>
+<dd>
+<p>Watcher function to process events when a notification is triggered.</p>
+</dd>
+
+        
+<dt>
+<term>recv_timeout</term>
+</dt>
+<dd>
+<p>Session expiration time in milliseconds.</p>
+</dd>
+
+        
+<dt>
+<term>*clientid</term>
+</dt>
+<dd>
+<p>We can specify 0 for a new session. If a session has already establish previously, we could provide that client ID and it would reconnect to that previous session.</p>
+</dd>
+
+        
+<dt>
+<term>*context</term>
+</dt>
+<dd>
+<p>Context object that can be associated with the zkhandle_t handler. If it is not used, we can set it to 0.</p>
+</dd>
+
+        
+<dt>
+<term>flags</term>
+</dt>
+<dd>
+<p>In an initiation, we can leave it for 0.</p>
+</dd>
+      
+</dl>
+<p>We will demonstrate client that outputs "Connected to Zookeeper" after successful connection or an error message otherwise. Let's call the following code <em>zkClient.cc</em> :</p>
+<pre class="code">
+#include &lt;stdio.h&gt;
+#include &lt;zookeeper/zookeeper.h&gt;
+#include &lt;errno.h&gt;
+using namespace std;
+
+// Keeping track of the connection state
+static int connected = 0;
+static int expired   = 0;
+
+// *zkHandler handles the connection with Zookeeper
+static zhandle_t *zkHandler;
+
+// watcher function would process events
+void watcher(zhandle_t *zkH, int type, int state, const char *path, void *watcherCtx)
+{
+    if (type == ZOO_SESSION_EVENT) {
+
+        // state refers to states of zookeeper connection.
+        // To keep it simple, we would demonstrate these 3: ZOO_EXPIRED_SESSION_STATE, ZOO_CONNECTED_STATE, ZOO_NOTCONNECTED_STATE
+        // If you are using ACL, you should be aware of an authentication failure state - ZOO_AUTH_FAILED_STATE
+        if (state == ZOO_CONNECTED_STATE) {
+            connected = 1;
+        } else if (state == ZOO_NOTCONNECTED_STATE ) {
+            connected = 0;
+        } else if (state == ZOO_EXPIRED_SESSION_STATE) {
+            expired = 1;
+            connected = 0;
+            zookeeper_close(zkH);
+        }
+    }
+}
+
+int main(){
+    zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
+
+    // zookeeper_init returns the handler upon a successful connection, null otherwise
+    zkHandler = zookeeper_init("localhost:2181", watcher, 10000, 0, 0, 0);
+    
+    if (!zkHandler) {
+        return errno;
+    }else{
+        printf("Connection established with Zookeeper. \n");
+    }
+
+    // Close Zookeeper connection
+    zookeeper_close(zkHandler);
+
+    return 0;
+}
+      </pre>
+<p>Compile the code with the multithreaded library mentioned before.</p>
+<p>
+<span class="codefrag command">&gt; g++ -Iinclude/ zkClient.cpp -lzookeeper_mt -o Client</span>
+</p>
+<p>Run the client. </p>
+<p>
+<span class="codefrag command">&gt; ./Client</span>
+</p>
+<p>From the output, you should see "Connected to Zookeeper" along with Zookeeper's DEBUG messages if the connection is successful.</p>
 <a name="sc_readOps"></a>
 <h3 class="h4">Read Operations</h3>
 <p></p>

二进制
docs/zookeeperProgrammers.pdf


二进制
docs/zookeeperQuotas.pdf


二进制
docs/zookeeperReconfig.pdf


二进制
docs/zookeeperStarted.pdf


+ 51 - 8
docs/zookeeperTutorial.html

@@ -204,7 +204,18 @@ document.write("Last Published: " + document.lastModified);
 <a href="#sc_producerConsumerQueues">Producer-Consumer Queues</a>
 </li>
 <li>
-<a href="#sc_sourceListing">Complete Source Listing</a>
+<a href="#Complete+example">Complete example</a>
+<ul class="minitoc">
+<li>
+<a href="#Queue+test">Queue test</a>
+</li>
+<li>
+<a href="#Barrier+test">Barrier test</a>
+</li>
+<li>
+<a href="#sc_sourceListing">Source Listing</a>
+</li>
+</ul>
 </li>
 </ul>
 </div>
@@ -534,9 +545,37 @@ from each one.</p>
 </pre>
 </div>
 
-<a name="sc_sourceListing"></a>
-<h2 class="h3">Complete Source Listing</h2>
+
+<a name="Complete+example"></a>
+<h2 class="h3">Complete example</h2>
 <div class="section">
+<p>
+In the following section you can find a complete command line application to demonstrate the above mentioned
+recipes. Use the following command to run it.
+</p>
+<pre class="code">
+ZOOBINDIR="[path_to_distro]/bin"
+. "$ZOOBINDIR"/zkEnv.sh
+java SyncPrimitive [Test Type] [ZK server] [No of elements] [Client type]
+</pre>
+<a name="Queue+test"></a>
+<h3 class="h4">Queue test</h3>
+<p>Start a producer to create 100 elements</p>
+<pre class="code">
+java SyncPrimitive qTest localhost 100 p
+</pre>
+<p>Start a consumer to consume 100 elements</p>
+<pre class="code">
+java SyncPrimitive qTest localhost 100 c
+</pre>
+<a name="Barrier+test"></a>
+<h3 class="h4">Barrier test</h3>
+<p>Start a barrier with 2 participants (start as many times as many participants you'd like to enter)</p>
+<pre class="code">
+java SyncPrimitive bTest localhost 2
+</pre>
+<a name="sc_sourceListing"></a>
+<h3 class="h4">Source Listing</h3>
 <div class="note example">
 <div class="label">SyncPrimitive.Java</div>
 <div class="content">
@@ -753,15 +792,19 @@ public class SyncPrimitive implements Watcher {
                         mutex.wait();
                     } else {
                         Integer min = new Integer(list.get(0).substring(7));
+                        String minNode = list.get(0);
                         for(String s : list){
                             Integer tempValue = new Integer(s.substring(7));
                             //System.out.println("Temporary value: " + tempValue);
-                            if(tempValue &lt; min) min = tempValue;
+                            if(tempValue &lt; min) {
+                                min = tempValue;
+                                minNode = s;
+                            }
                         }
-                        System.out.println("Temporary value: " + root + "/element" + min);
-                        byte[] b = zk.getData(root + "/element" + min,
-                                    false, stat);
-                        zk.delete(root + "/element" + min, 0);
+                        System.out.println("Temporary value: " + root + "/" + minNode);
+                        byte[] b = zk.getData(root + "/" + minNode,
+                        false, stat);
+                        zk.delete(root + "/" + minNode, 0);
                         ByteBuffer buffer = ByteBuffer.wrap(b);
                         retvalue = buffer.getInt();
 

二进制
docs/zookeeperTutorial.pdf


+ 45 - 8
src/docs/src/documentation/content/xdocs/zookeeperTutorial.xml

@@ -361,7 +361,41 @@ from each one.</para>
 </programlisting>
  
 </section>
-<section id="sc_sourceListing"><title>Complete Source Listing</title>
+
+<section>
+<title>Complete example</title>
+<para>
+In the following section you can find a complete command line application to demonstrate the above mentioned
+recipes. Use the following command to run it.
+</para>
+<programlisting>
+ZOOBINDIR="[path_to_distro]/bin"
+. "$ZOOBINDIR"/zkEnv.sh
+java SyncPrimitive [Test Type] [ZK server] [No of elements] [Client type]
+</programlisting>
+
+<section>
+<title>Queue test</title>
+<para>Start a producer to create 100 elements</para>
+<programlisting>
+java SyncPrimitive qTest localhost 100 p
+</programlisting>
+
+<para>Start a consumer to consume 100 elements</para>
+<programlisting>
+java SyncPrimitive qTest localhost 100 c
+</programlisting>
+</section>
+
+<section>
+<title>Barrier test</title>
+<para>Start a barrier with 2 participants (start as many times as many participants you'd like to enter)</para>
+<programlisting>
+java SyncPrimitive bTest localhost 2
+</programlisting>
+</section>
+
+<section id="sc_sourceListing"><title>Source Listing</title>
 <example id="eg_SyncPrimitive_java">
 <title>SyncPrimitive.Java</title>
 <programlisting>
@@ -574,15 +608,19 @@ public class SyncPrimitive implements Watcher {
                         mutex.wait();
                     } else {
                         Integer min = new Integer(list.get(0).substring(7));
+                        String minNode = list.get(0);
                         for(String s : list){
                             Integer tempValue = new Integer(s.substring(7));
                             //System.out.println("Temporary value: " + tempValue);
-                            if(tempValue &lt; min) min = tempValue;
+                            if(tempValue &lt; min) {
+                                min = tempValue;
+                                minNode = s;
+                            }
                         }
-                        System.out.println("Temporary value: " + root + "/element" + min);
-                        byte[] b = zk.getData(root + "/element" + min,
-                                    false, stat);
-                        zk.delete(root + "/element" + min, 0);
+                        System.out.println("Temporary value: " + root + "/" + minNode);
+                        byte[] b = zk.getData(root + "/" + minNode,
+                        false, stat);
+                        zk.delete(root + "/" + minNode, 0);
                         ByteBuffer buffer = ByteBuffer.wrap(b);
                         retvalue = buffer.getInt();
 
@@ -669,7 +707,6 @@ public class SyncPrimitive implements Watcher {
 }
 </programlisting></example>
 </section>
+</section>
 
 </article>
-
-