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> > <a href="http://hadoop.apache.org/">Hadoop</a> > <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"> + <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"> + + + </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 & 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 & + 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"> </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 © + 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> > <a href="http://hadoop.apache.org/">Hadoop</a> > <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"> + <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"> + + + </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 & 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<String> list = zk.getChildren(root, true); + + if (list.size() < 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<String> list = zk.getChildren(root, true); + if (list.size() > 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<String> 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 < 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<String> list = zk.getChildren(root, true); + + if (list.size() < 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<String> list = zk.getChildren(root, true); + if (list.size() > 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<String> 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 < 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 < max; i++) + try{ + q.produce(10 + i); + } catch (KeeperException e){ + + } catch (InterruptedException e){ + + } + } else { + System.out.println("Consumer"); + + for (i = 0; i < 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 < 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"> </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 © + 2008 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a> +</div> +<!--+ + |end bottomstrip + +--> +</div> +</body> +</html>