<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Streamy Development Blog</title>
	<atom:link href="http://devblog.streamy.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://devblog.streamy.com</link>
	<description></description>
	<pubDate>Sat, 19 Sep 2009 00:53:24 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<atom:link rel="hub" href="http://pubsubhubbub.appspot.com" />
			<item>
		<title>CAP Theorem</title>
		<link>http://devblog.streamy.com/2009/08/24/cap-theorem/</link>
		<comments>http://devblog.streamy.com/2009/08/24/cap-theorem/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 21:33:16 +0000</pubDate>
		<dc:creator>Jonathan Gray</dc:creator>
		
		<category><![CDATA[Distributed Systems]]></category>

		<category><![CDATA[Web Scale]]></category>

		<category><![CDATA[amazon]]></category>

		<category><![CDATA[availability]]></category>

		<category><![CDATA[bigtable]]></category>

		<category><![CDATA[brewer]]></category>

		<category><![CDATA[CAP]]></category>

		<category><![CDATA[CAP Theorem]]></category>

		<category><![CDATA[cassandra]]></category>

		<category><![CDATA[consistency]]></category>

		<category><![CDATA[distribution]]></category>

		<category><![CDATA[dynamo]]></category>

		<category><![CDATA[eventual consistency]]></category>

		<category><![CDATA[gfs]]></category>

		<category><![CDATA[google]]></category>

		<category><![CDATA[hbase]]></category>

		<category><![CDATA[nosql]]></category>

		<category><![CDATA[partition tolerance]]></category>

		<category><![CDATA[partitions]]></category>

		<category><![CDATA[Streamy]]></category>

		<guid isPermaLink="false">http://devblog.streamy.com/?p=51</guid>
		<description><![CDATA[If you&#8217;re talking or thinking about distributed data systems these days, you are almost certain to come across some discussion of the CAP theorem.  This is one of those beautifully simplistic ideas that helps explain something extraordinarily complex.
So, what does it mean?
CAP stands for Consistency, Availability, and Partition tolerance.  The theorem simply states that any [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re talking or thinking about distributed data systems these days, you are almost certain to come across some discussion of the <em>CAP theorem</em>.  This is one of those beautifully simplistic ideas that helps explain something extraordinarily complex.</p>
<h4>So, what does it mean?</h4>
<p>CAP stands for <strong>C</strong>onsistency, <strong>A</strong>vailability, and <strong>P</strong>artition tolerance.  The theorem simply states that any shared-data system <em>can only achieve two of these three</em>.</p>
<p><em><strong>Consistency<br />
</strong></em></p>
<p><a href="http://en.wikipedia.org/wiki/Database_consistency" target="_blank">Consistency</a> describes how and whether a system is left in a consistent state after an operation. In a distributed data system, this usually means that once a writer has written, all readers will see that write.</p>
<p>A distributed data system is either strongly consistent or has some form of weak consistency.  The most well known example of strong consistency in databases is <strong>ACID</strong> (Atomicity Consistency Isolation Durability), used in most <a href="http://en.wikipedia.org/wiki/RDBMS" target="_blank">relational databases</a>.  On the other end of the spectrum is <strong>BASE</strong> (Basically Available Soft-state Eventual consistency).</p>
<p>Most often, weak consistency comes in the form of eventual consistency which means the database <em>eventually</em> reaches a consistent state.  Weak consistency systems are usually ones where data is replicated; the latest version of something is sitting on some node in the cluster, but older versions are still out there on other nodes, but eventually all nodes will see the latest version.</p>
<p>If you are interested in learning more, Werner Vogels, CTO of Amazon, has two good blog posts on eventual consistency <a href="http://www.allthingsdistributed.com/2007/12/eventually_consistent.html" target="_blank">here</a> and <a href="http://www.allthingsdistributed.com/2008/12/eventually_consistent.html" target="_blank">here</a>.</p>
<p><em><strong>Availability</strong></em></p>
<p><a href="http://en.wikipedia.org/wiki/High_availability" target="_blank">High-Availability</a> refers to the design and implementation of a system such that it is ensured to remain operational over some period of time.</p>
<p>In this context, it generally means a system that is tolerant of node failures and can also remain available during software and hardware upgrades.  This is perhaps the simplest to understand and most commonly desired property, yet can be quite difficult to achieve to any level of certainty.</p>
<p><em><strong>Partition Tolerance</strong></em></p>
<p>Partition tolerance refers to the ability for a system to continue to operate in the presence of a network partitions.  For example, if I have a database running on 80 nodes across 2 racks and the interconnect between the racks is lost, my database is now partitioned.  If the system is tolerant of it, then the database will still be able to perform read and write operations while partitioned.  If not, often times the cluster is completely unusable or is read-only.</p>
<h4>Who came up with it?</h4>
<p>In July 2000, Dr. Eric Brewer of Berkeley gave a talk, <a href="http://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf" target="_blank">Toward Robust Distributed Systems</a>.</p>
<p>In it, he talks about the many trade-offs between ACID and BASE systems.  He explains that it should be thought of not as one or the other, but rather as a continuous spectrum.  As a useful principle, he then introduced the CAP Theorem.</p>
<h4>Why now?</h4>
<p>Distributed data systems are increasingly becoming a hot area of research and development.  Before the Internet and the web, there were not many companies dealing with terabyte or petabyte datasets.  With the explosion of content and information from websites, blogs, and social networks, more and more businesses are now trying to store, analyze, and serve massive amounts of data.  And they need to be able to perform massive batch operations on it while also serving it up to clients in near real-time.</p>
<p>These companies each have their own requirements: performance, reliability, durability; ACID, BASE, or somewhere in between.</p>
<h4>Real World Example</h4>
<p>In November 2006, Google released a paper, <a href="http://labs.google.com/papers/bigtable.html" target="_blank">BigTable: A Distributed Storage System for Structured Data</a> describing a distributed, column-oriented database that sat on top of the distributed <a href="http://labs.google.com/papers/gfs.html" target="_blank">Google File System</a>.</p>
<p>In October 2007, Amazon released their own paper, <a href="http://s3.amazonaws.com/AllThingsDistributed/sosp/amazon-dynamo-sosp2007.pdf" target="_blank">Dynamo: Amazon&#8217;s highly available Key-value Store</a> describing a distributed key-value database designed and in-use at Amazon.</p>
<p>What makes these two products a great example is that they are modern designs and implementations of distributed, shared data systems <em><strong>but with two different philosophies regarding CAP</strong></em>.</p>
<p><span style="text-decoration: underline">BigTable is a CA system</span>; it is strongly consistent and highly available, but can be unavailable under network partitions.  BigTable has no replication at the database level, rather replication is handled underneath by GFS.</p>
<p><span style="text-decoration: underline">Dynamo is an AP system</span>; it is highly available, even under network partitions, but eventually consistent.  Data is replicated within a single cluster, so even under partitions most data is available, however one node&#8217;s latest version might not match that of another, so every reader is only guaranteed to see every write <em>eventually</em>.</p>
<h4>CAP at Streamy</h4>
<p>First and foremost, <a href="http://www.streamy.com" target="_blank">Streamy</a> is backed by <a href="http://hbase.org" target="_blank">HBase</a>, an open-source implementation of Google&#8217;s BigTable.  As such, the core of our database systems are strongly consistent and highly available.  We are not overly concerned with network partitions as our clusters are all within a single data center and connected via local gigabit switches.  Once we expand to additional data centers, we plan to employ inter-cluster replication, with each cluster located in a single DC.  Remote replication will introduce some eventual consistency into the system, but each cluster will continue to be strongly consistent.</p>
<p>In addition to HBase, we also have a number of additional data systems that are responsible for indexing, sorting, merging, aggregating, and joining our data.  Some of these systems could be considered distributed or replicated, meaning there are multiple instances on multiple nodes and they talk to each other.  Since none are actually persistent (we do not rely on their state or their ability to save data under faults, that&#8217;s what HBase is for), we are most heavily focused on high availability and ensuring a read-your-writes consistency (a special form of eventual consistency).</p>
<p>Without going into more detail, it can be said that we employ both CA and AP systems here at Streamy.  The focus is not on fundamentally which is &#8220;better&#8221; but rather what the requirements are for that particular application and what the expectation is for our users.  The most important thing to avoid is a user who performs an action but then is unable to see that action immediately, which is why we often enforce a read-your-write consistency when we do need to relax our constraints.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/08/24/cap-theorem/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HUG7: HBase User Group Wrap-Up</title>
		<link>http://devblog.streamy.com/2009/08/11/hug7-hbase-user-group-wrap-up/</link>
		<comments>http://devblog.streamy.com/2009/08/11/hug7-hbase-user-group-wrap-up/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 23:37:06 +0000</pubDate>
		<dc:creator>Jonathan Gray</dc:creator>
		
		<category><![CDATA[Hadoop/HBase]]></category>

		<category><![CDATA[Meetup]]></category>

		<category><![CDATA[Presentations]]></category>

		<category><![CDATA[djryan]]></category>

		<category><![CDATA[hbase]]></category>

		<category><![CDATA[hug]]></category>

		<category><![CDATA[jgray]]></category>

		<category><![CDATA[mrbradford]]></category>

		<category><![CDATA[san francisco]]></category>

		<category><![CDATA[stack]]></category>

		<category><![CDATA[stumbleupon]]></category>

		<category><![CDATA[user group]]></category>

		<guid isPermaLink="false">http://devblog.streamy.com/?p=227</guid>
		<description><![CDATA[The biggest ever HBase User Group went off this past Friday, August 7 at StumbleUpon HQ in San Francisco.  We had over 30 attendees, ranging from new users to committers, and four presentations.  Big thanks to everyone for coming out, and especially to StumbleUpon for hosting us.
Jonathan Gray (me) covered the new features, architecture, [...]]]></description>
			<content:encoded><![CDATA[<p>The biggest ever <a href="http://hbase.org" target="_blank">HBase</a> <a href="http://www.meetup.com/hbaseusergroup/" target="_blank">User Group</a> went off this past Friday, August 7 at <a href="http://stumbleupon.com" target="_blank">StumbleUpon</a> HQ in San Francisco.  We had over 30 attendees, ranging from new users to committers, and four presentations.  Big thanks to everyone for coming out, and especially to StumbleUpon for hosting us.</p>
<p><a href="http://twitter.com/jgrayla" target="_blank">Jonathan Gray</a> (me) covered the new features, architecture, and API of the latest HBase 0.20 release, <a href="http://twitter.com/saintstack" target="_blank">Michael Stack</a> introduced the proposed features for 0.21, <a href="http://twitter.com/ryanobjc" target="_blank">Ryan Rawson</a> led a great practical discussion from his experiences using HBase at StumbleUpon, and finally <a href="http://twitter.com/lusciouspear" target="_blank">Bradford Stephens</a> gave an interesting talk on building an analytics framework atop Hadoop and HBase.</p>
<p>To read about what&#8217;s planned for the next release of HBase, 0.21, check out the <a href="http://wiki.apache.org/hadoop/HBase/RoadMaps" target="_blank">HBase 0.21 Roadmap</a>, notes from the <a href="http://devblog.streamy.com/2009/08/09/hbase-hackathon-2-day-one/" target="_blank">HBase Hackathon Day One Wrap-Up</a>, or <a href="https://issues.apache.org/jira/secure/IssueNavigator.jspa?fixfor=12313607" target="_blank">issues in JIRA</a>.</p>
<p><span style="text-decoration: underline"><strong>HBase 0.20 Introduction</strong></span></p>
<p><object width="450" height="400" data="http://viewer.docstoc.com/" type="application/x-shockwave-flash"><param name="id" value="_ds_9686721" /><param name="name" value="_ds_9686721" /><param name="FlashVars" value="doc_id=9686721&amp;mem_id=381319&amp;doc_type=ppt&amp;fullscreen=0" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><param name="src" value="http://viewer.docstoc.com/" /></object></p>
<p><span style="color: #ffffff">-</span></p>
<p><span style="text-decoration: underline"><strong>Practical HBase at StumbleUpon</strong></span></p>
<p><object width="450" height="400" data="http://viewer.docstoc.com/" type="application/x-shockwave-flash"><param name="id" value="_ds_9690019" /><param name="name" value="_ds_9690019" /><param name="FlashVars" value="doc_id=9690019&amp;mem_id=1165499&amp;doc_type=ppt&amp;fullscreen=0" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><param name="src" value="http://viewer.docstoc.com/" /></object></p>
<p><span style="color: #ffffff">-</span></p>
<p><span style="text-decoration: underline"><strong>Hadoop Analytics - A DB for 80% of Big Data sites</strong></span></p>
<div id="__ss_1845207" style="width: 425px;text-align: left"><object width="425" height="355" data="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=hadoopanalytics-090811140138-phpapp02&amp;rel=0&amp;stripped_title=hadoop-analytics-a-db-for-80-of-big-data-sites" type="application/x-shockwave-flash"><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=hadoopanalytics-090811140138-phpapp02&amp;rel=0&amp;stripped_title=hadoop-analytics-a-db-for-80-of-big-data-sites" /></object></div>
<div style="width: 425px;text-align: left"><span style="color: #ffffff">-</span></div>
<div style="width: 425px;text-align: left"><span style="color: #ffffff">-</span></div>
<div style="width: 425px;text-align: left"><span style="color: #ffffff">-</span></div>
<p><em><strong>JG</strong></em></p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/08/11/hug7-hbase-user-group-wrap-up/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HBase Hackathon 2 Wrap-Up: Day One</title>
		<link>http://devblog.streamy.com/2009/08/09/hbase-hackathon-2-day-one/</link>
		<comments>http://devblog.streamy.com/2009/08/09/hbase-hackathon-2-day-one/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 02:46:52 +0000</pubDate>
		<dc:creator>Jonathan Gray</dc:creator>
		
		<category><![CDATA[Hadoop/HBase]]></category>

		<category><![CDATA[Meetup]]></category>

		<guid isPermaLink="false">http://devblog.streamy.com/?p=205</guid>
		<description><![CDATA[The second HBase Hackathon took place this weekend at the StumbleUpon headquarters in San Francisco.  Big thanks to them for hosting us and feeding us.
The primary goal of this Hackathon was to roadmap, design, and hack on new features for the next release of HBase, 0.21.  The major targets are a Master rewrite, expanded use [...]]]></description>
			<content:encoded><![CDATA[<p>The second <a href="http://hadoop.apache.org/hbase" target="_blank">HBase</a> <a href="http://www.meetup.com/hackathon/" target="_blank">Hackathon</a> took place this weekend at the <a href="http://www.stumbleupon.com" target="_blank">StumbleUpon</a> headquarters in San Francisco.  Big thanks to them for hosting us and feeding us.</p>
<p>The primary goal of this Hackathon was to roadmap, design, and hack on new features for the next release of HBase, 0.21.  The major targets are a Master rewrite, expanded use of Zookeeper, and cross-cluster replication.</p>
<p>Here are notes from Day One:</p>
<p><!--[if gte mso 9]&gt;  Normal.dotm 0 0 1 250 1430 Streamy Inc. 11 2 1756 12.0     &lt;![endif]--><!--[if gte mso 9]&gt;  0 false   18 pt 18 pt 0 0  false false false        &lt;![endif]--><!--[if gte mso 9]&gt;   &lt;![endif]--> <!--  /* Font Definitions */ @font-face 	{font-family:"Courier New"; 	panose-1:2 7 3 9 2 2 5 2 4 4; 	mso-font-charset:0; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 0 0 0 1 0;} @font-face 	{font-family:Wingdings; 	panose-1:5 2 1 2 1 8 4 8 7 8; 	mso-font-charset:2; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:0 0 65536 0 -2147483648 0;} @font-face 	{font-family:Cambria; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:0; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 0 0 0 1 0;}  /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin-top:0in; 	margin-right:0in; 	margin-bottom:10.0pt; 	margin-left:0in; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-ascii-font-family:Cambria; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:Cambria; 	mso-fareast-theme-font:minor-latin; 	mso-hansi-font-family:Cambria; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph 	{margin-top:0in; 	margin-right:0in; 	margin-bottom:10.0pt; 	margin-left:.5in; 	mso-add-space:auto; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-ascii-font-family:Cambria; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:Cambria; 	mso-fareast-theme-font:minor-latin; 	mso-hansi-font-family:Cambria; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParagraphCxSpFirst 	{mso-style-type:export-only; 	margin-top:0in; 	margin-right:0in; 	margin-bottom:0in; 	margin-left:.5in; 	margin-bottom:.0001pt; 	mso-add-space:auto; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-ascii-font-family:Cambria; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:Cambria; 	mso-fareast-theme-font:minor-latin; 	mso-hansi-font-family:Cambria; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListParagraphCxSpMiddle 	{mso-style-type:export-only; 	margin-top:0in; 	margin-right:0in; 	margin-bottom:0in; 	margin-left:.5in; 	margin-bottom:.0001pt; 	mso-add-space:auto; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-ascii-font-family:Cambria; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:Cambria; 	mso-fareast-theme-font:minor-latin; 	mso-hansi-font-family:Cambria; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagraphCxSpLast 	{mso-style-type:export-only; 	margin-top:0in; 	margin-right:0in; 	margin-bottom:10.0pt; 	margin-left:.5in; 	mso-add-space:auto; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-ascii-font-family:Cambria; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:Cambria; 	mso-fareast-theme-font:minor-latin; 	mso-hansi-font-family:Cambria; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} @page Section1 	{size:8.5in 11.0in; 	margin:1.0in 1.25in 1.0in 1.25in; 	mso-header-margin:.5in; 	mso-footer-margin:.5in; 	mso-paper-source:0;} div.Section1 	{page:Section1;}  /* List Definitions */ @list l0 	{mso-list-id:1080908532; 	mso-list-type:hybrid; 	mso-list-template-ids:-34330262 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l0:level1 	{mso-level-number-format:bullet; 	mso-level-text:; 	mso-level-tab-stop:none; 	mso-level-number-position:left; 	text-indent:-.25in; 	font-family:Symbol;} @list l0:level2 	{mso-level-number-format:bullet; 	mso-level-text:o; 	mso-level-tab-stop:none; 	mso-level-number-position:left; 	text-indent:-.25in; 	font-family:"Courier New";} @list l0:level3 	{mso-level-number-format:bullet; 	mso-level-text:; 	mso-level-tab-stop:none; 	mso-level-number-position:left; 	text-indent:-.25in; 	font-family:Wingdings;} @list l0:level4 	{mso-level-number-format:bullet; 	mso-level-text:; 	mso-level-tab-stop:none; 	mso-level-number-position:left; 	text-indent:-.25in; 	font-family:Symbol;} @list l0:level5 	{mso-level-number-format:bullet; 	mso-level-text:o; 	mso-level-tab-stop:none; 	mso-level-number-position:left; 	text-indent:-.25in; 	font-family:"Courier New";} ol 	{margin-bottom:0in;} ul 	{margin-bottom:0in;} --> <!--[if gte mso 10]&gt; &lt;!   /* Style Definitions */ table.MsoNormalTable 	{mso-style-name:"Table Normal"; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0in 5.4pt 0in 5.4pt; 	mso-para-margin-top:0in; 	mso-para-margin-right:0in; 	mso-para-margin-bottom:10.0pt; 	mso-para-margin-left:0in; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-ascii-font-family:Cambria; 	mso-ascii-theme-font:minor-latin; 	mso-hansi-font-family:Cambria; 	mso-hansi-theme-font:minor-latin;} --> <!--[endif]--> <!--StartFragment--></p>
<p class="MsoNormal" style="margin-bottom: 0.0001pt"><strong>HBase Hackathon Notes</strong></p>
<p class="MsoNormal" style="margin-bottom: 0.0001pt"><em>Saturday, August 8, 2009</em></p>
<p class="MsoNormal" style="margin-bottom: 0.0001pt"><em><span style="color: #ffffff">-</span><br />
</em></p>
<p class="MsoListParagraphCxSpFirst" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol"> ·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Data Integrity</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->WAL</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]--><a href="http://issues.apache.org/jira/browse/HDFS-200" target="_blank">HADOOP-4379/HDFS-200</a> needs testing on large clusters</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->HBfsck (<a href="http://issues.apache.org/jira/browse/HBASE-7" target="_blank">HBASE-7</a>)</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Sequence IDs</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 2in"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Change to stamps?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 2in"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Must be unique</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 2in"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Fix for merges</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Start/end keys match</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 2in"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Figures out / runs merges</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Repair references</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Two modes</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 2in"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Quick mode scans META</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 2in"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Full mode reads HFiles and verifies fully</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 2in"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 2in">
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol"> ·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Master Rewrite (<a href="https://issues.apache.org/jira/browse/HBASE-1110" target="_blank">HBASE-1110</a>)</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->HCD + HTD</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Schema -&gt; JSON</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Stored in ZK</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->JNI ZK Client – Nitay</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Fix ZK being a black box</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Not kicked out from GC pauses</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Only responsible for ephemeral, other stuff still Java API</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Monitor existence of JVM RS process</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Master is “powerless”</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Should be written as though its ok we are offline for minutes</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Region assignment to ZK</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Consensus to definitely do this</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Master verify assignment state periodically?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->META information in ZK? (<a href="https://issues.apache.org/jira/browse/HBASE-1755" target="_blank">HBASE-1755</a>)</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Replacement for <strong>getClosestRowBefore</strong></p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->/hbase/TABLE/region</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Goal: 10k regions * 10k clients</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Load balancing</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->RS publish load statistics to ZK</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Master makes all decisions</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Zookeeper coordination</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Get rid of heartbeats (<a href="https://issues.apache.org/jira/browse/HBASE-1502" target="_blank">HBASE-1502</a>)</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Master uses RPC?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Zookeeper coordination / messaging instead?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Gets -&gt; Scan</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Timestamp collisions, known issues here (<a href="https://issues.apache.org/jira/browse/HBASE-1485" target="_blank">HBASE-1485</a>)</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Bloom filters?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Replication (<a href="https://issues.apache.org/jira/browse/HBASE-1295" target="_blank">HBASE-1295</a>)</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Sharded counters possible?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Log shipping initially</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Separate process alongside HRS</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Who does he talk to on the other cluster?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Coordination with shared ZK?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->When network partition</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Buffer in memory, then buffer on hdfs</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 2in"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->How big can it get? Hours, days, years?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Eventually must fall back on snapshot or full table replay?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Snapshot Backup Mechanism</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Flush, stop compactions</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Local copy first</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Should be per table</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Utilize distcp</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Can be used to initialize a slave replicated cluster</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->New RPC</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Punted to 0.22</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Unit test speedup (<a href="https://issues.apache.org/jira/browse/HBASE-1556" target="_blank">HBASE-1556</a>)</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span>HTableInterface, HRSInterface, HRInterface, etc</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Assigned to: Stack</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->New UI</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Punt with redirect</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->JG building something that taps into ZK and can publish JSON/XML/etc</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><!--[if !supportLists]--><span style="font-family: Wingdings">§<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Used for nagios plugin also being built</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1.5in"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Behind API Upload Process</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Patch exists, need to test <a href="https://issues.apache.org/jira/browse/HBASE-48" target="_blank">HBASE-48<br />
</a></p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Does not currently support multi-family or importing into table with data</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Cascading</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpLast" style="margin-bottom: 0.0001pt;padding-left: 30px"><!--[if !supportLists]--><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Distributed log splitting (<a href="https://issues.apache.org/jira/browse/HBASE-1364" target="_blank">HBASE-1364</a>)</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Stripped down version of MR?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span>Use ZK to map each HLog to which regions it contains edits for?</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><!--[if !supportLists]--><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span>We want to open any regions during a recovery that do not have edits immediately</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><a href="https://issues.apache.org/jira/browse/HBASE-48" target="_blank"></a></p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->JD leading on the design</p>
<p class="MsoListParagraphCxSpLast" style="margin-bottom: 0.0001pt;padding-left: 90px"><!--[endif]--></p>
<p><!--EndFragment--></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt"><em><span style="color: #ffffff">-</span></em></p>
<p class="MsoListParagraphCxSpLast" style="margin-bottom: 0.0001pt;padding-left: 30px"><span style="font-family: Symbol">·<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->Intra-row Scanning (<a href="https://issues.apache.org/jira/browse/HBASE-1537" target="_blank">HBASE-1537</a>)</p>
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in">
<p class="MsoListParagraphCxSpMiddle" style="margin: 0in 0in 0.0001pt 1in"><span style="font-family: &quot;Courier New&amp;quot">o<span style="font-family: &quot;Times New Roman&quot;font-style: normal;font-variant: normal;font-weight: normal;font-size: 7pt"> </span></span><!--[endif]-->We need it, but it&#8217;s hard <img src='http://devblog.streamy.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p class="MsoListParagraphCxSpMiddle" style="margin-bottom: 0.0001pt"><em><span style="color: #ffffff">-</span></em></p>
<p><!--EndFragment--></p>
<p>Thanks again to everyone at StumbleUpon and to all the committers and contributors for the good ideas and the good times!</p>
<p><strong><em>JG</em></strong></p>
<p><!--EndFragment--></p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/08/09/hbase-hackathon-2-day-one/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HOWTO: Determine the size of a Java Object or Class</title>
		<link>http://devblog.streamy.com/2009/07/24/determine-size-of-java-object-class/</link>
		<comments>http://devblog.streamy.com/2009/07/24/determine-size-of-java-object-class/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 23:19:10 +0000</pubDate>
		<dc:creator>Erik Holstad</dc:creator>
		
		<category><![CDATA[Tips and Tricks]]></category>

		<category><![CDATA[Class]]></category>

		<category><![CDATA[heap]]></category>

		<category><![CDATA[howto]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[memory]]></category>

		<category><![CDATA[Object]]></category>

		<category><![CDATA[size]]></category>

		<category><![CDATA[sizeof]]></category>

		<guid isPermaLink="false">http://devblog.streamy.com/?p=194</guid>
		<description><![CDATA[Finding out the size (memory/heap usage) of Java Objects and Classes can be somewhat tricky as there is no built-in sizeof()-like functionality.  Luckily most people don&#8217;t have to face this problem.  But when you do, it can be difficult and in the end is almost always a best-guess approximation.
The reason that I started to look [...]]]></description>
			<content:encoded><![CDATA[<p>Finding out the size (memory/heap usage) of Java Objects and Classes can be somewhat tricky as there is no built-in sizeof()-like functionality.  Luckily most people don&#8217;t have to face this problem.  But when you do, it can be difficult and in the end is almost always a best-guess approximation.</p>
<p>The reason that I started to look in to this subject was to build a memory-aware, <a href="http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used" target="_blank">LRU</a> eviction cache for the open source database project <a href="http://hbase.org" target="_blank">HBase</a>.  You can see the final result of that effort <a href="http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/io/hfile/LruBlockCache.java?view=co" target="_blank">here</a>.</p>
<p>When sizing a Class you can take two approaches.  One is to use the methods totalMemory and freeMemory from the Java <a href="http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html" target="_blank">Runtime</a> class. The other strategy is to analyze the internal structure of your Class.  The first approach has the benefit that it gives you the actual memory footprint of your object rather than the expected one, but has the downside of relying on the garbage collector to do it&#8217;s thing.  So for this to work you often have to make repeated calls to the GC and sleep in between to give it time to process and minimize heap usage.  As one can see, this is not a solution suitable to be used in real time system, but can be a solid solution that you go back to when everything else fails, or just to verify your findings.</p>
<p>The second way of sizing your Class is to dissect it into it&#8217;s fundamental building blocks.  Let&#8217;s start by introducing the notion of a <em>reference</em>, known in other languages as a pointer.  A <a href="http://en.wikipedia.org/wiki/Reference_(computer_science)" target="_blank">reference</a>, or REF for short, is 4 bytes on a 32 bit system and 8 bytes on a 64 bit system.  Also note, the total size of an Object will always be word-aligned (4 byte aligned on 32bit, 8 byte aligned on 64bit).</p>
<p>Every instantiated Object in Java has a fixed overhead of 2 REFs.  To that, you add the contributions from all the non-static variables/fields contained within the Object.  For the most basic primitives, these sizes are:</p>
<p><strong>byte = 1 byte, int = 4 bytes, long = 8 bytes</strong></p>
<p>For example, let&#8217;s define and size the Class <em>PrimitiveContainer<br />
</em></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> PrimitiveContainer <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">long</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The calculation for this would be:</p>
<p>overhead + sizeof(int) + sizeof(long) = <strong>(2 * REF)</strong> <strong>+ 4</strong> +<strong> 8</strong> = 28 bytes on 64-bit, after word-alignment we get <span style="text-decoration: underline"><strong>32 bytes</strong></span></p>
<p>Another example that uses Objects instead of primitives:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ObjectContainer <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Integer</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Long</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Since this Object contains references to other Objects (not primitives), we will calculate and include both the size of the referenced Objects (Integer and Long) as well as the references to those Objects (in ObjectContainer).  Both Integer and Long will have the fixed Object overhead of <strong>2 * REF</strong> in addition to either an int or long primitive in each.  So:</p>
<p>sizeof(Integer) = <strong>(2 * REF) + 4</strong> = <strong>20</strong><br />
sizeof(Long) = <strong>(2 * REF) + 8</strong> = <strong>24</strong></p>
<p>The total calculation would be:</p>
<p>overhead + reference to Integer + sizeof(Integer) + reference to Long + sizeof(Long) = <strong>(2 * REF)</strong> + <strong>(REF + 20)</strong> + <strong>(REF + 24)</strong> = <span style="text-decoration: underline"><strong>80 bytes</strong></span></p>
<p>As you can see that there is a significant increase in memory usage between using primitives when compared to their Object counterparts, in this case 2.5X larger.</p>
<p>Arrays in Java, though underneath are really Objects, are unlike other complex Classes (Lists, Maps, etc) because they can be used with primtives directly.  Through experimentation and instrumentation of the JVM, the fixed overhead of any array is <strong>3 * REF</strong>.</p>
<p>So with this in mind you can treat it as a regular object that aligns with it&#8217;s daughter objects.</p>
<p>For example if you have:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bs <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">3</span>,<span style="color: #cc66cc;">4</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>on a 32 bit system, you get a total size of : <strong>3 * REF + 4 = 3 * 4 + 4 = 16 bytes<br />
</strong>on a 64 bit system, you get a total size of:  <strong>3 * REF + 4 = 3 * 8 + 4 = </strong>28 which aligns to <strong>32 bytes</strong> (twice the memory usage in this case)</p>
<p>One more thing that is worth mentioning is the cost for static and final variables. Usually static variables are not taken into consideration when sizing you object, since this is only done once and not for each instantiated Object.  Final variables should almost always be included, but of course it depends on your use case and the reason that you are sizing your objects.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/07/24/determine-size-of-java-object-class/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Streamy @ Hadoop Summit: HBase Goes Realtime</title>
		<link>http://devblog.streamy.com/2009/07/24/streamy-hadoop-summit-hbase-goes-realtime/</link>
		<comments>http://devblog.streamy.com/2009/07/24/streamy-hadoop-summit-hbase-goes-realtime/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 18:13:59 +0000</pubDate>
		<dc:creator>Jonathan Gray</dc:creator>
		
		<category><![CDATA[Hadoop/HBase]]></category>

		<category><![CDATA[Meetup]]></category>

		<category><![CDATA[Presentations]]></category>

		<category><![CDATA[Video]]></category>

		<category><![CDATA[hadoop]]></category>

		<category><![CDATA[hadoop summit]]></category>

		<category><![CDATA[hbase]]></category>

		<category><![CDATA[realtime]]></category>

		<category><![CDATA[Streamy]]></category>

		<guid isPermaLink="false">http://devblog.streamy.com/?p=173</guid>
		<description><![CDATA[The Hadoop Summit was a great success this year and I had a ton of fun giving the presentation on HBase in front of a standing-room-only crowd.  Videos from the conference are now available online from Yahoo here.
Jean-Daniel Cryans and I presented on the (any day now) HBase 0.20.0 release.
Check out the slides and [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://developer.yahoo.com/events/hadoopsummit09/" target="_blank">Hadoop Summit</a> was a great success this year and I had a ton of fun giving the presentation on HBase in front of a standing-room-only crowd.  Videos from the conference are now available online from Yahoo <a href="http://developer.yahoo.net/blogs/theater/archives/hadoopsummit/" target="_blank">here</a>.</p>
<p>Jean-Daniel Cryans and I presented on the (any day now) HBase 0.20.0 release.</p>
<p>Check out the slides and video from <em>HBase Goes Realtime</em> below&#8230;</p>
<p><object id="_ds_7493304" name="_ds_7493304" width="600" height="450" type="application/x-shockwave-flash" data="http://viewer.docstoc.com/"><param name="FlashVars" value="doc_id=7493304&amp;mem_id=381319&amp;doc_type=pdf&amp;fullscreen=0&amp;showrelated=0" /><param name="movie"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /></object><br /><font size="1"><a href="http://www.docstoc.com/docs/7493304/HBase-Goes-Realtime">HBase Goes Realtime</a></font></p>
<p><embed src="http://d.yimg.com/cosmos.bcst.yahoo.com/up/fop/embedflv/swf/fop.swf?shareEnable=1&amp;id=14562329&amp;autoStart=0&amp;infoEnable=0&amp;shareEnable=0&amp;prepanelEnable=1&amp;carouselEnable=0&amp;postpanelEnable=1" width="400" height="300" type="application/x-shockwave-flash"></embed></p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/07/24/streamy-hadoop-summit-hbase-goes-realtime/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Streamy at the Hadoop Summit</title>
		<link>http://devblog.streamy.com/2009/05/14/streamy-at-the-hadoop-summit/</link>
		<comments>http://devblog.streamy.com/2009/05/14/streamy-at-the-hadoop-summit/#comments</comments>
		<pubDate>Thu, 14 May 2009 23:15:45 +0000</pubDate>
		<dc:creator>Jonathan Gray</dc:creator>
		
		<category><![CDATA[Meetup]]></category>

		<category><![CDATA[0.20]]></category>

		<category><![CDATA[CMU]]></category>

		<category><![CDATA[hadoop]]></category>

		<category><![CDATA[hadoop summit]]></category>

		<category><![CDATA[hbase]]></category>

		<category><![CDATA[party bus]]></category>

		<category><![CDATA[scalecamp]]></category>

		<category><![CDATA[Streamy]]></category>

		<guid isPermaLink="false">http://devblog.streamy.com/?p=141</guid>
		<description><![CDATA[Along with Jean-Daniel Cryans, I will be giving a presentation at the upcoming Hadoop Summit titled &#8220;HBase Goes Realtime&#8221;.  We will be discussing the major architectural changes that have led to significant increases in performance across the board in the upcoming 0.20 version of HBase.   In addition, there are a number of other improvements [...]]]></description>
			<content:encoded><![CDATA[<p>Along with Jean-Daniel Cryans, I will be giving a presentation at the upcoming <a href="http://developer.yahoo.com/events/hadoopsummit09/" target="_blank">Hadoop Summit</a> titled &#8220;HBase Goes Realtime&#8221;.  We will be discussing the major architectural changes that have led to significant increases in performance across the board in the upcoming 0.20 version of <a href="http://hbase.org" target="_blank">HBase</a>.   In addition, there are a number of other improvements to the API and fault-tolerance that will be discussed.</p>
<p>The Hadoop Summit is taking place on June 10th from 8AM to 9PM at the Santa Clara Marriott in Santa Clara, CA, USA.  You can order tickets for $100 <a href="http://hadoopsummit09.eventbrite.com/" target="_blank">here</a>.</p>
<p>On June 9th, HBase developers will be meeting at 3PM in San Francisco.  If you are interested in attending, drop me a line.  We&#8217;ll then be taking the <a href="http://www.bandago.com/vehicles.php" target="_blank">party bus</a> down to the Marriott at 7PM for <a href="http://www.scaleunlimited.com/events/scale_camp" target="_blank">ScaleCamp</a>, presented by our friends at <a href="http://www.scaleunlimited.com/" target="_blank">Scale Unlimited</a>.  You can order FREE tickets <a href="http://scalecamp.eventbrite.com/" target="_blank">here</a>.</p>
<p>Finally&#8230; A big shout out to <a href="http://www.cs.cmu.edu/~priya/" target="_blank">Priya Narasimhan</a>, one of my favorite professors from <a href="http://www.cmu.edu" target="_blank">CMU</a> that I reconnected with after learning she is also presenting at the Hadoop Summit.  Looking forward to collaborating with her and CMU soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/05/14/streamy-at-the-hadoop-summit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Debugging FastCGI and Lighttpd with spawn-fcgi and fcgi-debug</title>
		<link>http://devblog.streamy.com/2009/04/24/debugging-fastcgi-and-lighttpd-with-spawn-fcgi-and-fcgi-debug/</link>
		<comments>http://devblog.streamy.com/2009/04/24/debugging-fastcgi-and-lighttpd-with-spawn-fcgi-and-fcgi-debug/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 20:23:06 +0000</pubDate>
		<dc:creator>Jonathan Gray</dc:creator>
		
		<category><![CDATA[Tips and Tricks]]></category>

		<category><![CDATA[concurrency]]></category>

		<category><![CDATA[debug]]></category>

		<category><![CDATA[fastcgi]]></category>

		<category><![CDATA[fcgi-debug]]></category>

		<category><![CDATA[freenode]]></category>

		<category><![CDATA[http]]></category>

		<category><![CDATA[http daemon]]></category>

		<category><![CDATA[irc]]></category>

		<category><![CDATA[lighttpd]]></category>

		<category><![CDATA[spawn-fcgi]]></category>

		<category><![CDATA[stbuehler]]></category>

		<category><![CDATA[Streamy]]></category>

		<guid isPermaLink="false">http://devblog.streamy.com/?p=95</guid>
		<description><![CDATA[The web server of choice here at Streamy is Lighttpd.  Written in C, it&#8217;s designed for performance, efficiency, security and concurrency.  In addition to being one of the best performing http daemons for serving static content, it&#8217;s integration with FastCGI makes it simple to turn applications in almost any language into a CGI [...]]]></description>
			<content:encoded><![CDATA[<p>The web server of choice here at <a href="http://www.streamy.com" target="_blank">Streamy</a> is <a href="http://www.lighttpd.net" target="_blank">Lighttpd</a>.  Written in C, it&#8217;s designed for performance, efficiency, security and concurrency.  In addition to being one of the <a href="http://www.lighttpd.net/benchmark" target="_blank">best performing</a> http daemons for serving static content, it&#8217;s integration with <a href="http://www.fastcgi.com/drupal/" target="_blank">FastCGI</a> makes it simple to turn applications in almost any language into a CGI script with little or no code modification.  The communication between your script&#8217;s process and lighttpd is done with unix sockets or via tcp, making it easy to load-balance and have scripts that run on remote nodes.</p>
<p>Lighttpd makes it very easy to launch your cgi processes automatically without having to worry much about the interface.  However, debugging them like this can be arduous, if even possible.  When you want to get serious about developing fastcgi apps, you&#8217;ll need to run them yourself using <a href="http://redmine.lighttpd.net/projects/spawn-fcgi/wiki" target="_blank">spawn-fcgi</a> and can then debug them using <a href="http://cgit.stbuehler.de/gitosis/fcgi-debug/about/" target="_blank">fcgi-debug</a>.  spawn-fcgi is a way to separate the launching of the web server from the launching of the cgi proccess(es).  fcgi-debug is a nifty program that sits in between the web server and your script that allows you to see everything that&#8217;s going on.</p>
<p>A HUGE thanks to <a href="http://redmine.lighttpd.net/account/show/7" target="_blank">stbuehler</a> who not only develops and maintains both of these applications but also spent time helping me debug a nasty issue we were having at Streamy.  <a href="http://en.wikipedia.org/wiki/Internet_Relay_Chat" target="_blank">IRC</a> (and for developers, <a href="http://freenode.net/" target="_blank">Freenode</a>) is still one of the most powerful social networks out there! <img src='http://devblog.streamy.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Let&#8217;s imagine you have a compiled binary FastCGI program called <strong>myscript</strong> and you want to debug it.  At first, a simple lighttpd configuration for it might look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">fastcgi.<span style="color: black;">server</span> <span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;/myscript&quot;</span> =<span style="color: #66cc66;">&gt;</span> <span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;myscript&quot;</span> =<span style="color: #66cc66;">&gt;</span> <span style="color: black;">&#40;</span>
  <span style="color: #483d8b;">&quot;socket&quot;</span> =<span style="color: #66cc66;">&gt;</span> <span style="color: #483d8b;">&quot;/home/user/myscript.sock&quot;</span>,
  <span style="color: #483d8b;">&quot;bin-path&quot;</span> =<span style="color: #66cc66;">&gt;</span> <span style="color: #483d8b;">&quot;/home/user/myscript&quot;</span>,
  <span style="color: #483d8b;">&quot;min-procs&quot;</span> =<span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">1</span>,
  <span style="color: #483d8b;">&quot;max-procs&quot;</span> =<span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">1</span>
<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><em>Full configuration information for mod_fastcgi is available <a href="http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModFastCGI" target="_blank">here</a></em></p>
<p>The first step towards debugging is to change from Lighttpd spawning the process to using spawn-fcgi.  There are more detailed instructions available <a href="http://redmine.lighttpd.net/projects/spawn-fcgi/wiki/Basic_Ideas" target="_blank">here</a> and <a href="http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModFastCGI#FastCGI-and-Programming-Languages" target="_blank">here</a>, but in short what you will do is modify your lighty config to just point to the socket.  Remove bin-path and all process/load settings, otherwise you will run into conflicts.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">fastcgi.<span style="color: black;">server</span> <span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;/myscript&quot;</span> =<span style="color: #66cc66;">&gt;</span> <span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;myscript&quot;</span> =<span style="color: #66cc66;">&gt;</span> <span style="color: black;">&#40;</span>
  <span style="color: #483d8b;">&quot;socket&quot;</span> =<span style="color: #66cc66;">&gt;</span> <span style="color: #483d8b;">&quot;/home/user/myscript.sock&quot;</span>
<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>If we were not interested in debugging the interface/communications between lighttpd and fastcgi, we would spawn the script like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">spawn-fcgi <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>user<span style="color: #000000; font-weight: bold;">/</span>myscript.sock <span style="color: #660033;">-C</span> <span style="color: #000000;">0</span> <span style="color: #660033;">-F</span> <span style="color: #000000;">1</span> <span style="color: #660033;">-n</span> <span style="color: #660033;">--</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>user<span style="color: #000000; font-weight: bold;">/</span>myscript</pre></div></div>

<p>Adding fcgi-debug in the middle is as easy as calling it first rather than the script:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">spawn-fcgi <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>user<span style="color: #000000; font-weight: bold;">/</span>myscript.sock <span style="color: #660033;">-C</span> <span style="color: #000000;">0</span> <span style="color: #660033;">-F</span> <span style="color: #000000;">1</span> <span style="color: #660033;">-n</span> <span style="color: #660033;">--</span> fcgi-debug <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>user<span style="color: #000000; font-weight: bold;">/</span>myscript</pre></div></div>

<p>You should now see lots of debug information directly to stdout.</p>
<p>You should also ensure that you have fastcgi debug turned on in your lighttpd logs.  This is done with the setting:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">server<span style="color: #339933;">.</span>errorlog <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/home/user/lighttpd_error.log&quot;</span>
fastcgi<span style="color: #339933;">.</span>debug <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span></pre></div></div>

<h6>If using fcgi-debug, you are required to use <a href="http://www.lighttpd.net/download/spawn-fcgi-1.6.2.tar.gz" target="_blank">spawn-fcgi 1.6.2</a> rather than the one packaged with your lighttpd installation.  spawn-fcgi 1.4.22 will run but will not show any debug output.</h6>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/04/24/debugging-fastcgi-and-lighttpd-with-spawn-fcgi-and-fcgi-debug/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HBase 101: Row key design for paging (LIMIT, OFFSET) queries</title>
		<link>http://devblog.streamy.com/2009/04/23/hbase-row-key-design-for-paging-limit-offset-queries/</link>
		<comments>http://devblog.streamy.com/2009/04/23/hbase-row-key-design-for-paging-limit-offset-queries/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 00:10:48 +0000</pubDate>
		<dc:creator>Jonathan Gray</dc:creator>
		
		<category><![CDATA[Hadoop/HBase]]></category>

		<category><![CDATA[Tips and Tricks]]></category>

		<category><![CDATA[big endian]]></category>

		<category><![CDATA[binary]]></category>

		<category><![CDATA[composite key]]></category>

		<category><![CDATA[epoch]]></category>

		<category><![CDATA[hbase]]></category>

		<category><![CDATA[hbase 101]]></category>

		<category><![CDATA[indexing]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[limit]]></category>

		<category><![CDATA[offset]]></category>

		<category><![CDATA[paging]]></category>

		<category><![CDATA[query]]></category>

		<category><![CDATA[rdbms]]></category>

		<category><![CDATA[row key]]></category>

		<category><![CDATA[secondary indexes]]></category>

		<category><![CDATA[sql]]></category>

		<category><![CDATA[table design]]></category>

		<guid isPermaLink="false">http://devblog.streamy.com/?p=68</guid>
		<description><![CDATA[Paging is a very common use-case for web sites and many other applications.  In relational databases, this is easily implemented with LIMIT and OFFSET, or by selecting the row number in the query and adding conditionals based on it's value.  HBase 0.19.x, on the other hand, does not provide any queries or filters that support paging directly.]]></description>
			<content:encoded><![CDATA[<p>Paging is a very common use-case for web sites and many other applications.  In relational databases, this is easily implemented with LIMIT and OFFSET, or by selecting the row number in the query and adding conditionals based on it&#8217;s value.  HBase 0.19.x, on the other hand, does not provide any queries or filters that support paging directly.  After a quick example using SQL, I will show how to implement the same functionality in HBase.</p>
<p>Let&#8217;s assume that we have a large number of <strong>users</strong>.  Each user has performed a number of <strong>actions</strong>.  Each action has a unique identifier, a timestamp, and a name.</p>
<p>This is how you might get the third page of an individual users&#8217; actions using SQL:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> id<span style="color: #66cc66;">,</span> name<span style="color: #66cc66;">,</span> stamp <span style="color: #993333; font-weight: bold;">FROM</span> actions <span style="color: #993333; font-weight: bold;">WHERE</span> userid <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> stamp <span style="color: #993333; font-weight: bold;">DESC</span> <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">10</span> OFFSET <span style="color: #cc66cc;">20</span>;</pre></div></div>

<p>This utilizes secondary indexes on both <strong>userid </strong>and <strong>stamp</strong>, meaning to accomplish this query you need <em>at least</em> three indexes on this table as <strong>id </strong>is the primary key.  Though a simple query to write, you will run into problems as the <strong>actions</strong> table grows to millions of rows and beyond.  Insertions would look like:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> actions <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span> userid<span style="color: #66cc66;">,</span> name<span style="color: #66cc66;">,</span> stamp<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span>newid<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Joe User'</span><span style="color: #66cc66;">,</span> epoch<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>HBase has no real indexes.  Rows are stored in sorted order, and columns in a family are sorted.  For more information, read the <a href="http://wiki.apache.org/hadoop/Hbase/HbaseArchitecture" target="_blank">HBase Architecture</a> page on the <a href="http://wiki.apache.org/hadoop/Hbase" target="_blank">HBase Wiki</a>.</p>
<p>Very conscious of the primary queries we will run on user-actions, we will design an HBase table to support paging queries on per-user, time-ordered lists of actions.</p>
<p>We will use the Java Client API for HBase, specifically the HTable class.  What we are looking for are two methods:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> List<span style="color: #339933;">&lt;</span>Action<span style="color: #339933;">&gt;</span> getUserActions<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> userid, <span style="color: #000066; font-weight: bold;">int</span> offset, <span style="color: #000066; font-weight: bold;">int</span> limit<span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> putUserAction<span style="color: #009900;">&#40;</span><span style="color: #003399;">Action</span> action<span style="color: #009900;">&#41;</span></pre></div></div>

<p><em>Please note, I am using a custom object, Action, for simplicity.  It is a client-side holder for the four action fields (id, userid, name, stamp).</em></p>
<p>There are a number of ways to store your data in HBase that will allow the <strong>getUserActions</strong> query, but in this case we will go with a very <em>tall</em> table design (lots of rows with few columns in them) rather than <em>wide </em>(lots of columns in each row).  Specifically, the difference here would be whether you have a row-per-action or a row-per-user.  We will do a row-per-action, but will be designing our row key (the primary key) to be a composite key to allow for grouping and sorting of actions, rather than just the action id.  This means we will not have random-access to an action by it&#8217;s id, so rather than defining this as the <strong>actions</strong> table (which might also exist if you needed actionid random access) we will define it as the <strong>useractions</strong> table, and we will only store a single column in a single family, <strong>content:name</strong>.</p>
<p>The row key that we will use in our HBase <strong>useractions</strong> table is:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>userid<span style="color: #339933;">&gt;&lt;</span>reverse_order_stamp<span style="color: #339933;">&gt;&lt;</span>actionid<span style="color: #339933;">&gt;</span></pre></div></div>

<p>It&#8217;s very important that each of these fields is fixed-length and binary so that the lexicographical/ascending byte-ordering of HBase will properly sort our rows.</p>
<p>The <strong>userid</strong> field will be a 4 byte, big endian integer.  <strong>reverse_order_stamp</strong> is an 8 byte, big endian long with a value of (Long.MAX_VALUE - epoch).  This is so the most recent stamp is at the top rather than the bottom.  <strong>actionid</strong> is another 4 byte, big endian integer.  Thankfully, HBase provides helpful utilties in the org.apache.hadoop.hbase.util.Bytes class to deal with this (unfortunately it lacked some key features in 0.19, so the code below makes use of the Bytes class available in 0.20/TRUNK).  Before we get into HBase code, let&#8217;s define the helper methods <strong>makeActionRow</strong> and <strong>readActionRow</strong> to deal with the composite key:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> makeActionRow<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> userid, <span style="color: #000066; font-weight: bold;">long</span> stamp, <span style="color: #000066; font-weight: bold;">int</span> actionid<span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> useridBytes <span style="color: #339933;">=</span> Bytes.<span style="color: #006633;">toBytes</span><span style="color: #009900;">&#40;</span>userid<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> stampBytes <span style="color: #339933;">=</span> Bytes.<span style="color: #006633;">toBytes</span><span style="color: #009900;">&#40;</span>stamp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> actionidBytes <span style="color: #339933;">=</span> Bytes.<span style="color: #006633;">toBytes</span><span style="color: #009900;">&#40;</span>actionid<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">return</span> Bytes.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>useridBytes, stampBytes, actionidBytes<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">Action</span> readActionRow<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> row<span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// Bytes.toInt(byte [] buf, int offset, int length)</span>
  <span style="color: #000066; font-weight: bold;">int</span> userid <span style="color: #339933;">=</span> Bytes.<span style="color: #006633;">toInt</span><span style="color: #009900;">&#40;</span>row,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">long</span> stamp <span style="color: #339933;">=</span> <span style="color: #003399;">Long</span>.<span style="color: #006633;">MAX_VALUE</span> <span style="color: #339933;">-</span> Bytes.<span style="color: #006633;">toLong</span><span style="color: #009900;">&#40;</span>row,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">int</span> actionid <span style="color: #339933;">=</span> Bytes.<span style="color: #006633;">toInt</span><span style="color: #009900;">&#40;</span>row,<span style="color: #cc66cc;">12</span>,<span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Action</span><span style="color: #009900;">&#40;</span>userid,stamp,actionid<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now that we can deal with the composite keys, insertion is very straightforward:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> putUserAction<span style="color: #009900;">&#40;</span><span style="color: #003399;">Action</span> action<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// Get the fields from the Action object</span>
  <span style="color: #000066; font-weight: bold;">int</span> userid <span style="color: #339933;">=</span> action.<span style="color: #006633;">getUserID</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">long</span> stamp <span style="color: #339933;">=</span> <span style="color: #003399;">Long</span>.<span style="color: #006633;">MAX_VALUE</span> <span style="color: #339933;">-</span> action.<span style="color: #006633;">getStamp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">int</span> actionid <span style="color: #339933;">=</span> action.<span style="color: #006633;">getID</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003399;">String</span> name <span style="color: #339933;">=</span> action.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Build the composite row, column, and value</span>
  <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> row <span style="color: #339933;">=</span> makeActionRow<span style="color: #009900;">&#40;</span>userid,stamp,actionid<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> column <span style="color: #339933;">=</span> Bytes.<span style="color: #006633;">toBytes</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;content:name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> value <span style="color: #339933;">=</span> Bytes.<span style="color: #006633;">toBytes</span><span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Insert to HBase</span>
  HTable ht <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HTable<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;useractions&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  BatchUpdate bu <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> BatchUpdate<span style="color: #009900;">&#40;</span>row<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  bu.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>column,value<span style="color: #009900;">&#41;</span>
  ht.<span style="color: #006633;">commit</span><span style="color: #009900;">&#40;</span>bu<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>We just serialize the fields into the composite row, and write the single column to HBase in a BatchUpdate.  Reading will deal with unserializing the fields and Scanners.  In addition to matching for the <strong>content:name</strong> column, we will also specify a startRow and stopRow so that the Scanner only returns results from the user we are looking at.  This way we do not have to worry about jumping to the next user in our code, the Scanner will just stop.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> List<span style="color: #339933;">&lt;</span>Action<span style="color: #339933;">&gt;</span> getUserActions<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> userid, <span style="color: #000066; font-weight: bold;">int</span> offset, <span style="color: #000066; font-weight: bold;">int</span> limit<span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// Initialize counter and List to return</span>
  <span style="color: #000066; font-weight: bold;">int</span> count <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  List<span style="color: #339933;">&lt;</span>Action<span style="color: #339933;">&gt;</span> actions <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;</span>Action<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span>limit<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Initialize startRow, stopRow, and columns to match</span>
  <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> startRow <span style="color: #339933;">=</span> makeActionRow<span style="color: #009900;">&#40;</span>userid,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> stopRow <span style="color: #339933;">=</span> makeActionRow<span style="color: #009900;">&#40;</span>userid,<span style="color: #003399;">Long</span>.<span style="color: #006633;">MAX_VALUE</span>,<span style="color: #003399;">Integer</span>.<span style="color: #006633;">MAX_VALUE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> columns <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>Bytes.<span style="color: #006633;">toBytes</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;content:name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Open Scanner</span>
  HTable ht <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HTable<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;useractions&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  Scanner s <span style="color: #339933;">=</span> ht.<span style="color: #006633;">getScanner</span><span style="color: #009900;">&#40;</span>columns,startRow,stopRow<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  RowResult res <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Iterate over Scanner</span>
  <span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>res <span style="color: #339933;">=</span> s.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Check if past offset</span>
    <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">++</span>count <span style="color: #339933;">&lt;=</span> offset<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Get data from RowResult</span>
    <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> row <span style="color: #339933;">=</span> res.<span style="color: #006633;">getRow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> value <span style="color: #339933;">=</span> res.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>columns<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Build Action</span>
    <span style="color: #003399;">Action</span> action <span style="color: #339933;">=</span> readActionRow<span style="color: #009900;">&#40;</span>row<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">String</span> name <span style="color: #339933;">=</span> Bytes.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    action.<span style="color: #006633;">setName</span><span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    actions.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>action<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Check limit</span>
    <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>count <span style="color: #339933;">==</span> offset <span style="color: #339933;">+</span> limit<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #666666; font-style: italic;">// Cleanup and return</span>
  s.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">return</span> actions<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The storage of your data must be tied to how you need to query it.  Without a sophisticated query engine or indexing capabilities, you must design to take advantage of sorted rows and columns, potentially designing a table per query type.  Denormalization is okay!</p>
<p>In my next posts, I will show more interesting ways to use HBase for persisted dictionary/keyval/Object storage and directly address secondary indexing with HBase.</p>
<p><em>Disclaimer: The code in these examples is designed to illustrate the practical use of HBase.  While the design is sound, the code itself may not optimized for performance.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/04/23/hbase-row-key-design-for-paging-limit-offset-queries/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Web Scale</title>
		<link>http://devblog.streamy.com/2009/04/14/web-scale/</link>
		<comments>http://devblog.streamy.com/2009/04/14/web-scale/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 00:46:58 +0000</pubDate>
		<dc:creator>Jonathan Gray</dc:creator>
		
		<category><![CDATA[Web Scale]]></category>

		<category><![CDATA[consistent hashing]]></category>

		<category><![CDATA[dht]]></category>

		<category><![CDATA[distributed hash table]]></category>

		<category><![CDATA[Distributed Systems]]></category>

		<category><![CDATA[distribution]]></category>

		<category><![CDATA[Erlang]]></category>

		<category><![CDATA[hadoop]]></category>

		<category><![CDATA[hbase]]></category>

		<category><![CDATA[horizontal scale]]></category>

		<category><![CDATA[scalability]]></category>

		<category><![CDATA[scaling]]></category>

		<category><![CDATA[Streamy]]></category>

		<category><![CDATA[vertical scale]]></category>

		<guid isPermaLink="false">http://devblog.streamy.com/?p=49</guid>
		<description><![CDATA[Development at Streamy is always done with the mindset of &#8220;will it scale&#8221; in the back of our minds.
Generally speaking, scalability deals with the ability for a software system to handle increasing load when given additional resources.  Increased load could mean more concurrency, a larger data set, or increased complexity.  Additional resources refers to hardware [...]]]></description>
			<content:encoded><![CDATA[<p>Development at Streamy is always done with the mindset of &#8220;will it scale&#8221; in the back of our minds.</p>
<p>Generally speaking, <a href="http://en.wikipedia.org/wiki/Scalability" target="_blank">scalability</a> deals with the ability for a software system to handle increasing load when given additional resources.  Increased load could mean more concurrency, a larger data set, or increased complexity.  Additional resources refers to hardware and either <em>scaling vertically</em> (upgrading a single node) or <em>scaling horizontally</em> (adding additional nodes).  While vertical scale is important in terms of squeezing all the performance you can out of each node, and rapidly dropping hardware prices means even cheap nodes are powerful, the key to achieving true scalability is the ability to horizontally scale, or distribute.</p>
<p>Distributed systems are becoming more and more mainstream as the web has flourished.  Search engines index billions of web pages and social networks support millions of concurrent users.  Content continues to evolve from being static, to dynamic, to the current emphasis on personalization and customization.  The adoption of AJAX and COMET have further increased requirements for concurrency.  And all of this must be highly-available and low-latency (sub-second).</p>
<p>This is what I call <em><strong>Web Scale</strong></em>.</p>
<h3>So what exactly is it?</h3>
<p>It&#8217;s a new set of technical requirements borne out of Web 2.0, and the move towards distributed systems and cloud computing as the solution.  It encompasses all the different aspects of today&#8217;s web applications: the data, the storage, the caches, the web servers, the communications, the realtime queries, the batch queries, and everything in between.  It marks a departure from the vertical scaling of relational databases and web servers as the solution to scale towards a new world of horizontal scalability: distributed hash tables, consistent hashing, column-orientation, horizontal partitioning, eventual consistency, elastic computing, and every other buzzword you can think of.</p>
<h3>Who has solved it?</h3>
<p><strong>Google. </strong>They deserve a great deal of credit for being the first to really <em>achieve </em>web scale.  Long before web sites really considered their architecture as part of their competitive advantage, Google embraced the notion and invented their own solutions.  They subsequently published a number of papers describing their efforts:  The <a href="http://labs.google.com/papers/gfs-sosp2003.pdf" target="_blank">Google File System</a>, <a href="http://labs.google.com/papers/mapreduce-osdi04.pdf" target="_blank">MapReduce</a>, and <a href="http://labs.google.com/papers/bigtable.html" target="_blank">BigTable</a>.</p>
<p><strong>Amazon</strong>.  The enormous amount of work that was done in order to achieve scalability for the world&#8217;s premier e-commerce site is obvious; one need only look at their extensive and fast-growing elastic storage and computing services like <a href="https://s3.amazonaws.com/" target="_blank">S3</a> and <a href="http://aws.amazon.com/ec2/" target="_blank">EC2</a>.  An e-commerce site becoming a service provider?  There&#8217;s only so much cost-savings a good architecture can give an e-commerce site, so it only makes sense that they try to profit from their proprietary systems.  The CTO of Amazon, Werner Vogels, has an excellent blog <a href="http://www.allthingsdistributed.com/" target="_blank">AllThingsDistributed</a>.  Read through some of his posts and you can quickly see that Amazon is a company that understands scaling, distribution, and the right way to go about design and engineering in today&#8217;s Web Scale world.</p>
<h3>Who struggles with it?</h3>
<p><strong>Facebook</strong>.   Today&#8217;s prime example for what happens when you don&#8217;t build for scale early on: the only short-term solution to rapid growth is to throw money at the problem.  Utilizing both horizontal and vertical scale, <a href="http://www.facebook.com" target="_blank">Facebook</a> has enormous clusters of <a href="http://www.mysql.org" target="_blank">MySQL</a> and <a href="http://www.danga.com/memcached/" target="_blank">Memcached</a> to deal with storing user data and serving user queries.  As <a href="http://www.paragon-cs.com/wordpress/2008/04/16/scaling-mysql-up-or-out-panel-uc/" target="_blank">reported nearly a year ago</a>, they already had close to 2,000 MySQL boxes and 1,000 Memcached boxes in addition to their 10,000 web servers.</p>
<p>They have been playing catch-up ever since, slowly developing (and open-sourcing in some cases) distributed systems to deal with their enormous scale.  Though almost always plagued by the lack of community and direct support from Facebook engineers, they have some very interesting projects including <a href="http://cwiki.apache.org/confluence/display/CSDR/Index" target="_blank">Cassandra</a> and <a href="http://hadoop.apache.org/hive/" target="_blank">Hive</a>.  More recently, they seem to finally have solved their photo storage cost issues with <a href="http://www.flowgram.com/fg/2qi3k8eicrfgkv/" target="_blank">Haystack</a>, saving them from <a href="http://www.techcrunch.com/2009/04/06/facebook-completes-rollout-of-haystack-to-stem-losses-from-massive-photo-uploads/" target="_blank">needing to buy an additional $2M+ server every month</a> just to keep up.  The difference in architectures is well described in <a href="http://www.niallkennedy.com/blog/2009/04/facebook-haystack.html" target="_blank">Niall Kennedy&#8217;s post</a>.</p>
<p><strong>Twitter</strong>.  Considering how well known the <a href="http://www.readwriteweb.com/archives/the_story_of_the_fail_whale.php" target="_blank">fail whale</a> is, it&#8217;s clear to most that Twitter has been plagued by slow responses and downtime, even to this day.  Though extremely simple in its requirements, the personalized views, emphasis on search, and massive use of the API by developers creates huge amounts of load for the microblogging (or is it nanoblogging?) service.</p>
<p><strong>FriendFeed</strong>.  A company led by ex-Googlers, and to my knowledge without major technical issues, seems to be going down a path of scaling that seems clunky and backwards.  Generally speaking, scaling a database means letting go of some of the traditional restrictions, first things like normalization and secondary indexes, and then more significantly by relaxing ACID-compliance or adding eventual consistency.  As outlined in a blog post by one of their founders, Bret Taylor, their attempt at a <a href="http://bret.appspot.com/entry/how-friendfeed-uses-mysql" target="_blank">schema-less storage system atop MySQL</a> seems to be a good idea and good effort gone wrong.</p>
<p>When what you&#8217;re after is schema-less storage, and the need for partitioning/distribution, why would you base it on a system completely tied to schemas and full-blown transactions?  You&#8217;re bringing with you all the things you don&#8217;t want, at the expense of performance and flexibility, because they &#8220;trust&#8221; MySQL and are already familiar with it.  Good reasons, no doubt, but the whole thing appears misguided.  In any case, I bet that it works and performance is acceptable.  But it&#8217;s not always about finding a solution that works.  Flexibility, simplicity, and of course, additional scalability, are also important and something so confusing to do something so simple just ask for you to not want to touch it once it works <img src='http://devblog.streamy.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><em>Note:  This is not to say that these companies are &#8220;doing it wrong&#8221;.  I point out these examples because they are cases of costs gone out of control, continued performance and uptime issues, approaches I personally would not recommend, etc.  MySQL + Memcached is certainly part of the Web Scale tool box and in a great deal of use cases is satisfactory.  For more information on relational databases and how they compare to something like HBase, check out my presentation on <a href="http://www.docstoc.com/docs/2996433/Hadoop-and-HBase-vs-RDBMS" target="_blank">Hadoop and HBase vs RDBMS</a>.</em></p>
<h3>So, how does Streamy solve it?</h3>
<p>Stay tuned!  This will be the topic of an upcoming series of posts over the next few weeks.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/04/14/web-scale/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HBase Hackathon Wrap-up</title>
		<link>http://devblog.streamy.com/2009/02/04/hbase-hackathon-wrap-up/</link>
		<comments>http://devblog.streamy.com/2009/02/04/hbase-hackathon-wrap-up/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 04:29:33 +0000</pubDate>
		<dc:creator>Jonathan Gray</dc:creator>
		
		<category><![CDATA[Hadoop/HBase]]></category>

		<category><![CDATA[Meetup]]></category>

		<category><![CDATA[caching]]></category>

		<category><![CDATA[Cascading]]></category>

		<category><![CDATA[hackathon]]></category>

		<category><![CDATA[hadoop]]></category>

		<category><![CDATA[hbase]]></category>

		<category><![CDATA[hfile]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[lru]]></category>

		<category><![CDATA[manhattan beach]]></category>

		<category><![CDATA[MapReduce]]></category>

		<category><![CDATA[Streamy]]></category>

		<category><![CDATA[tfile]]></category>

		<category><![CDATA[zookeeper]]></category>

		<guid isPermaLink="false">http://streamydev.wordpress.com/?p=28</guid>
		<description><![CDATA[HBase contributors came together last weekend for the first ever HBase Hackathon here at Streamy HQ in Manhattan Beach, California.  In attendance were most of the HBase committers, guys from Sun and StumbleUpon&#8230; nearly 20 developers in total.  There are photos posted on the Meetup Page (for members only).  If anyone else who attended has [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://hbase.org" target="_blank">HBase</a> contributors came together last weekend for the first ever HBase Hackathon here at <a href="http://streamy.com" target="_blank">Streamy</a> HQ in Manhattan Beach, California.  In attendance were most of the HBase committers, guys from <a href="http://sun.com" target="_blank">Sun</a> and <a href="http://stumbleupon.com" target="_blank">StumbleUpon</a>&#8230; nearly 20 developers in total.  There are photos posted on the <a href="http://meetup.com/hbasela" target="_blank">Meetup Page</a> (for members only).  If anyone else who attended has pictures please post links in the comments!</p>
<p>We spent a great deal of time discussing the new features set for the 0.20 release of HBase.  You can follow all the issues slated for 0.20 <a href="https://issues.apache.org/jira/secure/IssueNavigator.jspa?fixfor=12313474&amp;sorter/field=priority&amp;sorter/order=DESC" target="_blank">here</a>.  It&#8217;s been a few days and so much has already come out of the weekend so I thought I&#8217;d post a quick follow-up to share some of the cool stuff being worked on now.</p>
<p><strong>Cascading Support for HBase<br />
</strong>Chris Wensel, of <a href="http://www.concurrentinc.com/" target="_blank">Concurrent Inc.</a>, has successfully implemented the first version of <a href="http://github.com/cwensel/cascading.hbase/tree/master" target="_blank">HBase adapters for Cascading</a>.  Streamy devs are really looking forward to refactoring some of their MapReduce jobs for Cascading!  We will report back soon.</p>
<p><strong>HBase New File Format<br />
</strong>We have hit a performance wall in HBase with the Hadoop MapFile format.  It was never intended for a random-access read pattern which is really the primary purpose of HBase.  Based on the hard work by guys over at Yahoo on the <a href="https://issues.apache.org/jira/browse/HADOOP-3315" target="_blank">TFile binary file format</a>, work is well under way on a new <a href="https://issues.apache.org/jira/browse/HBASE-61" target="_blank">HBase-specific file format</a>, currently being called HFile.  Michael Stack of Powerset and Ryan Rawson of StumbleUpon are leading the effort.</p>
<p>The emphasis is on speed and efficiency.  By switching to a block-based segmenting/indexing of the file, we can have predictable memory usage and an ideal abstraction for caching.  Once in memory, we can use something like Java&#8217;s <a href="http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html" target="_blank">NIO ByteBuffers</a> to allow high numbers of concurrent scanners with minimal memory copying.  Remember, even random-access reads require scanning.  The new format also supports meta blocks for additional indexes, bloom filters, meta data and anything else we want to add in the future.</p>
<p><strong>Cell Caching<br />
</strong>Streamy&#8217;s own Erik Holstad is wrapping up testing, benchmarking and optimizing the new <a href="https://issues.apache.org/jira/browse/HBASE-80" target="_blank">Cell Cache</a>.  We&#8217;re seeing a 5-10X improvement in random-access speed when serving out of the cache.  A big part of this feature is implementing a memory-aware LRU in Java.  Since Java will not tell you the size of an Object in memory, we have had to hack our way around through profiling and some tools we&#8217;ve built to determine sizes.  More on this in a later post.</p>
<p><strong>Zookeeper Integration<br />
</strong>Jean-Daniel Cryans and Nitay Joffe have made leaps and bounds with Zookeper integration into HBase.  Initially designed to remove the single point of failure, discussions at the Hackathon opened the door to future improvements such as configuration management and even to eventually distribute master functionality and eliminate the HMaster all together.  They have already committed 5 issues to 0.20 trunk.  You can follow their progress <a href="https://issues.apache.org/jira/browse/HBASE-546" target="_blank">here</a>.</p>
<p><strong>Datanode Network I/O Improvements<br />
</strong>Andrew Purtell at Trend Micro is working on a <a href="https://issues.apache.org/jira/browse/HADOOP-3856" target="_blank">Hadoop issue</a> that creates a big headache for the users of HBase.  We keep a large numbers of files open at a time and since it is currently implemented using a thread-per-connection model, we end up with thousands of idle threads and having to keep increasing the total number of receivers.  I&#8217;m not sure where this currently stands.</p>
<p><strong>My Random Contributions<br />
</strong>In addition to voicing my opinion and contributing to design and decision making, I&#8217;m currently working on a number of small issues:  a <a href="https://issues.apache.org/jira/browse/HBASE-1183" target="_blank">binary key range splitting algorithm</a>, the ability to run <a href="https://issues.apache.org/jira/browse/HBASE-1172" target="_blank">more than one mapper per region</a> or to <a href="https://issues.apache.org/jira/browse/HBASE-1170" target="_blank">specify start and stop rows</a> for MR jobs sourcing from HBase, and a number of benchmarking tools to evaluate all the new stuff.</p>
<p>All in all, it was a terrific weekend.  The weather was absolutely perfect and it was as friendly and smart a group as I could have imagined.  Thanks to everyone who came, especially those who made the trip down from Norcal and JD who came from Canada to defrost for a bit in the Cali sun.  Summer is coming soon, stay tuned for the next beach city hackathon <img src='http://devblog.streamy.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.streamy.com/2009/02/04/hbase-hackathon-wrap-up/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
