zookeeper-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ph...@apache.org
Subject [17/57] [abbrv] [partial] zookeeper git commit: Add the historical documentation.
Date Fri, 01 Dec 2017 17:58:11 GMT
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/01b6b5e4/doc/r3.1.2/zookeeperStarted.html
----------------------------------------------------------------------
diff --git a/doc/r3.1.2/zookeeperStarted.html b/doc/r3.1.2/zookeeperStarted.html
new file mode 100644
index 0000000..c6eb324
--- /dev/null
+++ b/doc/r3.1.2/zookeeperStarted.html
@@ -0,0 +1,502 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta content="Apache Forrest" name="Generator">
+<meta name="Forrest-version" content="0.8">
+<meta name="Forrest-skin-name" content="pelt">
+<title>ZooKeeper Getting Started Guide</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/fontsize.js" language="javascript" type="text/javascript"></script>
+<link rel="shortcut icon" href="images/favicon.ico">
+</head>
+<body onload="init()">
+<script type="text/javascript">ndeSetTextSize();</script>
+<div id="top">
+<!--+
+    |breadtrail
+    +-->
+<div class="breadtrail">
+<a href="http://www.apache.org/">Apache</a> &gt; <a href="http://hadoop.apache.org/">Hadoop</a> &gt; <a href="http://hadoop.apache.org/zookeeper/">ZooKeeper</a><script src="skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
+</div>
+<!--+
+    |header
+    +-->
+<div class="header">
+<!--+
+    |start group logo
+    +-->
+<div class="grouplogo">
+<a href="http://hadoop.apache.org/"><img class="logoImage" alt="Hadoop" src="images/hadoop-logo.jpg" title="Apache Hadoop"></a>
+</div>
+<!--+
+    |end group logo
+    +-->
+<!--+
+    |start Project Logo
+    +-->
+<div class="projectlogo">
+<a href="http://hadoop.apache.org/zookeeper/"><img class="logoImage" alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed coordination"></a>
+</div>
+<!--+
+    |end Project Logo
+    +-->
+<!--+
+    |start Search
+    +-->
+<div class="searchbox">
+<form action="http://www.google.com/search" method="get" class="roundtopsmall">
+<input value="hadoop.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>
+<!--+
+    |end search
+    +-->
+<!--+
+    |start Tabs
+    +-->
+<ul id="tabs">
+<li>
+<a class="unselected" href="http://hadoop.apache.org/zookeeper/">Project</a>
+</li>
+<li>
+<a class="unselected" href="http://wiki.apache.org/hadoop/ZooKeeper">Wiki</a>
+</li>
+<li class="current">
+<a class="selected" href="index.html">ZooKeeper 3.1 Documentation</a>
+</li>
+</ul>
+<!--+
+    |end Tabs
+    +-->
+</div>
+</div>
+<div id="main">
+<div id="publishedStrip">
+<!--+
+    |start Subtabs
+    +-->
+<div id="level2tabs"></div>
+<!--+
+    |end Endtabs
+    +-->
+<script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+</div>
+<!--+
+    |breadtrail
+    +-->
+<div class="breadtrail">
+
+             &nbsp;
+           </div>
+<!--+
+    |start Menu, mainarea
+    +-->
+<!--+
+    |start Menu
+    +-->
+<div id="menu">
+<div onclick="SwitchMenu('menu_selected_1.1', 'skin/')" id="menu_selected_1.1Title" class="menutitle" style="background-image: url('skin/images/chapter_open.gif');">Overview</div>
+<div id="menu_selected_1.1" class="selectedmenuitemgroup" style="display: block;">
+<div class="menuitem">
+<a href="index.html">Welcome</a>
+</div>
+<div class="menuitem">
+<a href="zookeeperOver.html">Overview</a>
+</div>
+<div class="menupage">
+<div class="menupagetitle">Getting Started</div>
+</div>
+<div class="menuitem">
+<a href="releasenotes.html">Release Notes</a>
+</div>
+</div>
+<div onclick="SwitchMenu('menu_1.2', 'skin/')" id="menu_1.2Title" class="menutitle">Developer</div>
+<div id="menu_1.2" class="menuitemgroup">
+<div class="menuitem">
+<a href="api/index.html">API Docs</a>
+</div>
+<div class="menuitem">
+<a href="zookeeperProgrammers.html">Programmer's Guide</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_1.3', 'skin/')" id="menu_1.3Title" class="menutitle">Admin &amp; Ops</div>
+<div id="menu_1.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>
+<div onclick="SwitchMenu('menu_1.4', 'skin/')" id="menu_1.4Title" class="menutitle">Contributor</div>
+<div id="menu_1.4" class="menuitemgroup">
+<div class="menuitem">
+<a href="zookeeperInternals.html">ZooKeeper Internals</a>
+</div>
+</div>
+<div onclick="SwitchMenu('menu_1.5', 'skin/')" id="menu_1.5Title" class="menutitle">Miscellaneous</div>
+<div id="menu_1.5" class="menuitemgroup">
+<div class="menuitem">
+<a href="http://wiki.apache.org/hadoop/ZooKeeper">Wiki</a>
+</div>
+<div class="menuitem">
+<a href="http://wiki.apache.org/hadoop/ZooKeeper/FAQ">FAQ</a>
+</div>
+<div class="menuitem">
+<a href="http://hadoop.apache.org/zookeeper/mailing_lists.html">Mailing Lists</a>
+</div>
+</div>
+<div id="credit"></div>
+<div id="roundbottom">
+<img style="display: none" class="corner" height="15" width="15" alt="" src="skin/images/rc-b-l-15-1body-2menu-3menu.png"></div>
+<!--+
+  |alternative credits
+  +-->
+<div id="credit2"></div>
+</div>
+<!--+
+    |end Menu
+    +-->
+<!--+
+    |start content
+    +-->
+<div id="content">
+<div title="Portable Document Format" class="pdflink">
+<a class="dida" href="zookeeperStarted.pdf"><img alt="PDF -icon" src="skin/images/pdfdoc.gif" class="skin"><br>
+        PDF</a>
+</div>
+<h1>ZooKeeper Getting Started Guide</h1>
+<div id="minitoc-area">
+<ul class="minitoc">
+<li>
+<a href="#ch_GettingStarted">Getting Started: Coordinating Distributed Applications with
+      ZooKeeper</a>
+<ul class="minitoc">
+<li>
+<a href="#sc_Prerequisites">Pre-requisites</a>
+</li>
+<li>
+<a href="#sc_Download">Download</a>
+</li>
+<li>
+<a href="#sc_InstallingSingleMode">Standalone Operation</a>
+</li>
+<li>
+<a href="#sc_FileManagement">Managing ZooKeeper Storage</a>
+</li>
+<li>
+<a href="#sc_ConnectingToZooKeeper">Connecting to ZooKeeper</a>
+</li>
+<li>
+<a href="#sc_ProgrammingToZooKeeper">Programming to ZooKeeper</a>
+</li>
+<li>
+<a href="#sc_RunningReplicatedZooKeeper">Running Replicated ZooKeeper</a>
+</li>
+<li>
+<a href="#Other+Optimizations">Other Optimizations</a>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+  
+
+  
+
+  
+<a name="N10009"></a><a name="ch_GettingStarted"></a>
+<h2 class="h3">Getting Started: Coordinating Distributed Applications with
+      ZooKeeper</h2>
+<div class="section">
+<p>This document contains information to get you started quickly with
+    ZooKeeper. It is aimed primarily at developers hoping to try it out, and
+    contains simple installation instructions for a single ZooKeeper server, a
+    few commands to verify that it is running, and a simple programming
+    example. Finally, as a convenience, there are a few sections regarding
+    more complicated installations, for example running replicated
+    deployments, and optimizing the transaction log. However for the complete
+    instructions for commercial deployments, please refer to the <a href="zookeeperAdmin.html">ZooKeeper
+    Administrator's Guide</a>.</p>
+<a name="N10016"></a><a name="sc_Prerequisites"></a>
+<h3 class="h4">Pre-requisites</h3>
+<p>See <a href="zookeeperAdmin.html#sc_systemReq">
+          System Requirements</a> in the Admin guide.</p>
+<a name="N10024"></a><a name="sc_Download"></a>
+<h3 class="h4">Download</h3>
+<p>To get a ZooKeeper distribution, download a recent
+        <a href="http://hadoop.apache.org/zookeeper/releases.html">
+          stable</a> release from one of the Apache Download
+        Mirrors.</p>
+<a name="N10032"></a><a name="sc_InstallingSingleMode"></a>
+<h3 class="h4">Standalone Operation</h3>
+<p>Setting up a ZooKeeper server in standalone mode is
+      straightforward. The server is contained in a single JAR file,
+      so installation consists of creating a configuration.</p>
+<p>Once you've downloaded a stable ZooKeeper release unpack
+      it and cd to the root</p>
+<p>To start ZooKeeper you need a configuration file. Here is a sample,
+      create it in <strong>conf/zoo.cfg</strong>:</p>
+<pre class="code">
+tickTime=2000
+dataDir=/var/zookeeper
+clientPort=2181
+</pre>
+<p>This file can be called anything, but for the sake of this
+      discussion call
+      it <strong>conf/zoo.cfg</strong>. Change the
+      value of <strong>dataDir</strong> to specify an
+      existing (empty to start with) directory.  Here are the meanings
+      for each of the fields:</p>
+<dl>
+        
+<dt>
+<term>
+<strong>tickTime</strong>
+</term>
+</dt>
+<dd>
+<p>the basic time unit in milliseconds used by ZooKeeper. It is
+            used to do heartbeats and the minimum session timeout will be
+            twice the tickTime.</p>
+</dd>
+      
+</dl>
+<dl>
+        
+<dt>
+<term>
+<strong>dataDir</strong>
+</term>
+</dt>
+<dd>
+<p>the location to store the in-memory database snapshots and,
+            unless specified otherwise, the transaction log of updates to the
+            database.</p>
+</dd>
+
+        
+<dt>
+<term>
+<strong>clientPort</strong>
+</term>
+</dt>
+<dd>
+<p>the port to listen for client connections</p>
+</dd>
+      
+</dl>
+<p>Now that you created the configuration file, you can start
+      ZooKeeper:</p>
+<pre class="code">bin/zkServer.sh start</pre>
+<p>ZooKeeper logs messages using log4j -- more detail
+      available in the
+      <a href="zookeeperProgrammers.html#Logging">Logging</a>
+      section of the Programmer's Guide. You will see log messages
+      coming to the console (default) and/or a log file depending on
+      the log4j configuration.</p>
+<p>The steps outlined here run ZooKeeper in standalone mode. There is
+      no replication, so if ZooKeeper process fails, the service will go down.
+      This is fine for most development situations, but to run ZooKeeper in
+      replicated mode, please see <a href="#sc_RunningReplicatedZooKeeper">Running Replicated
+      ZooKeeper</a>.</p>
+<a name="N10083"></a><a name="sc_FileManagement"></a>
+<h3 class="h4">Managing ZooKeeper Storage</h3>
+<p>For long running production systems ZooKeeper storage must
+      be managed externally (dataDir and logs). See the section on
+      <a href="zookeeperAdmin.html#sc_maintenance">maintenance</a> for
+      more details.</p>
+<a name="N10091"></a><a name="sc_ConnectingToZooKeeper"></a>
+<h3 class="h4">Connecting to ZooKeeper</h3>
+<p>Once ZooKeeper is running, you have several options for connection
+      to it:</p>
+<ul>
+        
+<li>
+          
+<p>
+<strong>Java</strong>: Use</p>
+
+          
+<pre class="code">bin/zkCli.sh 127.0.0.1:2181</pre>
+
+          
+<p>This lets you perform simple, file-like operations.</p>
+        
+</li>
+
+        
+<li>
+          
+<p>
+<strong>C</strong>: compile cli_mt
+          (multi-threaded) or cli_st (single-threaded) by running
+          <span class="codefrag command">make cli_mt</span> or <span class="codefrag command">make
+          cli_st</span> in
+          the <strong>src/c</strong> subdirectory in
+          the ZooKeeper sources. See the README contained within
+          <strong>src/c</strong> for full details.</p>
+
+          
+<p>You can run the program
+          from <strong>src/c</strong> using:</p>
+
+          
+<pre class="code">LD_LIBRARY_PATH=. cli_mt 127.0.0.1:2181</pre>
+
+          
+<p>or</p>
+
+          
+<pre class="code">LD_LIBRARY_PATH=. cli_st 127.0.0.1:2181</pre>
+          
+<p>This will give you a simple shell to execute file
+          system like operations on ZooKeeper.</p>
+        
+</li>
+      
+</ul>
+<a name="N100D4"></a><a name="sc_ProgrammingToZooKeeper"></a>
+<h3 class="h4">Programming to ZooKeeper</h3>
+<p>ZooKeeper has a Java bindings and C bindings. They are
+      functionally equivalent. The C bindings exist in two variants: single
+      threaded and multi-threaded. These differ only in how the messaging loop
+      is done. For more information, see the <a href="zookeeperProgrammers.html#ch_programStructureWithExample.html">Programming
+      Examples in the ZooKeeper Programmer's Guide</a> for
+      sample code using of the different APIs.</p>
+<a name="N100E2"></a><a name="sc_RunningReplicatedZooKeeper"></a>
+<h3 class="h4">Running Replicated ZooKeeper</h3>
+<p>Running ZooKeeper in standalone mode is convenient for evaluation,
+      some development, and testing. But in production, you should run
+      ZooKeeper in replicated mode. A replicated group of servers in the same
+      application is called a <em>quorum</em>, and in replicated
+      mode, all servers in the quorum have copies of the same configuration
+      file. The file is similar to the one used in standalone mode, but with a
+      few differences. Here is an example:</p>
+<pre class="code">
+tickTime=2000
+dataDir=/var/zookeeper
+clientPort=2181
+initLimit=5
+syncLimit=2
+server.1=zoo1:2888:3888
+server.2=zoo2:2888:3888
+server.3=zoo3:2888:3888
+</pre>
+<p>The new entry, <strong>initLimit</strong> is
+      timeouts ZooKeeper uses to limit the length of time the ZooKeeper
+      servers in quorum have to connect to a leader. The entry <strong>syncLimit</strong> limits how far out of date a server can
+      be from a leader.</p>
+<p>With both of these timeouts, you specify the unit of time using
+      <strong>tickTime</strong>. In this example, the timeout
+      for initLimit is 5 ticks at 2000 milleseconds a tick, or 10
+      seconds.</p>
+<p>The entries of the form <em>server.X</em> list the
+      servers that make up the ZooKeeper service. When the server starts up,
+      it knows which server it is by looking for the file
+      <em>myid</em> in the data directory. That file has the 
+      contains the server number, in ASCII.</p>
+<p>Finally, note the two port numbers after each server
+       name: " 2888" and "3888". Peers use the former port to connect
+       to other peers. Such a connection is necessary so that peers
+       can communicate, for example, to agree upon the order of
+       updates. More specifically, a ZooKeeper server uses this port
+       to connect followers to the leader. When a new leader arises, a
+       follower opens a TCP connection to the leader using this
+       port. Because the default leader election also uses TCP, we
+       currently require another port for leader election. This is the
+       second port in the server entry.
+       </p>
+<div class="note">
+<div class="label">Note</div>
+<div class="content">
+        
+<p>If you want to test multiple servers on a single
+        machine, specify the servername
+        as <em>localhost</em> with unique quorum &amp;
+        leader election ports (i.e. 2888:3888, 2889:3889, 2890:3890 in
+        the example above) for each server.X in that server's config
+        file. Of course separate <em>dataDir</em>s and
+        distinct <em>clientPort</em>s are also necessary
+        (in the above replicated example, running on a
+        single <em>localhost</em>, you would still have
+        three config files).</p>
+      
+</div>
+</div>
+<a name="N1011F"></a><a name="Other+Optimizations"></a>
+<h3 class="h4">Other Optimizations</h3>
+<p>There are a couple of other configuration parameters that can
+      greatly increase performance:</p>
+<ul>
+        
+<li>
+          
+<p>To get low latencies on updates it is important to
+          have a dedicated transaction log directory. By default
+          transaction logs are put in the same directory as the data
+          snapshots and <em>myid</em> file. The dataLogDir
+          parameters indicates a different directory to use for the
+          transaction logs.</p>
+        
+</li>
+
+        
+<li>
+          
+<p>
+<em>[tbd: what is the other config param?]</em>
+</p>
+        
+</li>
+      
+</ul>
+</div>
+
+<p align="right">
+<font size="-2"></font>
+</p>
+</div>
+<!--+
+    |end content
+    +-->
+<div class="clearboth">&nbsp;</div>
+</div>
+<div id="footer">
+<!--+
+    |start bottomstrip
+    +-->
+<div class="lastmodified">
+<script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+</div>
+<div class="copyright">
+        Copyright &copy;
+         2008 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
+</div>
+<!--+
+    |end bottomstrip
+    +-->
+</div>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/01b6b5e4/doc/r3.1.2/zookeeperStarted.pdf
----------------------------------------------------------------------
diff --git a/doc/r3.1.2/zookeeperStarted.pdf b/doc/r3.1.2/zookeeperStarted.pdf
new file mode 100644
index 0000000..0be5ca7
--- /dev/null
+++ b/doc/r3.1.2/zookeeperStarted.pdf
@@ -0,0 +1,576 @@
+%PDF-1.3
+%����
+4 0 obj
+<< /Type /Info
+/Producer (FOP 0.20.5) >>
+endobj
+5 0 obj
+<< /Length 770 /Filter [ /ASCII85Decode /FlateDecode ]
+ >>
+stream
+Gb!$E968Q9&:j6K'fr4I$9e@Ged#ajL.Q*-.WB?9`USm3\["Q!r-BnUNar@Z^sIUQLj-P5e[Nu0FI<?:DC?V9,*8r/AH.qr!_%V?C4@'G<YmLoBc)JE"$XsNP^4uN/bBo?-W/ZJT"PlYPd57cH]r.gEmJ3!k2Hes!U73K@aYK$7H#DD+l,Xk4<:LJJD&8m)2ALXhE9$uQ*B5WrA7G'pV'VT#\faFGT:*J*Y0K)#:(-a`qoeADbba8n,,]<?3^8)q[C,\ROb4V?HR)#G?m*rQ](5p>J9U%Y,cTr=t82bmB/9]-[En^am`A-ldAP8HPi-4B@C8?MB`Ju+V!qo6kB_$f\okhF"JHBAQ'Mp9[2t$*m;bV4IV\W$mq"&9JVYKY169J.a.i,m=7lDp`%:_#U>*uVicC_G'hCpX-E76DVf9NDU4n.%lQI@qX&\F22`W%e81T-GPI9AX;I5kW#6)1YB3g$QVBdcNj0We">`*`9p+&^+J7fi*NkWk@QA=27f>V+qHN<RmlT6#ln+p_d)'L?hr.V:6>)e4IfOE'8I1@]V[<%.=u6OLEk'jr3J+sYrMekM<2Y8UfJ+8JfedljrQZ0SA,?aWZhCGF?CPt6IN-Sl'/oWg[D`7A:pFrei3BneFa"se+rI^,[[Se!KEEgA.ejicg5?t3,RD5R=@.58_jnUijIfdu*Xu+U5O#IU)g?/r9K72.5q$nS\e\&NW3`<RhlE$qA_PVgW,6ljfJGq@Xf@o<`GRe@1dZ[,3HXKB!Mp#gn,~>
+endstream
+endobj
+6 0 obj
+<< /Type /Page
+/Parent 1 0 R
+/MediaBox [ 0 0 612 792 ]
+/Resources 3 0 R
+/Contents 5 0 R
+/Annots 7 0 R
+>>
+endobj
+7 0 obj
+[
+8 0 R
+10 0 R
+12 0 R
+14 0 R
+16 0 R
+18 0 R
+20 0 R
+22 0 R
+24 0 R
+]
+endobj
+8 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 102.0 529.541 455.312 517.541 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 9 0 R
+/H /I
+>>
+endobj
+10 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 108.0 511.341 189.488 499.341 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 11 0 R
+/H /I
+>>
+endobj
+12 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 108.0 493.141 173.492 481.141 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 13 0 R
+/H /I
+>>
+endobj
+14 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 108.0 474.941 227.816 462.941 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 15 0 R
+/H /I
+>>
+endobj
+16 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 108.0 456.741 268.796 444.741 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 17 0 R
+/H /I
+>>
+endobj
+18 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 108.0 438.541 248.144 426.541 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 19 0 R
+/H /I
+>>
+endobj
+20 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 108.0 420.341 258.812 408.341 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 21 0 R
+/H /I
+>>
+endobj
+22 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 108.0 402.141 276.14 390.141 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 23 0 R
+/H /I
+>>
+endobj
+24 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 108.0 383.941 221.828 371.941 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 25 0 R
+/H /I
+>>
+endobj
+26 0 obj
+<< /Length 2348 /Filter [ /ASCII85Decode /FlateDecode ]
+ >>
+stream
+Gat%%8TWWE'Y`m7n<RV)7L8G+9FaYLUs!kC`]CNlJL2NHA!0XgdYdV]qnVkj!bHLpL]R,7g\9Y#ldb<^YsSWQ3pY&5Fg`gc\F>P?W=*oIi"PBGcFS&qGtH+.kLL%6rQA!<Bm@=^0CG<'2QV-Zhg>u%(;.r:n*[]#,_'Ldg\LErIUDXc^(duDD\'M6c)8=1pk,h7PHUL+Sb;HP?e2:HTWD2he#HL#%nI=%:='U.L2KQA1j('b*`dcmhJ6%WLO-Y5VO8JO6/5\ThJo>Y+nE'NFYhq9U2D`Hp#Pd8aK!^<^21aco9LQrUM/hClFf)_HuF<0=<=)W!XcnbLcJL!j-Ac^3Qne\9o(`1]9g1Q,f^NR`33QEX:ucfn_K&8&Q*@Y,7u/\(l>]35pGURP!]tfp*ITd#!\C7M21c+D"EjdJP[IL2Y4gC,jo'S!_]aCP[ot59Kk1V@kaI,YlhG0Wk^<"pC-QL)s!N$L],F5@OU!B"r3J0Q_"#t@W+S)15/qKAQDf#!83E,e"W*'#\@5+7k@\DV*aO?=Nt!>ZQ!^"PK9_kEEM_%@],?QCn'YnJi'T_[$qmY,T9@00_ETmQPIdgFgI/]K-/COO&\5R?,3!jl5lXb_BegaYP:o"C3Fbn_Jnd.NQc.&j_!)1@Z(<\X#N@uap!DY)(7Ya\E9TgSgbeQdnJmd/"\U7G\>0:;W(::7^<KSen?(f6b:S"1N:'WE`P"&8JD<CM!DjZ*1E`Mo#>b8\0MAjkMY.iD13Um>A$iEAhiU\*@P$k+f03Af=N=$Phc0VaQ&)paWgPZksRE[qQ>?peRLCNKRBI/e2@&;H0HW#kN&U.m^jpAmM5SYFL/]R>$d/m`/%l73Ia\VmlD0B>=NZ>"5=%]!s6:UjGRQXP/5(9]O>Oe(5-Qj!pYiN!(OYG%42?Y0UrVfhQt2^Ub;2N`!MTk,db`iSSQW#F&d[L>R[;reZe=:;+.;:jKdQ^(<HjjO+rBDMc$*;Z+aRf/0sOBK-
 gF::!RV:og6:UOrcn;SQ!i]9+XCDGi>#@*_M_[EMuNm'oQc=KE--Bn-DiG\11.!8H1(TT]6[I6UT1O0T$GT6R,&@[?reZY`UL*:oQ<2I&P^hgYsS+"Qc;F,Nr^gRr5CNadEMl&]X$%BeAc*)^M)[,o`_u1gHiTcs3["YJb$%'D>RH+-qHoFk1Z?m`sV\-^R_%ok`4SBa!Y9)mdOS=T_l&?"Be*k[t1X!(@]%a\NN^6dm#::'f.[.\$>QlAsAukFAVUmJbgul7jf\oZ#$nAl9o^N!h<RLT/2#]*;*J!RM[(bo4Xd9H[e!i-Y>Ri^Y&`UW$>0"591drV(MC;+C'g6Vf#4e[Djde59%]b+<mhA1%bcM0:h*g\0#B<c\>/Un]rB!>QQ#hhrk(*m:$)i;'(n/k#N:]%S&pjjCeBQn'!Lq$_mMm"K,S2H$LCd72p^\n1T0`l@FNZN\ee2k,rLd+?o)\:$S=*MU;/M(c3ILtB.8SCD0_6Y,#gZsIPEqPOlMheX[oo@a\&fYEZgUjZ`0DeK]e)a[Vd.<JJd5;^ctDodjOe@g;:#mKFfL''"e0`+T0:tO-6]JLaN33F2_IpDT&^%GX^[0>D[!g9@sf1"8$G?hk1rKKn@Jk$6G9epBsY!6f:,qOu!(Eo9WJ-Y9AVtIFD3o-1W?=n:?TX\S^;]^m)PbjLTos*2<.lC#WCDJ=`4YDaFj2m+X]N**j3hV1pFN]LF/L1CbA=.g_U:IWM_?R-M;0`-`POXPA]<'kp"gai,Z9>I>;0NAWdF[qDpE<HfW9sD2nR4.+aDbKaH^5VS-TKiH#IJQIAUf'KWdTLA>F)mcIUE!G$:bW"($o)D`E&2Uh]T9<dA/nu@)Xo"N3K[!1OqDc^n;-LAYIsSDY28gmj;3K_!l54c'lB)r18eC0hJM$5@fZ78>hL&4E4+8k[ZM'9<K*W/q+CJ's>L\'VbX!Z>"?q_(F$[3sL7bJ9HuD".k,-:G@DST[1TP0D+O8[0X,
 hG#I)K,GI%n$5YdA7a6MI96E.IMEDhd)T@Aa='+!=Unq/q>`/HrgU1dL>Z.!A[hYqHIe2+T4;a_Ze_+9r`(:Y\E"8/kdaM[g35e.u-lsM%DX7Dq,LeX\V_1**g$>crKDKEC!S?6kRQ1VrEt[+BE?D)4/`YK7R125lHM6KClc$Hr,1$$ob&hhls(,U;%R$m%45[IO!7[!:O:Us?-*RHgo\YVVT:Y<`JkgdS4/l8#;!gp,O+9fjLMRpW")Ns'*/&"oUL?^A.!2+oW&N!8Ys1jo20AbZXsJE<SPObiP5-qN')c7op;Z^;fJJBB"hDDD-sB_\"pdDTod/333nXk2=gt";AG4i/2;VaW~>
+endstream
+endobj
+27 0 obj
+<< /Type /Page
+/Parent 1 0 R
+/MediaBox [ 0 0 612 792 ]
+/Resources 3 0 R
+/Contents 26 0 R
+/Annots 28 0 R
+>>
+endobj
+28 0 obj
+[
+29 0 R
+30 0 R
+31 0 R
+]
+endobj
+29 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 145.644 550.466 309.108 538.466 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A << /URI (zookeeperAdmin.html)
+/S /URI >>
+/H /I
+>>
+endobj
+30 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 110.328 499.213 215.328 487.213 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A << /URI (zookeeperAdmin.html#sc_systemReq)
+/S /URI >>
+/H /I
+>>
+endobj
+31 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 341.616 447.96 369.612 435.96 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A << /URI (http://hadoop.apache.org/zookeeper/releases.html)
+/S /URI >>
+/H /I
+>>
+endobj
+32 0 obj
+<< /Length 2343 /Filter [ /ASCII85Decode /FlateDecode ]
+ >>
+stream
+Gatm=>>s<8'Ro4HpoRsO#YUI8S!cGOP0ckM;P4P7kqH^N];rr[2SMH?YOD!Mp6!s5aCQ2(bH%CZs3<Xaeb-bJl[qt<e60]Xq*F'Sf*R$/5.P#b+8Hs(4GoY63d1gY*5$T\J-o%bJG()"oc2-4X6\;egQ8u86QPHH26@r3)KP"%FoHip8<h?@$_<W>c9KVI00njtZm.Ub,1Q#Db)JN*N`[OAMeth!<i$k/'318P)qHO1%uZ`4>3d`'Mc/f@k_(YlZoV,O,/aF>rI?kF@W]hhY0`TIN(^_"H_n]$V:JWff1_<k.ZlCI%ZJfTU5ZA>Iqek^PZsQJFRhANF%O0$lT6^2e.\q_/)ZEIjD/E-bKFt)F#A(H26Ms1BKJ6VkLe'pM-NM:g7%;%A]Oh!]TW*(bXo&?E<@"M5O8%*,X2].a?-Hs$6g#HFYTsq=VUC0U,Q)GZF.*2s#VcmNY&><O_^8gN)_X7j*OnJG6uutZB8@Rbo6g),B=]b!7JaqIBYSQ;MPK0@?:KO9`e?+IGm:J=05UelInJB(;hTB*:NNGh.YCo`gOgKY@E-l(N"+%6L30d!k.oYf>uSaE09I/*iH!]Im=c5YLHI5@Jp4^l[qfk&IU$>=6t"`6Dp.4E*A<dW6j0M2rM>K>UALV+nB!K4N>JbNs(kI*SeSml?,_Yi7Q1gBo/b._(ZOB<m$Ut^4::Kn@ch3!L@SbKlg<A.`:2MOZ8$c$HY,e3m'pTC`+T]6hI@dr-E4PY)jnHnkCaGM-;b$+UfmJ%^ha)RmBX!PN^b+0-Eds8jYi[05%@m!8OLVH=7'<)MtfM&"07@edOdH'Xj$%8lArZ3'?V?U:4i8>p_B3TGs%lPuV<FXNFg+;pW1rV8a*,5\cW052/KFKk7YP'_<Lj!!Pcg#/n0)"K[+C*";/Z5jD]W=Z/Ot%X-Q"C9GrjY.Fp,UBA:6&Nn=0cm,K_`53^V:<M>$QUbJ:)lZ387j8Q;De>D[FO:)raL=7h4rfId87
 +oA6bS=Cb(GKUT=);)_a>UI50i/qKk;!lF]I]H&/o>%[=gZ87"iF!$6CSMl4djq46IdWU97L@X0'O)--ArT+?Wb,UOlN/!^rp)?9JXj8"UG0cJ:S[9l1]:54WbDo.3Y"a/Q`6Skl:^"c?,]`ig+03S>$\[k;P.OV=m:D&d!;\8Gq8n].;+HQWR3#KW#g?N%g[rloMie=;)38Rn#O)]`Q!3>%8m,\bF)Oc7Y,\$IQU%TjP*!p5Rs@!uRdZ`[6!lOV"gZQ$#Q,`(W''<M]><A/_p]Qt`g'"0\rrLVs\1PNlg:'Am#p7(j6ni:g80re?%gC5LYUJ*n`9H-Bb-b[(TN++KhH*gN:L+seIB6#,q.>0Fp0@1j1)rWn;VDoI3qm2CAB4C*.o0`!Z34E>mS>!pKd/d(uZ/mN6f$$IK+RhY[$)8YlEb=te-NXmK?4M`X,0OFB'Hi(E].&UAQ#<^dY\lsl'(o,]!0M+sM)&kleJ)Qc^W=qj_2TLKqp_K>YlekWSDZY,[oP!g6hkMUnFm.V3%<BT\UhkJ.@7Q"*t@\JKgf&RH=3!e_RmjF6IP*0mHD=f#(9*Wl]B+.`rf4PRMr'I/u-\(I=+eW9r%;CZHti:W!5.K.uO^*@u4?[N(6]R7qYL+Y>Z%K_ut@J09-iqG^;!8#n3Ib;0B?I3T-.IO[F:;fiPh/Q,=<?[qnh7Ld`GXOlGrVl0J(^/F8%AABds^WnaOhT1q;#K$*G4T<\b:PXM3>A"i[t_DB?5:6%.D:s$s*+(d0^XEhXr1M^WK`&uZ95)jtV,"QO.nWOlH?mb(t/Y_Asju_BqFiF][Ih5tIpWWB*AMof'YA`=sr9EkFo#'k6l1Ih:&j*uLN;C+0^gNB4kr@G4O63jioIDb2S-\gNc&6Me*'T'@=oLn^\AHLO<=I8D9j7hLH6_r'\D`RBje=6p\8G<;G#1HCGc$^#hs^3QoOJJ*"cSL.@!^H*!LL>jqh?G`#*<//IlZi*cPsDCZoL=
 ge_EmB-8$XihmRcX9i]FI(uC/5S$UqAp0A<2!&5N*<`R^-ZL*n,qt!a_mc-]IV1"6?E-ES&*__nieQn$nB8([<WtIQ<=5:j,MR0TJ_6I*d)]2i7[U[;sG#Mo:J8\h]C:1pmcri,&.Q@$M+M-cH%Wj0^IKn:EPXQ77(8AN.@*X[O=dge>Is4n"bI<?;qs$7LHg"^Y1$As8nLarM_YcFr=!e"5UgOdiC=((FdEUZ6.h??*^^I.I'AUWP+9:4pi&abC.-kKj1VJ4\eU#\h<.mtIaF$%MR-TLEWf*HlEOq,GG^ZDij[0iNm@1Srb*M2@[O5k\Vd2-l$ac5m/S*mYA%;O>`Vj)j~>
+endstream
+endobj
+33 0 obj
+<< /Type /Page
+/Parent 1 0 R
+/MediaBox [ 0 0 612 792 ]
+/Resources 3 0 R
+/Contents 32 0 R
+/Annots 34 0 R
+>>
+endobj
+34 0 obj
+[
+35 0 R
+36 0 R
+37 0 R
+38 0 R
+]
+endobj
+35 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 419.616 595.04 460.284 583.04 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A << /URI (zookeeperProgrammers.html#Logging)
+/S /URI >>
+/H /I
+>>
+endobj
+36 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 395.28 521.04 490.944 509.04 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 23 0 R
+/H /I
+>>
+endobj
+37 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 90.0 507.84 143.976 495.84 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A 23 0 R
+/H /I
+>>
+endobj
+38 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 273.3 443.387 333.948 431.387 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A << /URI (zookeeperAdmin.html#sc_maintenance)
+/S /URI >>
+/H /I
+>>
+endobj
+39 0 obj
+<< /Length 3016 /Filter [ /ASCII85Decode /FlateDecode ]
+ >>
+stream
+Gat=.>Ar<.&UsJX&G"23!/Vn_OsgM'6^"%:ma[:+S>&_"jB_1+@7f8<iiW+D44Ih!PXp'u"SS9hc>]rD%*<n.^\[X&lGjY0p@.\H.Ll<kMrPY'LQVT5?,TX5#0a-$pMfg"X%tA]Yg<p.lM"X0O&5W2IWlNK6im31?;DD857U$K^@;-p\iGR*hE0G2H!Q6;cM"R!:K+f%a(Zgbl0k`(Kg-$]W!Y7W'k/]:SZ7RKOfEdjc.2qJl,<A+GQ5]id9^#FgK3j$ET3lY#-!G$K%,Jj12b=s?Jm1CpJ0RNYPg^lmCfjc',RJAD5Hr+<YV+Af$3A^_<,11^A3B"MuZs*M9k*5-]:jcM%g9pl[Q5"R#BZEnVfJEQ]h%/(+a&#KbjoD+($5]R1]fW98BH%Y'M%q]$6B=RkZ$%>4tWMcNL;AIFbV*;GusM6Irb[QuVOLd&!9ah&cSql;'_d7HN09c<>-%YA^j[&^OQU_L.s'QfXc/OiV$qM!>dXbfr)n>K5u5/m6,6(*F$r5j4%;$2q8sgX2K-s(Ien9[VQ7#-PO1Y%bOG>;U)1!uod.#%2(WPe3Kb7+k74+)c(4Iurmm([cjr3cm8i,tRt?jQkkN5"G,=XY!1Uo5EWUb>$QDm5/Gb0=,<p`/d5KQApu]5*$\;_[nC$>Tj^D79^%M2P*/U=gcAoD3dQ*^a0%d()N9r.\B*X%J(H4&l2Ze0$9##YQr+1aORNq->s-!R-K4]l)5'tLE%c.#'<50s3rrM[>pO+[[W[)c`0E#*E8LQk#GVlCp_@E?u7_GfgkpSMn1W2e#;]K;XMjQ`O2Y96rhtF1-urn"c]ft^H7h"iR9@(Yp.j](#hZp0c#=YW%%A"<`O!VVHQG<j34DmBMp"g(f%f`cBpN9X]>lE58q#BgiT;@j7n^!)2N?uU:.[H`<22Y41T:1R1FHr`rU7B)<gPUhPt-1o*iTLUDuUB.;c<u\<)]9BkuZ]]aGX<koXm8SRcdq@d'nN3%`O%,A
 O%N+%55;2FA+6^:X5L<'"\-GS!.Aie2<O5<6s[%Ara?F5mg/NZf3XPaee$lB/l:\1l*(4u=X-o6;nrED;'.YZ`$8WJD"a[onpn?<5\HT<db\J!G>u7DU)SiHNKNZ;%JfpJt;=2'iR6Y"t]!'0^S_ZM?;08ol"Uf5bP3ULA$<>]0DGe@HF$2Ah_H;opE=+?K<`P9ft>i0T]=3^(VZ3i_H.$ZmP6WnaC[RZ8u`S0]ncOWT`0aGnCnEB&PAX66t%oZrne(m5'&^;98SgD).c$%4_06\4&Y^o4\-1R=1+fid&C4n#khk'\l)4jHIuV.=!tfpTh^A`tPL7BBKK>t7_m"2J@p2N@[Y%-s*o+TrcUfsu(@K-:\O)O`^X"+J4?])@MZiALs'ZQmF"l=;[n92e%lBm(>p'o#EK(k;cue\3t#Y1C\H&%H.LW`Za&78V811'U$o1D'IM3Fh7qC12j]NaudpFVGe*HZfO->=sZ>bYT>6H`*?9$E(nr<+lEs2(uj],E?AX.+E-n7KFn+:lVOs/;lk[5"flt)U$Mj,@Ibk_[,ke4Q8,Q./GE80%gl+]37J&D/3p/BMQWk=<)qf$nUaB"=I\@f]qP1XCK\f:b-rAm4SX%SVGS^O#7X&VrlVWb@U'-c3:F0#Ai';Hc-MAFDu4BVVL*In$dotXgVcV"?.+TN!?E$=O\CS)fZ-HQKj.SSIT[]E3jZjhZM$Z*821gN+k\"ZYX0CILRal*/(^PT&k,IAUuT.!@Ef4U"A[te]rhD&A=>D'I$O?)astChX&8n=maiOP,-31l2#^Dm'82a7"tSoo_<\*q<#\cE&<P$[/(t>3!2;g-DbJ>7K,D/Tc/92DK7?;#)QW<AJNm%fT^@7q(N7b+Zt@"%1S<'hCIF*]g>c7'o!!2rGoA6'0:]HL(Pu&WT(nQ#LkqiMj=]AH.Qs#B:XUQo;E+*l>-;)j\fq8hf-d[9j;^nhkGRi:>!!P70+-'T9rJ<QkqUB\n,`jp6@<
 c::V!1<Ej8`%.*@YG;IlZIkfe"qMmgYAmoK";]<UkoV+gn(s.Q8rtE5Q;gGN@Ah@tmZPWRSO6r8&0[:_&)-U*5OPSVd:oI`6Yf`80+u^K1Bs7.&T5W?AoEG1/XdIk_pjPtSZ=OZ@_---12K+mc=\M*0$1^JJ(I$#^*go:oR\M8m@C0o&I1r-GFKEEA<oRN3auL:U;.Sb=geso;7TmRYP4M"K;4PQ<]_,Qt9,@8Ui%.I21XfH/`p8(<KZ6l=`nb9WK<h$8hD'TbfT6enk((>U.>6)1U2M.9YG)N@2?j;5J9lDG2:q.-kj;:)d1J/#I0"IYkmQ"sq'$ZfNp27,PT%7CL[0f36E-M]8>UjVg`&K"GSRWR7YVmn)%7C[5/#U/SL'YPB'FHcc-aiTir:5E,ThhZ*n7l-i\-n6$0b./RElc:NHg(jLN.DuAYfL5oh,:"bQ1,-nM[c<jHUaJ23_O\!h(*3ip+%&I-pYWbmX7a28"c1]*S^pdDXO!=&957WlEX&1V-DP)\,+;SU'<(FoOtDEg?U8(LVE*$liR%EJ#R_C;<,9rVg!spf)=KT6k@tV0XaOk0a7ldbk2r)B'B%hZrg"^;"[\2jQ@%T+UJfi-q_6qht:([?LBQA)>l<D.bdNZn,`EiC:4TD$8';X1Gna=,;qTdLsha#+OT&fGu([iI4<bPKLC+7qH0\ofLm)E=5&MJb/S/M!5E'/I.9gOq>fFe5i>Z>FOU@m]boL!8$W"9@:&qXlb\>0>N1g8%kZbm^&NV@M/mL4uVY1f4HE%FV5[k+1fJNlrNdeFR?N@XhVW=T"$4?()lZDpmlBlEPd)i;bOUE]Dl\7^"6U[dgRQcce[idLu.^O3qUW\'U!nEkb<tNO+oS0W&To:1rrq1#\7BNo271"+PL\@(WL>9dVUPkd#V!E7_&.[Oe9YOQOpMD>,op6pftr>T`Y@fFAYOQ16#rY,h$G:hWb=fNrV(OI&D/4Bo)8-k)3utD0G=J#I<3Mr
 LhoW7Usj)cka$%rrWr6lJV~>
+endstream
+endobj
+40 0 obj
+<< /Type /Page
+/Parent 1 0 R
+/MediaBox [ 0 0 612 792 ]
+/Resources 3 0 R
+/Contents 39 0 R
+/Annots 41 0 R
+>>
+endobj
+41 0 obj
+[
+42 0 R
+43 0 R
+]
+endobj
+42 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 371.976 660.8 518.304 648.8 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A << /URI (zookeeperProgrammers.html#ch_programStructureWithExample.html)
+/S /URI >>
+/H /I
+>>
+endobj
+43 0 obj
+<< /Type /Annot
+/Subtype /Link
+/Rect [ 90.0 647.6 246.12 635.6 ]
+/C [ 0 0 0 ]
+/Border [ 0 0 0 ]
+/A << /URI (zookeeperProgrammers.html#ch_programStructureWithExample.html)
+/S /URI >>
+/H /I
+>>
+endobj
+44 0 obj
+<< /Length 843 /Filter [ /ASCII85Decode /FlateDecode ]
+ >>
+stream
+GasIf9lHOU&A@ZcHqY#iYeb_J;Di;)WNFZ>iRB[h#7PC)[Ae!UD1?uI^b/!k2MsD%`ZEHqk;VGe,5>%=Ifb3?s18a2&;MZ*')t1.qsOn*&PQ>\N'L1T?#X'PQT$?;O^BX(+<9B-s$tEQ)b2k8'GXjEE(4f$cd;n::-/:22SoI#F)if2E[S9#kNEKm?e;MM%-MVV6kal'$S2\u3au7OTG01O7N@+X/EY0(@Eb@?m^j5cko+q&_3\?UZK]VaIWfqjn?$ZHf\,FGgjq^#[PpZpfC!7+<2FeAJ>!XRen3**.BY"\/oSgfR_p!*d8]^U9%brW/P.53L'WO/,>/pt'***S?\#t`:o+l!6HDFL<IP$PPi*YjrS('d`t_^"!5O=RY?t0R.TuT^'o4YN=^E_aU=ILfrj$(#;bRZI=42oQBsRms^#$S92=FcDIO]\2?!Rua=&9W>Qh@'R8IqK0RJ'%E-Q@#7(%:KY41egERc40@3EOa.*Q_N.cjWE$>D?s<ZML2f=H!oZ/7WGJ$G^NK)Z+a7I$UG/ef%)Zn]'t-*b8RRmY3c++V78HL]->(lP6gCbU![qLQYD)!5I-X/C#qPmE_%:(_ce&itQiZ:Y"!cnmsOWj=,ea%^&ldIs=("Td[hK)s!ujpOqZRNaGt>';?FA9iIR[#t8L9_E"TaL%!l<1NhuqYEtN)j*q#]$qX!WHBtI#+8SK?5Nh@MS0tAQnec$(K^1"(`$,ou<KV6HY]*(\R"8n.0`T!8$tZ[sEME;nmWM&XRt9L>IhVgq(muroL=pB;Z6#!d*A=+7YA<kf%>E2NUO,uM0*_\iD*&\(D@:8hKm=FKSr*=Ln;5Yl~>
+endstream
+endobj
+45 0 obj
+<< /Type /Page
+/Parent 1 0 R
+/MediaBox [ 0 0 612 792 ]
+/Resources 3 0 R
+/Contents 44 0 R
+>>
+endobj
+47 0 obj
+<<
+ /Title (\376\377\0\61\0\40\0\107\0\145\0\164\0\164\0\151\0\156\0\147\0\40\0\123\0\164\0\141\0\162\0\164\0\145\0\144\0\72\0\40\0\103\0\157\0\157\0\162\0\144\0\151\0\156\0\141\0\164\0\151\0\156\0\147\0\40\0\104\0\151\0\163\0\164\0\162\0\151\0\142\0\165\0\164\0\145\0\144\0\40\0\101\0\160\0\160\0\154\0\151\0\143\0\141\0\164\0\151\0\157\0\156\0\163\0\40\0\167\0\151\0\164\0\150\0\40\0\132\0\157\0\157\0\113\0\145\0\145\0\160\0\145\0\162)
+ /Parent 46 0 R
+ /First 48 0 R
+ /Last 55 0 R
+ /Count -8
+ /A 9 0 R
+>> endobj
+48 0 obj
+<<
+ /Title (\376\377\0\61\0\56\0\61\0\40\0\120\0\162\0\145\0\55\0\162\0\145\0\161\0\165\0\151\0\163\0\151\0\164\0\145\0\163)
+ /Parent 47 0 R
+ /Next 49 0 R
+ /A 11 0 R
+>> endobj
+49 0 obj
+<<
+ /Title (\376\377\0\61\0\56\0\62\0\40\0\104\0\157\0\167\0\156\0\154\0\157\0\141\0\144)
+ /Parent 47 0 R
+ /Prev 48 0 R
+ /Next 50 0 R
+ /A 13 0 R
+>> endobj
+50 0 obj
+<<
+ /Title (\376\377\0\61\0\56\0\63\0\40\0\123\0\164\0\141\0\156\0\144\0\141\0\154\0\157\0\156\0\145\0\40\0\117\0\160\0\145\0\162\0\141\0\164\0\151\0\157\0\156)
+ /Parent 47 0 R
+ /Prev 49 0 R
+ /Next 51 0 R
+ /A 15 0 R
+>> endobj
+51 0 obj
+<<
+ /Title (\376\377\0\61\0\56\0\64\0\40\0\115\0\141\0\156\0\141\0\147\0\151\0\156\0\147\0\40\0\132\0\157\0\157\0\113\0\145\0\145\0\160\0\145\0\162\0\40\0\123\0\164\0\157\0\162\0\141\0\147\0\145)
+ /Parent 47 0 R
+ /Prev 50 0 R
+ /Next 52 0 R
+ /A 17 0 R
+>> endobj
+52 0 obj
+<<
+ /Title (\376\377\0\61\0\56\0\65\0\40\0\103\0\157\0\156\0\156\0\145\0\143\0\164\0\151\0\156\0\147\0\40\0\164\0\157\0\40\0\132\0\157\0\157\0\113\0\145\0\145\0\160\0\145\0\162)
+ /Parent 47 0 R
+ /Prev 51 0 R
+ /Next 53 0 R
+ /A 19 0 R
+>> endobj
+53 0 obj
+<<
+ /Title (\376\377\0\61\0\56\0\66\0\40\0\120\0\162\0\157\0\147\0\162\0\141\0\155\0\155\0\151\0\156\0\147\0\40\0\164\0\157\0\40\0\132\0\157\0\157\0\113\0\145\0\145\0\160\0\145\0\162)
+ /Parent 47 0 R
+ /Prev 52 0 R
+ /Next 54 0 R
+ /A 21 0 R
+>> endobj
+54 0 obj
+<<
+ /Title (\376\377\0\61\0\56\0\67\0\40\0\122\0\165\0\156\0\156\0\151\0\156\0\147\0\40\0\122\0\145\0\160\0\154\0\151\0\143\0\141\0\164\0\145\0\144\0\40\0\132\0\157\0\157\0\113\0\145\0\145\0\160\0\145\0\162)
+ /Parent 47 0 R
+ /Prev 53 0 R
+ /Next 55 0 R
+ /A 23 0 R
+>> endobj
+55 0 obj
+<<
+ /Title (\376\377\0\61\0\56\0\70\0\40\0\117\0\164\0\150\0\145\0\162\0\40\0\117\0\160\0\164\0\151\0\155\0\151\0\172\0\141\0\164\0\151\0\157\0\156\0\163)
+ /Parent 47 0 R
+ /Prev 54 0 R
+ /A 25 0 R
+>> endobj
+56 0 obj
+<< /Type /Font
+/Subtype /Type1
+/Name /F3
+/BaseFont /Helvetica-Bold
+/Encoding /WinAnsiEncoding >>
+endobj
+57 0 obj
+<< /Type /Font
+/Subtype /Type1
+/Name /F5
+/BaseFont /Times-Roman
+/Encoding /WinAnsiEncoding >>
+endobj
+58 0 obj
+<< /Type /Font
+/Subtype /Type1
+/Name /F6
+/BaseFont /Times-Italic
+/Encoding /WinAnsiEncoding >>
+endobj
+59 0 obj
+<< /Type /Font
+/Subtype /Type1
+/Name /F1
+/BaseFont /Helvetica
+/Encoding /WinAnsiEncoding >>
+endobj
+60 0 obj
+<< /Type /Font
+/Subtype /Type1
+/Name /F9
+/BaseFont /Courier
+/Encoding /WinAnsiEncoding >>
+endobj
+61 0 obj
+<< /Type /Font
+/Subtype /Type1
+/Name /F2
+/BaseFont /Helvetica-Oblique
+/Encoding /WinAnsiEncoding >>
+endobj
+62 0 obj
+<< /Type /Font
+/Subtype /Type1
+/Name /F7
+/BaseFont /Times-Bold
+/Encoding /WinAnsiEncoding >>
+endobj
+1 0 obj
+<< /Type /Pages
+/Count 5
+/Kids [6 0 R 27 0 R 33 0 R 40 0 R 45 0 R ] >>
+endobj
+2 0 obj
+<< /Type /Catalog
+/Pages 1 0 R
+ /Outlines 46 0 R
+ /PageMode /UseOutlines
+ >>
+endobj
+3 0 obj
+<< 
+/Font << /F3 56 0 R /F5 57 0 R /F1 59 0 R /F6 58 0 R /F9 60 0 R /F2 61 0 R /F7 62 0 R >> 
+/ProcSet [ /PDF /ImageC /Text ] >> 
+endobj
+9 0 obj
+<<
+/S /GoTo
+/D [27 0 R /XYZ 85.0 659.0 null]
+>>
+endobj
+11 0 obj
+<<
+/S /GoTo
+/D [27 0 R /XYZ 85.0 527.466 null]
+>>
+endobj
+13 0 obj
+<<
+/S /GoTo
+/D [27 0 R /XYZ 85.0 476.213 null]
+>>
+endobj
+15 0 obj
+<<
+/S /GoTo
+/D [27 0 R /XYZ 85.0 411.76 null]
+>>
+endobj
+17 0 obj
+<<
+/S /GoTo
+/D [33 0 R /XYZ 85.0 484.84 null]
+>>
+endobj
+19 0 obj
+<<
+/S /GoTo
+/D [33 0 R /XYZ 85.0 420.387 null]
+>>
+endobj
+21 0 obj
+<<
+/S /GoTo
+/D [33 0 R /XYZ 85.0 187.954 null]
+>>
+endobj
+23 0 obj
+<<
+/S /GoTo
+/D [40 0 R /XYZ 85.0 624.6 null]
+>>
+endobj
+25 0 obj
+<<
+/S /GoTo
+/D [45 0 R /XYZ 85.0 659.0 null]
+>>
+endobj
+46 0 obj
+<<
+ /First 47 0 R
+ /Last 47 0 R
+>> endobj
+xref
+0 63
+0000000000 65535 f 
+0000016660 00000 n 
+0000016746 00000 n 
+0000016838 00000 n 
+0000000015 00000 n 
+0000000071 00000 n 
+0000000932 00000 n 
+0000001052 00000 n 
+0000001133 00000 n 
+0000016983 00000 n 
+0000001268 00000 n 
+0000017046 00000 n 
+0000001405 00000 n 
+0000017112 00000 n 
+0000001542 00000 n 
+0000017178 00000 n 
+0000001679 00000 n 
+0000017243 00000 n 
+0000001816 00000 n 
+0000017308 00000 n 
+0000001953 00000 n 
+0000017374 00000 n 
+0000002090 00000 n 
+0000017440 00000 n 
+0000002226 00000 n 
+0000017504 00000 n 
+0000002363 00000 n 
+0000004804 00000 n 
+0000004927 00000 n 
+0000004968 00000 n 
+0000005141 00000 n 
+0000005327 00000 n 
+0000005527 00000 n 
+0000007963 00000 n 
+0000008086 00000 n 
+0000008134 00000 n 
+0000008319 00000 n 
+0000008455 00000 n 
+0000008589 00000 n 
+0000008775 00000 n 
+0000011884 00000 n 
+0000012007 00000 n 
+0000012041 00000 n 
+0000012252 00000 n 
+0000012459 00000 n 
+0000013394 00000 n 
+0000017568 00000 n 
+0000013502 00000 n 
+0000014026 00000 n 
+0000014211 00000 n 
+0000014375 00000 n 
+0000014610 00000 n 
+0000014880 00000 n 
+0000015132 00000 n 
+0000015390 00000 n 
+0000015672 00000 n 
+0000015887 00000 n 
+0000016000 00000 n 
+0000016110 00000 n 
+0000016221 00000 n 
+0000016329 00000 n 
+0000016435 00000 n 
+0000016551 00000 n 
+trailer
+<<
+/Size 63
+/Root 2 0 R
+/Info 4 0 R
+>>
+startxref
+17619
+%%EOF

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/01b6b5e4/doc/r3.1.2/zookeeperTutorial.html
----------------------------------------------------------------------
diff --git a/doc/r3.1.2/zookeeperTutorial.html b/doc/r3.1.2/zookeeperTutorial.html
new file mode 100644
index 0000000..2870f73
--- /dev/null
+++ b/doc/r3.1.2/zookeeperTutorial.html
@@ -0,0 +1,876 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta content="Apache Forrest" name="Generator">
+<meta name="Forrest-version" content="0.8">
+<meta name="Forrest-skin-name" content="pelt">
+<title>Programming with ZooKeeper - A basic tutorial</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/fontsize.js" language="javascript" type="text/javascript"></script>
+<link rel="shortcut icon" href="images/favicon.ico">
+</head>
+<body onload="init()">
+<script type="text/javascript">ndeSetTextSize();</script>
+<div id="top">
+<!--+
+    |breadtrail
+    +-->
+<div class="breadtrail">
+<a href="http://www.apache.org/">Apache</a> &gt; <a href="http://hadoop.apache.org/">Hadoop</a> &gt; <a href="http://hadoop.apache.org/zookeeper/">ZooKeeper</a><script src="skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
+</div>
+<!--+
+    |header
+    +-->
+<div class="header">
+<!--+
+    |start group logo
+    +-->
+<div class="grouplogo">
+<a href="http://hadoop.apache.org/"><img class="logoImage" alt="Hadoop" src="images/hadoop-logo.jpg" title="Apache Hadoop"></a>
+</div>
+<!--+
+    |end group logo
+    +-->
+<!--+
+    |start Project Logo
+    +-->
+<div class="projectlogo">
+<a href="http://hadoop.apache.org/zookeeper/"><img class="logoImage" alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed coordination"></a>
+</div>
+<!--+
+    |end Project Logo
+    +-->
+<!--+
+    |start Search
+    +-->
+<div class="searchbox">
+<form action="http://www.google.com/search" method="get" class="roundtopsmall">
+<input value="hadoop.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>
+<!--+
+    |end search
+    +-->
+<!--+
+    |start Tabs
+    +-->
+<ul id="tabs">
+<li>
+<a class="unselected" href="http://hadoop.apache.org/zookeeper/">Project</a>
+</li>
+<li>
+<a class="unselected" href="http://wiki.apache.org/hadoop/ZooKeeper">Wiki</a>
+</li>
+<li class="current">
+<a class="selected" href="index.html">ZooKeeper 3.1 Documentation</a>
+</li>
+</ul>
+<!--+
+    |end Tabs
+    +-->
+</div>
+</div>
+<div id="main">
+<div id="publishedStrip">
+<!--+
+    |start Subtabs
+    +-->
+<div id="level2tabs"></div>
+<!--+
+    |end Endtabs
+    +-->
+<script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+</div>
+<!--+
+    |breadtrail
+    +-->
+<div class="breadtrail">
+
+             &nbsp;
+           </div>
+<!--+
+    |start Menu, mainarea
+    +-->
+<!--+
+    |start Menu
+    +-->
+<div id="menu">
+<div onclick="SwitchMenu('menu_1.1', 'skin/')" id="menu_1.1Title" class="menutitle">Overview</div>
+<div id="menu_1.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_selected_1.2', 'skin/')" id="menu_selected_1.2Title" class="menutitle" style="background-image: url('skin/images/chapter_open.gif');">Developer</div>
+<div id="menu_selected_1.2" class="selectedmenuitemgroup" style="display: block;">
+<div class="menuitem">
+<a href="api/index.html">API Docs</a>
+</div>
+<div class="menuitem">
+<a href="zookeeperProgrammers.html">Programmer's Guide</a>
+</div>
+<div class="menuitem">
+<a href="javaExample.html">Java Example</a>
+</div>
+<div class="menupage">
+<div class="menupagetitle">Barrier and Queue Tutorial</div>
+</div>
+<div class="menuitem">
+<a href="recipes.html">Recipes</a>
+</div>
+</div>
+<div onclick="SwitchMenu('menu_1.3', 'skin/')" id="menu_1.3Title" class="menutitle">Admin &amp; Ops</div>
+<div id="menu_1.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>
+<div onclick="SwitchMenu('menu_1.4', 'skin/')" id="menu_1.4Title" class="menutitle">Contributor</div>
+<div id="menu_1.4" class="menuitemgroup">
+<div class="menuitem">
+<a href="zookeeperInternals.html">ZooKeeper Internals</a>
+</div>
+</div>
+<div onclick="SwitchMenu('menu_1.5', 'skin/')" id="menu_1.5Title" class="menutitle">Miscellaneous</div>
+<div id="menu_1.5" class="menuitemgroup">
+<div class="menuitem">
+<a href="http://wiki.apache.org/hadoop/ZooKeeper">Wiki</a>
+</div>
+<div class="menuitem">
+<a href="http://wiki.apache.org/hadoop/ZooKeeper/FAQ">FAQ</a>
+</div>
+<div class="menuitem">
+<a href="http://hadoop.apache.org/zookeeper/mailing_lists.html">Mailing Lists</a>
+</div>
+</div>
+<div id="credit"></div>
+<div id="roundbottom">
+<img style="display: none" class="corner" height="15" width="15" alt="" src="skin/images/rc-b-l-15-1body-2menu-3menu.png"></div>
+<!--+
+  |alternative credits
+  +-->
+<div id="credit2"></div>
+</div>
+<!--+
+    |end Menu
+    +-->
+<!--+
+    |start content
+    +-->
+<div id="content">
+<div title="Portable Document Format" class="pdflink">
+<a class="dida" href="zookeeperTutorial.pdf"><img alt="PDF -icon" src="skin/images/pdfdoc.gif" class="skin"><br>
+        PDF</a>
+</div>
+<h1>Programming with ZooKeeper - A basic tutorial</h1>
+<div id="minitoc-area">
+<ul class="minitoc">
+<li>
+<a href="#ch_Introduction">Introduction</a>
+</li>
+<li>
+<a href="#sc_barriers">Barriers</a>
+</li>
+<li>
+<a href="#sc_producerConsumerQueues">Producer-Consumer Queues</a>
+</li>
+<li>
+<a href="#sc_sourceListing">Complete Source Listing</a>
+</li>
+</ul>
+</div>
+  
+
+  
+
+  
+<a name="N10009"></a><a name="ch_Introduction"></a>
+<h2 class="h3">Introduction</h2>
+<div class="section">
+<p>In this tutorial, we show simple implementations of barriers and 
+    producer-consumer queues using ZooKeeper. We call the respective classes Barrier and Queue. 
+    These examples assume that you have at least one ZooKeeper server running.</p>
+<p>Both primitives use the following common excerpt of code:</p>
+<pre class="code">
+    static ZooKeeper zk = null;
+    static Integer mutex;
+
+    String root;
+
+    SyncPrimitive(String address) {
+        if(zk == null){
+            try {
+                System.out.println("Starting ZK:");
+                zk = new ZooKeeper(address, 3000, this);
+                mutex = new Integer(-1);
+                System.out.println("Finished starting ZK: " + zk);
+            } catch (IOException e) {
+                System.out.println(e.toString());
+                zk = null;
+            }
+        }
+        //else mutex = new Integer(-1);
+    }
+
+    synchronized public void process(WatchedEvent event) {
+        synchronized (mutex) {
+            //System.out.println("Process: " + event.getType());
+            mutex.notify();
+        }
+    }
+</pre>
+<p>Both classes extend SyncPrimitive. In this way, we execute steps that are 
+common to all primitives in the constructor of SyncPrimitive. To keep the examples 
+simple, we create a ZooKeeper object the first time we instantiate either a barrier 
+object or a queue object, and we declare a static variable that is a reference 
+to this object. The subsequent instances of Barrier and Queue check whether a 
+ZooKeeper object exists. Alternatively, we could have the application creating a
+ZooKeeper object and passing it to the constructor of Barrier and Queue.</p>
+<p>
+We use the process() method to process notifications triggered due to watches. 
+In the following discussion, we present code that sets watches. A watch is internal 
+structure that enables ZooKeeper to notify a client of a change to a node. For example, 
+if a client is waiting for other clients to leave a barrier, then it can set a watch and 
+wait for modifications to a particular node, which can indicate that it is the end of the wait. 
+This point becomes clear once we go over the examples.
+</p>
+</div>
+   
+ 
+<a name="N1001F"></a><a name="sc_barriers"></a>
+<h2 class="h3">Barriers</h2>
+<div class="section">
+<p>
+ A barrier is a primitive that enables a group of processes to synchronize the 
+ beginning and the end of a computation. The general idea of this implementation 
+ is to have a barrier node that serves the purpose of being a parent for individual 
+ process nodes. Suppose that we call the barrier node "/b1". Each process "p" then 
+ creates a node "/b1/p". Once enough processes have created their corresponding 
+ nodes, joined processes can start the computation.
+ </p>
+<p>In this example, each process instantiates a Barrier object, and its constructor takes as parameters:</p>
+<ul>
+<li>
+<p>the address of a ZooKeeper server (e.g., "zoo1.foo.com:2181")</p>
+</li>
+
+<li>
+<p>the path of the barrier node on ZooKeeper (e.g., "/b1")</p>
+</li>
+
+<li>
+<p>the size of the group of processes</p>
+</li>
+
+</ul>
+<p>The constructor of Barrier passes the address of the Zookeeper server to the 
+constructor of the parent class. The parent class creates a ZooKeeper instance if 
+one does not exist. The constructor of Barrier then creates a 
+barrier node on ZooKeeper, which is the parent node of all process nodes, and 
+we call root (<strong>Note:</strong> This is not the ZooKeeper root "/").</p>
+<pre class="code">
+        /**
+         * Barrier constructor
+         *
+         * @param address
+         * @param root
+         * @param size
+         */
+        Barrier(String address, String root, int size) {
+            super(address);
+            this.root = root;
+            this.size = size;
+
+            // Create barrier node
+            if (zk != null) {
+                try {
+                    Stat s = zk.exists(root, false);
+                    if (s == null) {
+                        zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                                CreateMode.PERSISTENT);
+                    }
+                } catch (KeeperException e) {
+                    System.out
+                            .println("Keeper exception when instantiating queue: "
+                                    + e.toString());
+                } catch (InterruptedException e) {
+                    System.out.println("Interrupted exception");
+                }
+            }
+
+            // My node name
+            try {
+                name = new String(InetAddress.getLocalHost().getCanonicalHostName().toString());
+            } catch (UnknownHostException e) {
+                System.out.println(e.toString());
+            }
+
+        }
+</pre>
+<p>
+To enter the barrier, a process calls enter(). The process creates a node under 
+the root to represent it, using its host name to form the node name. It then wait 
+until enough processes have entered the barrier. A process does it by checking 
+the number of children the root node has with "getChildren()", and waiting for 
+notifications in the case it does not have enough. To receive a notification when 
+there is a change to the root node, a process has to set a watch, and does it 
+through the call to "getChildren()". In the code, we have that "getChildren()" 
+has two parameters. The first one states the node to read from, and the second is
+a boolean flag that enables the process to set a watch. In the code the flag is true.
+</p>
+<pre class="code">
+        /**
+         * Join barrier
+         *
+         * @return
+         * @throws KeeperException
+         * @throws InterruptedException
+         */
+
+        boolean enter() throws KeeperException, InterruptedException{
+            zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.EPHEMERAL_SEQUENTIAL);
+            while (true) {
+                synchronized (mutex) {
+                    List&lt;String&gt; list = zk.getChildren(root, true);
+
+                    if (list.size() &lt; size) {
+                        mutex.wait();
+                    } else {
+                        return true;
+                    }
+                }
+            }
+        }
+</pre>
+<p>
+Note that enter() throws both KeeperException and InterruptedException, so it is 
+the reponsability of the application to catch and handle such exceptions.</p>
+<p>
+Once the computation is finished, a process calls leave() to leave the barrier. 
+First it deletes its corresponding node, and then it gets the children of the root 
+node. If there is at least one child, then it waits for a notification (obs: note 
+that the second parameter of the call to getChildren() is true, meaning that 
+ZooKeeper has to set a watch on the the root node). Upon reception of a notification, 
+it checks once more whether the root node has any child.</p>
+<pre class="code">
+        /**
+         * Wait until all reach barrier
+         *
+         * @return
+         * @throws KeeperException
+         * @throws InterruptedException
+         */
+
+        boolean leave() throws KeeperException, InterruptedException{
+            zk.delete(root + "/" + name, 0);
+            while (true) {
+                synchronized (mutex) {
+                    List&lt;String&gt; list = zk.getChildren(root, true);
+                        if (list.size() &gt; 0) {
+                            mutex.wait();
+                        } else {
+                            return true;
+                        }
+                    }
+                }
+        }
+    }
+</pre>
+</div>
+
+<a name="N10051"></a><a name="sc_producerConsumerQueues"></a>
+<h2 class="h3">Producer-Consumer Queues</h2>
+<div class="section">
+<p>
+A producer-consumer queue is a distributed data estructure thata group of processes 
+use to generate and consume items. Producer processes create new elements and add 
+them to the queue. Consumer processes remove elements from the list, and process them. 
+In this implementation, the elements are simple integers. The queue is represented 
+by a root node, and to add an element to the queue, a producer process creates a new node, 
+a child of the root node.
+</p>
+<p>
+The following excerpt of code corresponds to the constructor of the object. As 
+with Barrier objects, it first calls the constructor of the parent class, SyncPrimitive, 
+that creates a ZooKeeper object if one doesn't exist. It then verifies if the root 
+node of the queue exists, and creates if it doesn't.
+</p>
+<pre class="code">
+        /**
+         * Constructor of producer-consumer queue
+         *
+         * @param address
+         * @param name
+         */
+        Queue(String address, String name) {
+            super(address);
+            this.root = name;
+            // Create ZK node name
+            if (zk != null) {
+                try {
+                    Stat s = zk.exists(root, false);
+                    if (s == null) {
+                        zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                                CreateMode.PERSISTENT);
+                    }
+                } catch (KeeperException e) {
+                    System.out
+                            .println("Keeper exception when instantiating queue: "
+                                    + e.toString());
+                } catch (InterruptedException e) {
+                    System.out.println("Interrupted exception");
+                }
+            }
+        }
+</pre>
+<p>
+A producer process calls "produce()" to add an element to the queue, and passes 
+an integer as an argument. To add an element to the queue, the method creates a 
+new node using "create()", and uses the SEQUENCE flag to instruct ZooKeeper to 
+append the value of the sequencer counter associated to the root node. In this way, 
+we impose a total order on the elements of the queue, thus guaranteeing that the 
+oldest element of the queue is the next one consumed.
+</p>
+<pre class="code">
+        /**
+         * Add element to the queue.
+         *
+         * @param i
+         * @return
+         */
+
+        boolean produce(int i) throws KeeperException, InterruptedException{
+            ByteBuffer b = ByteBuffer.allocate(4);
+            byte[] value;
+
+            // Add child with value i
+            b.putInt(i);
+            value = b.array();
+            zk.create(root + "/element", value, Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT_SEQUENTIAL);
+
+            return true;
+        }
+</pre>
+<p>
+To consume an element, a consumer process obtains the children of the root node, 
+reads the node with smallest counter value, and returns the element. Note that 
+if there is a conflict, then one of the two contending processes won't be able to 
+delete the node and the delete operation will throw an exception.</p>
+<p>
+A call to getChildren() returns the list of children in lexicographic order. 
+As lexicographic order does not necessary follow the numerical order of the counter 
+values, we need to decide which element is the smallest. To decide which one has 
+the smallest counter value, we traverse the list, and remove the prefix "element" 
+from each one.</p>
+<pre class="code">
+        /**
+         * Remove first element from the queue.
+         *
+         * @return
+         * @throws KeeperException
+         * @throws InterruptedException
+         */
+        int consume() throws KeeperException, InterruptedException{
+            int retvalue = -1;
+            Stat stat = null;
+
+            // Get the first element available
+            while (true) {
+                synchronized (mutex) {
+                    List&lt;String&gt; list = zk.getChildren(root, true);
+                    if (list.size() == 0) {
+                        System.out.println("Going to wait");
+                        mutex.wait();
+                    } else {
+                        Integer min = new Integer(list.get(0).substring(7));
+                        for(String s : list){
+                            Integer tempValue = new Integer(s.substring(7));
+                            //System.out.println("Temporary value: " + tempValue);
+                            if(tempValue &lt; min) min = tempValue;
+                        }
+                        System.out.println("Temporary value: " + root + "/element" + min);
+                        byte[] b = zk.getData(root + "/element" + min,
+                                    false, stat);
+                        zk.delete(root + "/element" + min, 0);
+                        ByteBuffer buffer = ByteBuffer.wrap(b);
+                        retvalue = buffer.getInt();
+
+                        return retvalue;
+                    }
+                }
+            }
+        }
+    }
+</pre>
+</div>
+
+<a name="N1006F"></a><a name="sc_sourceListing"></a>
+<h2 class="h3">Complete Source Listing</h2>
+<div class="section">
+<div class="note example">
+<div class="label">SyncPrimitive.Java</div>
+<div class="content">
+
+<title>SyncPrimitive.Java</title>
+
+<pre class="code">
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+
+public class SyncPrimitive implements Watcher {
+
+    static ZooKeeper zk = null;
+    static Integer mutex;
+
+    String root;
+
+    SyncPrimitive(String address) {
+        if(zk == null){
+            try {
+                System.out.println("Starting ZK:");
+                zk = new ZooKeeper(address, 3000, this);
+                mutex = new Integer(-1);
+                System.out.println("Finished starting ZK: " + zk);
+            } catch (IOException e) {
+                System.out.println(e.toString());
+                zk = null;
+            }
+        }
+        //else mutex = new Integer(-1);
+    }
+
+    synchronized public void process(WatchedEvent event) {
+        synchronized (mutex) {
+            //System.out.println("Process: " + event.getType());
+            mutex.notify();
+        }
+    }
+
+    /**
+     * Barrier
+     */
+    static public class Barrier extends SyncPrimitive {
+        int size;
+        String name;
+
+        /**
+         * Barrier constructor
+         *
+         * @param address
+         * @param root
+         * @param size
+         */
+        Barrier(String address, String root, int size) {
+            super(address);
+            this.root = root;
+            this.size = size;
+
+            // Create barrier node
+            if (zk != null) {
+                try {
+                    Stat s = zk.exists(root, false);
+                    if (s == null) {
+                        zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                                CreateMode.PERSISTENT);
+                    }
+                } catch (KeeperException e) {
+                    System.out
+                            .println("Keeper exception when instantiating queue: "
+                                    + e.toString());
+                } catch (InterruptedException e) {
+                    System.out.println("Interrupted exception");
+                }
+            }
+
+            // My node name
+            try {
+                name = new String(InetAddress.getLocalHost().getCanonicalHostName().toString());
+            } catch (UnknownHostException e) {
+                System.out.println(e.toString());
+            }
+
+        }
+
+        /**
+         * Join barrier
+         *
+         * @return
+         * @throws KeeperException
+         * @throws InterruptedException
+         */
+
+        boolean enter() throws KeeperException, InterruptedException{
+            zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.EPHEMERAL_SEQUENTIAL);
+            while (true) {
+                synchronized (mutex) {
+                    List&lt;String&gt; list = zk.getChildren(root, true);
+
+                    if (list.size() &lt; size) {
+                        mutex.wait();
+                    } else {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Wait until all reach barrier
+         *
+         * @return
+         * @throws KeeperException
+         * @throws InterruptedException
+         */
+
+        boolean leave() throws KeeperException, InterruptedException{
+            zk.delete(root + "/" + name, 0);
+            while (true) {
+                synchronized (mutex) {
+                    List&lt;String&gt; list = zk.getChildren(root, true);
+                        if (list.size() &gt; 0) {
+                            mutex.wait();
+                        } else {
+                            return true;
+                        }
+                    }
+                }
+        }
+    }
+
+    /**
+     * Producer-Consumer queue
+     */
+    static public class Queue extends SyncPrimitive {
+
+        /**
+         * Constructor of producer-consumer queue
+         *
+         * @param address
+         * @param name
+         */
+        Queue(String address, String name) {
+            super(address);
+            this.root = name;
+            // Create ZK node name
+            if (zk != null) {
+                try {
+                    Stat s = zk.exists(root, false);
+                    if (s == null) {
+                        zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
+                                CreateMode.PERSISTENT);
+                    }
+                } catch (KeeperException e) {
+                    System.out
+                            .println("Keeper exception when instantiating queue: "
+                                    + e.toString());
+                } catch (InterruptedException e) {
+                    System.out.println("Interrupted exception");
+                }
+            }
+        }
+
+        /**
+         * Add element to the queue.
+         *
+         * @param i
+         * @return
+         */
+
+        boolean produce(int i) throws KeeperException, InterruptedException{
+            ByteBuffer b = ByteBuffer.allocate(4);
+            byte[] value;
+
+            // Add child with value i
+            b.putInt(i);
+            value = b.array();
+            zk.create(root + "/element", value, Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT_SEQUENTIAL);
+
+            return true;
+        }
+
+
+        /**
+         * Remove first element from the queue.
+         *
+         * @return
+         * @throws KeeperException
+         * @throws InterruptedException
+         */
+        int consume() throws KeeperException, InterruptedException{
+            int retvalue = -1;
+            Stat stat = null;
+
+            // Get the first element available
+            while (true) {
+                synchronized (mutex) {
+                    List&lt;String&gt; list = zk.getChildren(root, true);
+                    if (list.size() == 0) {
+                        System.out.println("Going to wait");
+                        mutex.wait();
+                    } else {
+                        Integer min = new Integer(list.get(0).substring(7));
+                        for(String s : list){
+                            Integer tempValue = new Integer(s.substring(7));
+                            //System.out.println("Temporary value: " + tempValue);
+                            if(tempValue &lt; min) min = tempValue;
+                        }
+                        System.out.println("Temporary value: " + root + "/element" + min);
+                        byte[] b = zk.getData(root + "/element" + min,
+                                    false, stat);
+                        zk.delete(root + "/element" + min, 0);
+                        ByteBuffer buffer = ByteBuffer.wrap(b);
+                        retvalue = buffer.getInt();
+
+                        return retvalue;
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(String args[]) {
+        if (args[0].equals("qTest"))
+            queueTest(args);
+        else
+            barrierTest(args);
+
+    }
+
+    public static void queueTest(String args[]) {
+        Queue q = new Queue(args[1], "/app1");
+
+        System.out.println("Input: " + args[1]);
+        int i;
+        Integer max = new Integer(args[2]);
+
+        if (args[3].equals("p")) {
+            System.out.println("Producer");
+            for (i = 0; i &lt; max; i++)
+                try{
+                    q.produce(10 + i);
+                } catch (KeeperException e){
+
+                } catch (InterruptedException e){
+
+                }
+        } else {
+            System.out.println("Consumer");
+
+            for (i = 0; i &lt; max; i++) {
+                try{
+                    int r = q.consume();
+                    System.out.println("Item: " + r);
+                } catch (KeeperException e){
+                    i--;
+                } catch (InterruptedException e){
+
+                }
+            }
+        }
+    }
+
+    public static void barrierTest(String args[]) {
+        Barrier b = new Barrier(args[1], "/b1", new Integer(args[2]));
+        try{
+            boolean flag = b.enter();
+            System.out.println("Entered barrier: " + args[2]);
+            if(!flag) System.out.println("Error when entering the barrier");
+        } catch (KeeperException e){
+
+        } catch (InterruptedException e){
+
+        }
+
+        // Generate random integer
+        Random rand = new Random();
+        int r = rand.nextInt(100);
+        // Loop for rand iterations
+        for (int i = 0; i &lt; r; i++) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+
+            }
+        }
+        try{
+            b.leave();
+        } catch (KeeperException e){
+
+        } catch (InterruptedException e){
+
+        }
+        System.out.println("Left barrier");
+    }
+}
+</pre>
+</div>
+</div>
+</div>
+
+
+<p align="right">
+<font size="-2"></font>
+</p>
+</div>
+<!--+
+    |end content
+    +-->
+<div class="clearboth">&nbsp;</div>
+</div>
+<div id="footer">
+<!--+
+    |start bottomstrip
+    +-->
+<div class="lastmodified">
+<script type="text/javascript"><!--
+document.write("Last Published: " + document.lastModified);
+//  --></script>
+</div>
+<div class="copyright">
+        Copyright &copy;
+         2008 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
+</div>
+<!--+
+    |end bottomstrip
+    +-->
+</div>
+</body>
+</html>


Mime
View raw message