blob: 3cb9acd16b7d3e0b6d33b54fe5feea7934bd4c4e [file] [log] [blame]
<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE- 2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<title>Apache BookKeeper - BookKeeper Getting Started Guide</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<link href="/archives/css/bootstrap.min.css" rel="stylesheet">
<link href="/archives/css/bootstrap-responsive.min.css" rel="stylesheet">
<link href="/archives/css/styles.css" rel="stylesheet">
</head>
<body>
<header class="navbar navbar-inverse navbar-static-top" role="banner">
<div class="container">
<div class="navbar-header hidden-xs hidden-sm">
<a class="navbar-brand navbar-logo" href="/archives/"><img class="img-responsive" src="/archives/img/bookkeeper_blk40.png" alt="Bookkeeper Logo" /></a>
</div>
<div class="navbar-header">
<button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".bs-navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/archives/">Apache BookKeeper</a>
</div>
<nav class="collapse navbar-collapse bs-navbar-collapse" role="navigation">
<ul class="nav navbar-nav">
<li><a href="/archives/releases.html">Download</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Documentation<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="/archives/docs/master">Latest (master)</a></li>
<li><ul>
<li><a href="/archives/docs/master/apidocs">Java API docs</a></li>
<li><a href="/archives/docs/master/bookkeeperTutorial.html">Tutorial</a></li>
<li><a href="/archives/docs/master/bookkeeperConfig.html">Admin guide</a></li>
</ul><li>
<li><a href="/archives/docs/r4.4.0">Release 4.4.0</a></li>
<li class="divider"></li>
<li>Older releases</li>
<li><a href="/archives/docs/r4.3.2">Release 4.3.2</a></li>
<li><a href="/archives/docs/r4.3.1">Release 4.3.1</a></li>
<li><a href="/archives/docs/r4.3.0">Release 4.3.0</a></li>
<li><a href="/archives/docs/r4.2.4">Release 4.2.4</a></li>
<li><a href="/archives/docs/r4.2.3">Release 4.2.3</a></li>
<li><a href="/archives/docs/r4.2.2">Release 4.2.2</a></li>
<li><a href="/archives/docs/r4.2.1">Release 4.2.1</a></li>
<li><a href="/archives/docs/r4.2.0">Release 4.2.0</a></li>
<li><a href="/archives/docs/r4.1.0">Release 4.1.0</a></li>
<li><a href="/archives/docs/r4.0.0">Release 4.0.0</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Get Involved<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="/archives/lists.html">Mailing Lists</a></li>
<li><a href="/archives/irc.html">IRC</a></li>
<li><a href="/archives/svn.html">Version Control</a></li>
<li><a href="https://issues.apache.org/jira/browse/BOOKKEEPER">Issue Tracker</a></li>
</ul>
</li>
<li><a href="https://cwiki.apache.org/confluence/display/BOOKKEEPER/Index">Wiki</a></li>
<!--<li><a href="#">Hedwig</a></li>//-->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Project Info<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="/archives/credits.html">Who are we?</a></li>
<li><a href="/archives/bylaws.html">Bylaws</a></li>
<li><a href="http://www.apache.org/licenses/">License</a></li>
<li class="divider"></li>
<li><a href="/archives/privacy.html">Privacy Policy</a></li>
<li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsership</a></li>
<li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
</ul>
</li>
</ul>
<script>
(function() {
var cx = '017580107654524087317:iqnsyimpydg';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//www.google.com/cse/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
<div class="navbar-form navbar-right visible-lg" id="googlebox">
<gcse:searchbox-only></gcse:searchbox-only>
</div>
</nav>
</div>
</header>
<div class="container">
<h1>Abstract</h1>
<p>This guide contains detailed information about using BookKeeper for write ahead logging. It discusses the basic operations BookKeeper supports, and how to create logs and perform basic read and write operations on these logs. The main classes used by BookKeeper client are <a href="./apidocs/org/apache/bookkeeper/client/BookKeeper.html">BookKeeper</a> and <a href="./apidocs/org/apache/bookkeeper/client/LedgerHandle.html">LedgerHandle</a>. </p>
<p>BookKeeper is the main client used to create, open and delete ledgers. A ledger is a log file in BookKeeper, which contains a sequence of entries. Only the client which creates a ledger can write to it. A LedgerHandle represents the ledger to the client, and allows the client to read and write entries. When the client is finished writing they can close the LedgerHandle. Once a ledger has been closed, all client who read from it are guaranteed to read the exact same entries in the exact same order. All methods of BookKeeper and LedgerHandle have synchronous and asynchronous versions. Internally the synchronous versions are implemented using the asynchronous.</p>
<h1> Instantiating BookKeeper</h1>
<p>To create a BookKeeper client, you need to create a configuration object and set the address of the ZooKeeper ensemble in use. For example, if you were using <code>zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181</code> as your ensemble, you would create the BookKeeper client as follows.</p>
<pre><code>
ClientConfiguration conf = new ClientConfiguration();
conf.setZkServers(&quot;zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181&quot;);
BookKeeper client = new BookKeeper(conf);
</code></pre>
<p>It is important to close the client once you are finished working with it. The set calls on ClientConfiguration are chainable, so instead of putting a set* call on a new line as above, it is possible to make a number of calls on the one line. For example;</p>
<pre><code>
ClientConfiguration conf = new ClientConfiguration().setZkServers(&quot;localhost:2181&quot;).setZkTimeout(5000);
</code></pre>
<p>There is also a useful shortcut constructor which allows you to pass the zookeeper ensemble string directly to BookKeeper.</p>
<pre><code>
BookKeeper client = new BookKeeper(&quot;localhost:2181&quot;);
</code></pre>
<p>See <a href="./apidocs/org/apache/bookkeeper/client/BookKeeper.html">BookKeeper</a> for the full api.</p>
<h1> Creating a ledger</h1>
<p>Before writing entries to BookKeeper, it is necessary to create a ledger. Before creating the ledger you must decide the ensemble size and the quorum size. </p>
<p>The ensemble size is the number of Bookies over which entries will be striped. The quorum size is the number of bookies which an entry will be written to. Striping is done in a round robin fashion. For example, if you have an ensemble size of 3 (consisting of bk1, bk2 &amp; bk3), and a quorum of 2, entry 1 will be written to bk1 &amp; bk2, entry 2 will be written to bk2 &amp; bk3, entry 3 will be written to bk3 &amp; bk1 and so on.</p>
<p>Ledgers are also created with a digest type and password. The digest type is used to generate a checksum so that when reading entries we can ensure that the content is the same as what was written. The password is used as an access control mechanism.</p>
<p>To create a ledger, with ensemble size 3, quorum size 2, using a <span class="caps">CRC </span>to checksum and "foobar" as the password, do the following:</p>
<pre><code>
LedgerHandle lh = client.createLedger(3, 2, DigestType.CRC32, &quot;foobar&quot;);
</code></pre>
<p>You can now write to this ledger handle. As you probably plan to read the ledger at some stage, now is a good time to store the id of the ledger somewhere. The ledger id is a long, and can be obtained with <code>lh.getId()</code>.</p>
<h1> Adding entries to a ledger</h1>
<p>Once you have obtained a ledger handle, you can start adding entries to it. Entries are simply arrays of bytes. As such, adding entries to the ledger is rather simple.</p>
<pre><code>
lh.addEntry(&quot;Hello World!&quot;.getBytes());
</code></pre>
<h1> Closing a ledger</h1>
<p>Once a client is done writing, it can closes the ledger. Closing the ledger is a very important step in BookKeeper, as once a ledger is closed, all reading clients are guaranteed to read the same sequence of entries in the same order. Closing takes no parameters. </p>
<pre><code>
lh.close();
</code></pre>
<h1> Opening a ledger</h1>
<p>To read from a ledger, a client must open it first. To open a ledger you must know its <span class="caps">ID, </span>which digest type was used when creating it, and its password. To open the ledger we created above, assuming it has ID 1;</p>
<pre><code>
LedgerHandle lh2 = client.openLedger(1, DigestType.CRC32, &quot;foobar&quot;);
</code></pre>
<p>You can now read entries from the ledger. Any attempt to write to this handle will throw an exception.</p>
<blockquote><p><span class="caps">NOTE</span>: Opening a ledger, which another client already has open for writing will prevent that client from writing any new entries to it. If you do not wish this to happen, you should use the openLedgerNoRecovery method. However, keep in mind that without recovery, you lose the guarantees of what entries are in the ledger. You should only use openLedgerNoRecovery if you know what you are doing.</p></blockquote>
<h1>Reading entries from a ledger</h1>
<p>Now that you have an open ledger, you can read entries from it. You can use <code>getLastAddConfirmed</code> to get the id of the last entry in the ledger.</p>
<pre><code>
long lastEntry = lh2.getLastAddConfirmed();
Enumeration&lt;LedgerEntry&gt; entries = lh2.readEntries(0, 9);
while (entries.hasMoreElements()) {
byte[] bytes = entries.nextElement().getEntry();
System.out.println(new String(bytes));
}
</code></pre>
</div>
<footer class="footer">
<div class="container">
<p class="text-muted">Copyright &copy; 2014 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.<br/>
Apache BookKeeper, BookKeeper, Apache, Apache ZooKeeper, ZooKeeper, the Apache feather logo, and the Apache BookKeeper project logo are trademarks of The Apache Software Foundation.</p>
</div>
</footer>
<script src="//code.jquery.com/jquery.js"></script>
<script src="/archives/js/bootstrap.min.js"></script>
</body>
</html>