<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Alex Feinberg</title>
 <link href="http://afeinberg.github.com/atom.xml" rel="self"/>
 <link href="http://afeinberg.github.com/"/>
 <updated>2011-07-25T14:20:37-07:00</updated>
 <id>http://afeinberg.github.com/</id>
 <author>
   <name>Alex Feinberg</name>
   <email>alex@strlen.net</email>
 </author>

 
 <entry>
   <title>Reliability, availability and scale - an interlude</title>
   <link href="http://afeinberg.github.com/2011/06/25/reliability-availability-scale-interlude.html"/>
   <updated>2011-06-25T00:00:00-07:00</updated>
   <id>http://afeinberg.github.com/2011/06/25/reliability-availability-scale-interlude</id>
   <content type="html">&lt;h1&gt;Reliability, availability and scale &amp;#8211; an interlude&lt;/h1&gt;
&lt;h2&gt;An interlude&lt;/h2&gt;
&lt;p&gt;My &lt;a href=&quot;http://afeinberg.github.com/2011/06/17/replication-atomicity-and-order-in-distributed-systems.html&quot;&gt;last post on distributed systems&lt;/a&gt; was dense with concepts. Before continuing with much more discussion, let&amp;#8217;s take a quick detour and define several frequently used, but  often confused, terms in distributed computing.&lt;/p&gt;
&lt;p&gt;The term scalability is often conflated with other related, important concepts. See for example an article by 37Signals &lt;a href=&quot;http://37signals.com/svn/archives2/dont_scale_99999_uptime_is_for_walmart.php&quot;&gt;&amp;#8220;Don’t scale: 99.999% uptime is for Wal-Mart&amp;#8221;&lt;/a&gt; &amp;#8212; in the article, the notions of scalability and an availability &lt;span class=&quot;caps&quot;&gt;SLA&lt;/span&gt; (which are typically stated as percentages) are used as if they were interchangeable.&lt;/p&gt;
&lt;p&gt;However, as we&amp;#8217;ll see in this post, meeting one or more of these related non-functional (i.e., ones which often come &lt;em&gt;after&lt;/em&gt; the core functionality has been implemented) requirements does not imply meeting the others.&lt;/p&gt;
&lt;p&gt;The non-functional requirements (or &amp;#8220;ilities&amp;#8221;) will be separated into three &amp;#8220;buckets&amp;#8221;: reliability, availability and scalability. It&amp;#8217;s very difficult to agree on what these terms mean, but based on systems engineering practice, here&amp;#8217;s the way that I approach it.&lt;/p&gt;
&lt;h2&gt;Reliability&lt;/h2&gt;
&lt;p&gt;In the previous post, the term &amp;#8220;reliability&amp;#8221; was used informally and the term &amp;#8220;fault tolerance&amp;#8221; was used more formally, e.g., in discussion of fault tolerance properties of algorithms. Rigorously speaking, fault tolerance is only a part of the reliability story: in a fault tolerant multi-component system, it is sufficient that failure of one component doesn&amp;#8217;t cause failure of other components. A system that continues to function in a degraded state is fault tolerant, but unless the full functionality of the previous state can be restored, it&amp;#8217;s not fully reliable. In other words, a reliable system requires fault tolerance, but a fault tolerant system may not require reliability.&lt;/p&gt;
&lt;h3&gt;Recovery&lt;/h3&gt;
&lt;p&gt;&amp;#8220;Recovery&amp;#8221; refers to restoring full functionality (defined to be the previous state in this context) when a failure occurs. Recovery is not often an explicitly stated goal, and is sometimes not included in formal definitions of reliability. However, recovery is an important consideration in the the discipline of deploying and maintaining production systems. Certain design choices (e.g., not maintaining a transaction log) can hurt a system&amp;#8217;s recovery profile despite helping scalability and improving the availability of a system.&lt;/p&gt;
&lt;p&gt;&amp;#8220;&lt;span class=&quot;caps&quot;&gt;MTTR&lt;/span&gt;&amp;#8221; stands for &lt;a href=&quot;http://en.wikipedia.org/wiki/Mean_time_to_recovery&quot;&gt;&lt;em&gt;Mean Time To Recovery&lt;/em&gt;&lt;/a&gt;: the average time from when a failure is encountered to when the previous state is restored, i.e., a system&amp;#8217;s recovery time.&lt;/p&gt;
&lt;h2&gt;Availability&lt;/h2&gt;
&lt;p&gt;In Tannenbaum, Steen &lt;em&gt;Distributed Systems: Principles and Paradigms&lt;/em&gt; availability is defined as&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[The] property that a system is ready to be used immediately. In general, it refers to the probability that the system is operating correctly at any given moment and is available to perform its functions on behalf of its users. In other words, a highly available system is one that will most likely be working at a given instant in time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here we see two definitions &amp;#8212; first sentence defines availability at a specific point in time, while rest of the paragraph gives a way to characterize the &lt;em&gt;overall&lt;/em&gt; availability of a system. Enterprise vendors frequently talk about high availability of their solutions, however, this could mean different things.&lt;/p&gt;
&lt;p&gt;For example, a system that goes down for a minute in the case of failure and then recovers can still be marketed as &amp;#8220;highly available&amp;#8221;: this could be honest marketing if the system is designed such that the failures are rare, i.e., the &lt;a href=&quot;http://en.wikipedia.org/wiki/MTBF&quot;&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;MTBF&lt;/span&gt;&lt;/strong&gt;&lt;/a&gt; is particularly high in relation to &lt;span class=&quot;caps&quot;&gt;MTTR&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Recently the trend has become to build systems that either maintain availability in the face of failure or recover it quickly, rather then systems with especially high &lt;span class=&quot;caps&quot;&gt;MTBF&lt;/span&gt;. This systems engineering view is well summarized by John Allspaw in &lt;a href=&quot;http://www.kitchensoap.com/2010/11/07/mttr-mtbf-for-most-types-of-f/&quot;&gt;&amp;#8220;&lt;span class=&quot;caps&quot;&gt;MTTR&lt;/span&gt; is more important than &lt;span class=&quot;caps&quot;&gt;MTBF&lt;/span&gt; (for most types of F)&amp;#8221;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For the purpose of this blog, a &amp;#8220;median&amp;#8221; definition will be used: a system is highly available if, in the case of failure, it can still respond within a reasonable (acceptable to the end-user) timeout.&lt;/p&gt;
&lt;h2&gt;Scalability&lt;/h2&gt;
&lt;p&gt;Scalability is a property of systems that are able to handle an increase in requests without performance degradation, e.g., in terms of latency and/or throughput. In the context of a distributed system, scalability requires that requests are handled in parallel by multiple nodes.&lt;/p&gt;
&lt;p&gt;Note that there are multiple ways to distribute load across nodes. With a stateless system (or a system whose state can fit within a single machine&amp;#8217;s main memory), a simple way to increase scalability would be to use a high degree of replication (replicating the full instance of the service, allowing it to take both reads and writes) and round-robin requests between multiple machines. In a system where state &lt;em&gt;does not&lt;/em&gt; fit in a single machine&amp;#8217;s main memory, scalability generally requires partitioning the data, i.e., a &lt;em&gt;shared-nothing&lt;/em&gt; architecture.&lt;/p&gt;
&lt;h3&gt;Soft state&lt;/h3&gt;
&lt;p&gt;In addition to stateful and stateless services, there are services that maintain soft state. &amp;#8220;Soft state&amp;#8221; is loosely defined as state that has several properties including relaxed consistency semantics , and is not critical to the core of the service (although soft state may often be required for optional functionality) (Chiappa, &lt;a href=&quot;http://mercury.lcs.mit.edu/~jnc/tech/hard_soft.html&quot;&gt;&amp;#8220;Soft and Hard State&amp;#8221;&lt;/a&gt;).  In this case, there are several options of where the soft state could be stored: in memory of local machines (which frequently implies using sticky sessions) or in a separate system, e.g., in a distributed cache. The former may imply certain scalability and availability characteristics, e.g., possibility of hot spots in the load balancer and need for sessions to be restarted when service nodes fail; in the later case, the availability and scalability properties of the separate stateful system carry over to the service itself.&lt;/p&gt;
&lt;h3&gt;Elasticity&lt;/h3&gt;
&lt;p&gt;Elasticity is a concern closely related to scalability: the ability to add or remove resources (in our case, nodes) to change a system&amp;#8217;s capacity without downtime. A scalable system may not always be elastic, e.g., if adding a node requires taking the system down, manually moving data around, reconfiguring the system, and then starting the system up again. In other words, a scalable system without elasticity would be taking a hits to its availability when nodes need to be added or removed.&lt;/p&gt;
&lt;h2&gt;Case study: a shared nothing database&lt;/h2&gt;
&lt;p&gt;Now that we&amp;#8217;ve looked at these concepts in abstract, let&amp;#8217;s use an example: a shared nothing database. Shared nothing architecture means the nodes in the system don&amp;#8217;t share memory or disk: data resides independently on the nodes which communicate over a network (Stonebraker, &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.58.5370&quot;&gt;The Case for Shared Nothing&lt;/a&gt;). The space of all possible primary keys is partitioned (a frequently used synonym for partitioning, especially when done at the application level is &amp;#8220;sharding&amp;#8221;) by using either hashing or range based partitioning, such that one or more partitions could be assigned to a primary physical location.&lt;/p&gt;
&lt;p&gt;Since data is spread across several nodes, assuming a uniform key and request distribution, the system scales linearly to multiple nodes. It could be also made elastic by using consistent hashing and/or virtual partitions. For availability and reliability, different types of replication can be used, placing the data at multiple physical locations.&lt;/p&gt;
&lt;p&gt;In case of independent failures, partitioning also provides &lt;em&gt;fault isolation&lt;/em&gt;: provided the system knows how to serve results from a partial dataset, only the partitions held by the failed nodes are affected.&lt;/p&gt;
&lt;h3&gt;What&amp;#8217;s next?&lt;/h3&gt;
&lt;p&gt;We&amp;#8217;re now left with an important series of questions, related to maintenance or recovery of availability (including maintaining latency) for the affected partitions in case of various failure and high-load scenarios.&lt;/p&gt;
&lt;p&gt;Various approaches and the systems that take them will be discussed in the next post: &amp;#8220;Alternatives to total transactional replication&amp;#8221;. As this detour ends and the journey continues, pay attention to how the various theoretical approaches and real-world systems work in situations such as:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Providing availability under failure. This shouldn&amp;#8217;t be seen as simple either/or trade-off, but rather on a sliding scale, ranging from responses to simpler (non-correlated, of individual nodes) to more complex (correlated failures, potentially of majority of nodes, split-brain scenarios) failures&lt;/li&gt;
	&lt;li&gt;Adding a new node to either expand capacity (elasticity) or take place of a node that failed (recovery), or recovering a node from a temporary failure&lt;/li&gt;
	&lt;li&gt;Handling high write throughput and contention&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next post will also look at impact (or, at times, non-impact) of scalability, atomicity and reliability (non-functional requirements) upon functional requirements such as support for ordered operations and atomicity.&lt;/p&gt;
&lt;h3&gt;Contributions&lt;/h3&gt;
&lt;p&gt;Thanks to Ted Nyman (&lt;a href=&quot;http://twitter.com/#!/tnm&quot;&gt;@tnm&lt;/a&gt;), Jeff Hodges (&lt;a href=&quot;http://twitter.com/jmhodges&quot;&gt;@jmhodges&lt;/a&gt;), Justin Sheehy (&lt;a href=&quot;http://twitter.com/justinsheehy&quot;&gt;@justinsheehy&lt;/a&gt;), &lt;a href=&quot;http://danweinreb.org/blog/&quot;&gt;Daniel Weinreb&lt;/a&gt;, &lt;a href=&quot;http://www.cs.berkeley.edu/~palvaro/&quot;&gt;Peter Alvaro&lt;/a&gt;, Dave Fayram (&lt;a href=&quot;http://twitter.com/KirinDave&quot;&gt;@KirinDave&lt;/a&gt;), &lt;a href=&quot;http://anil.recoil.org/&quot;&gt;Anil Madhavapeddy&lt;/a&gt;, &lt;a href=&quot;http://neilconway.org/&quot;&gt;Neil Conway&lt;/a&gt;  and C. Scott Andreas (&lt;a href=&quot;https://twitter.com/#!/cscotta&quot;&gt;@cscotta&lt;/a&gt;) for proof-reading and editing this post.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Replication, atomicity and order in distributed systems</title>
   <link href="http://afeinberg.github.com/2011/06/17/replication-atomicity-and-order-in-distributed-systems.html"/>
   <updated>2011-06-17T00:00:00-07:00</updated>
   <id>http://afeinberg.github.com/2011/06/17/replication-atomicity-and-order-in-distributed-systems</id>
   <content type="html">&lt;h1&gt;Replication, atomicity and order in distributed systems&lt;/h1&gt;
&lt;p&gt;Distributed systems are an increasingly important topic in Computer Science. The difficulty and immediate applicability of this topic is what makes distributed systems rewarding to study and build.&lt;/p&gt;
&lt;p&gt;The goal of this post (and future posts on this topic) is to help the reader develop a basic toolkit they could use to reason about distributed systems. The toolkit should help the reader see the well known patterns in the specific problems they&amp;#8217;re solving, to identify the cases where others have already solved the problems they&amp;#8217;re facing and to understand the cases where solving hundred percent of the problem may not be worth the effort.&lt;/p&gt;
&lt;h2&gt;Leaving a Newtonian universe&lt;/h2&gt;
&lt;p&gt;For the most part, a single machine is a Newtonian universe: that is, we have a single frame of reference. As a result, we can impose a total &lt;em&gt;Happened-Before&lt;/em&gt; order on events i.e., we can &lt;em&gt;always&lt;/em&gt; tell that one event happened before another event. Communication can happen over shared memory, access to which can be synchronized through locks and memory barriers&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;When we move to a client and server architecture, message passing architecture is required. In the case of a single server (with one or more clients), we can still maintain an illusion of a Newtonian universe: &lt;span class=&quot;caps&quot;&gt;TCP&lt;/span&gt; (the transport layer used by popular application protocols) gives a guarantee that packets will be delivered to the server in the order sent by the client. As we&amp;#8217;ll later see, this guarantee can be used as a powerful primitive upon which more complex guarantees can be buit.&lt;/p&gt;
&lt;p&gt;However, there are reasons why we no longer want to run an application on a single server: in recent times it has become consensus that &lt;strong&gt;reliability&lt;/strong&gt;, &lt;strong&gt;availability&lt;/strong&gt; and &lt;strong&gt;scalability&lt;/strong&gt; are best obtained using multiple machines. Mission critical applications must at least maintain reliability and availability; in the case of consumer (and even many enterprise) web applications, with success often come scalability challenges. Thus, it&amp;#8217;s inevitable that we leave Newton&amp;#8217;s universe and enter Einstein&amp;#8217;s&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn1&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; This is not to belittle the fascinating challenges of building parallel shared memory systems: the topic is merely very well covered and outside of this post. I highly recommend &lt;em&gt;The Art of Multiprocessor Programming&lt;/em&gt; (by Maurice Herlihy) and &lt;em&gt;Java Concurrency In Practice&lt;/em&gt; (Goetz, Lea et al) to those interested in shared memory concurrency.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn2&quot;&gt;&lt;sup&gt;2&lt;/sup&gt; The comparison with theory of relativity is not original: Leslie Lamport and &lt;a href=&quot;http://blogs.msdn.com/b/pathelland/&quot;&gt;Pat Helland&lt;/a&gt; have used this comparison. Several concepts in distributed systems such as Vector Clocks and Lamport Timestamps are explicitly inspired by relativity.&lt;/p&gt;
&lt;h2&gt;Intuitive formulation of the problem&lt;/h2&gt;
&lt;p&gt;Suppose we have a group of (physical or logical) nodes: perhaps replicas of a partition (aka a &lt;em&gt;shard&lt;/em&gt;) of a &lt;a href=&quot;http://en.wikipedia.org/wiki/Shared%20nothing&quot;&gt;shared nothing&lt;/a&gt; database, a group of workstations collaborating on a document or a set of servers running a stateful business application for one specific customer. Another group of nodes (which may or may not overlap with the first group of nodes) is sending messages to the first group. In the case of a collaborative editor, a sample message could be &amp;#8220;insert this line into paragraph three of the document&amp;#8221;. Naturally, we would like these messages delivered to all available machines in the first group.&lt;/p&gt;
&lt;p&gt;Question is, how do we ensure, that after the messages are delivered to all machines, that the machines remain in the same state? In the case of our collaborative editor application, suppose Bob is watching Alice type over the shoulder and sees her type &amp;#8220;The&amp;#8221; and types &amp;#8220;quick brown fox&amp;#8221; after: we&amp;#8217;d like all instances of the collaborative editor to say &amp;#8220;The quick brown fox&amp;#8221; and not &amp;#8220;quick brown fox The&amp;#8221;; nor do we want messages delivered multiple times &lt;em&gt;e.g.,&lt;/em&gt; not &amp;#8220;The The quick brown fox&amp;#8221; and especially not &amp;#8220;The quick brown fox The&amp;#8221;!&lt;/p&gt;
&lt;p&gt;We&amp;#8217;d like (or, in many cases, require) that if one of the servers goes down, the accumulated state is not lost (reliability). We&amp;#8217;d also like to be able to view the state in the case of server failures (read availability) as well as continue sending messages (write availability). When a node fails, we&amp;#8217;d also like to be able to add a new node to take its place (restoring its state from other replicas). Ideally, we&amp;#8217;d like the later process to be as dynamic as possible.&lt;/p&gt;
&lt;p&gt;All of this should have reasonable performance guarantees. In the case of the collaborative editor, we&amp;#8217;d like characters to appear on the screen seemingly immediately after they are typed; in the case of the shared nothing database, we&amp;#8217;d like to reason about performance not too differently from how we reason about single node database performance i.e., determined (in terms of both &lt;em&gt;throughput&lt;/em&gt; and &lt;em&gt;latency&lt;/em&gt;) primarily by the &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt;, memory, disks and ethernet. In many cases we&amp;#8217;d like our distributed systems to even perform better than analogous single node systems (by allowing operations to be spread across multiple nodes), especially under high load.&lt;/p&gt;
&lt;p&gt;Problem is, however, that &lt;em&gt;these goals are often contradictory&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;State machines, atomic multicast and consensus&lt;/h2&gt;
&lt;p&gt;An approach commonly used to implement this sort of behavior is &lt;a href=&quot;http://en.wikipedia.org/wiki/State%20machine%20replication&quot;&gt;state machine replication&lt;/a&gt;. This was first proposed by Leslie Lamport (also known as the author of LaTeX), in the paper &lt;a href=&quot;http://research.microsoft.com/en-us/um/people/lamport/pubs/pubs.html#time-clocks&quot;&gt;&lt;em&gt;Time, Clocks and the Ordering of Events in a Distributed System&lt;/em&gt;&lt;/a&gt;. The idea is that if we model each node in a distributed system as a state machine, and send the same input (messages) in the same order to each state machine, we will end up in the same final state.&lt;/p&gt;
&lt;p&gt;This leads to our next question: how do we ensure that the same messages are sent to each machine, in the same order? This problem is known as &lt;a href=&quot;http://en.wikipedia.org/wiki/Atomic%20broadcast&quot;&gt;&lt;em&gt;atomic broadcast&lt;/em&gt;&lt;/a&gt; or more generally &lt;em&gt;atomic multicast&lt;/em&gt;. We should take special care to distinguish this from the &lt;a href=&quot;http://en.wikipedia.org/wiki/IP%20multicast&quot;&gt;IP multicast protocol&lt;/a&gt; which makes no guarantees about order or reliability of messages: &lt;span class=&quot;caps&quot;&gt;UDP&lt;/span&gt;, rather than &lt;span class=&quot;caps&quot;&gt;TCP&lt;/span&gt; is layered on top of it.&lt;/p&gt;
&lt;p&gt;A better way to view atomic multicast is a as a special case of the publish subscribe pattern (used by message queing systems such as &lt;a href=&quot;http://activemq.apache.org&quot;&gt;ActiveMQ&lt;/a&gt;, &lt;a href=&quot;http://www.rabbitmq.com&quot;&gt;RabbitMQ&lt;/a&gt;, &lt;a href=&quot;http://sna-projects.com/kafka/&quot;&gt;Kafka&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Virtual%20synchrony&quot;&gt;Virtual Synchrony&lt;/a&gt; based systems such as &lt;a href=&quot;http://www.jgroups.org/&quot;&gt;JGroups&lt;/a&gt; and &lt;a href=&quot;http://www.spread.org/&quot;&gt;Spread&lt;/a&gt; &lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;).&lt;/p&gt;
&lt;p&gt;A generalization of this problem is the distributed transaction problem: how we do ensure that either all the nodes execute the exact same transaction (executing all operations in the same order), or none do?&lt;/p&gt;
&lt;p&gt;Traditionally &lt;a href=&quot;http://en.wikipedia.org/wiki/Two%20phase%20commit&quot;&gt;two phase commit&lt;/a&gt; (2PC) algorithm has been used for distributed transactions. The problem with two phase commit is that it isn&amp;#8217;t fault tolerant: if the coordinator node fails, the process is blocked until the coordinator is repaired (&lt;a href=&quot;http://research.microsoft.com/apps/pubs/default.aspx?id=64636&quot;&gt;Consensus on Transaction Commit&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Consensus%20(computer%20science)&quot;&gt;&lt;em&gt;Consensus&lt;/em&gt;&lt;/a&gt; algorithms solve the problem of how multiples nodes could arrive at a commonly accepted value in the process of failures. We can use consensus algorithm to build fault tolerant distributed commit protocols by (this is somewhat of an over-simplification) having nodes &amp;#8220;decide&amp;#8221; whether or not a transaction has been committed or aborted.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn3&quot;&gt;&lt;sup&gt;3&lt;/sup&gt; Virtual synchrony (making asynchronous systems appear as synchronous) is itself a research topic that is closesly related to and at times complemented by consensus work. Ken Birman&amp;#8217;s group at Cornell has done a great deal of work on it. Unfortunately, it was difficult to work much of this fascinating research into a high level blog post.&lt;/p&gt;
&lt;h3&gt;Theoretic impossibility, practical possibility&lt;/h3&gt;
&lt;p&gt;Problem is that it&amp;#8217;s impossible to construct a fault tolerant consensus algorithm that will terminate in a guaranteed time-bound in an asynchronous system lacking a common clock: this is known (after the Fisher, Lynch, Patterson) as the &lt;a href=&quot;http://portal.acm.org/citation.cfm?doid=3149.214121&quot;&gt;&lt;span class=&quot;caps&quot;&gt;FLP&lt;/span&gt; impossibility result&lt;/a&gt;. Eric Brewer&amp;#8217;s &lt;a href=&quot;http://en.wikipedia.org/wiki/CAP%20theorem&quot;&gt;&lt;span class=&quot;caps&quot;&gt;CAP&lt;/span&gt; theorem&lt;/a&gt; (a &lt;a href=&quot;http://www.cloudera.com/blog/2010/04/cap-confusion-problems-with-partition-tolerance/&quot;&gt;well covered&lt;/a&gt; &lt;a href=&quot;http://codahale.com/you-cant-sacrifice-partition-tolerance/&quot;&gt;topic&lt;/a&gt;) can be argued to be an elegant and intuitive re-statement of the &lt;span class=&quot;caps&quot;&gt;FLP&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;In practice, however, consensus algorithms can be constructed with reasonable liveness properties. It does, however, imply that consensus should be limited in its applications.&lt;/p&gt;
&lt;p&gt;One thing to note is that consensus protocols can typically handle simple or clean failures (failures of minority of nodes), at the cost of greater latency: handling more complex (split brain scenarios) where a &lt;a href=&quot;http://en.wikipedia.org/wiki/Quorum%20(Distributed%20Systems)&quot;&gt;quorum&lt;/a&gt; can&amp;#8217;t be reached is more difficult.&lt;/p&gt;
&lt;h4&gt;Paxos and &lt;span class=&quot;caps&quot;&gt;ZAB&lt;/span&gt; (Chubby and ZooKeeper)&lt;/h4&gt;
&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Paxos%20algorithm&quot;&gt;Paxos&lt;/a&gt; Consensus and Commit protocols are well known and are seeing greater production use. A detailed discussions of these algorithms is outside the scope of this post, but it should be mentioned that practical Paxos implementations have somewhat modified the algorithms to allow for greater liveness and performance.&lt;/p&gt;
&lt;p&gt;Google&amp;#8217;s &lt;a href=&quot;http://labs.google.com/papers/chubby.html&quot;&gt;Chubby&lt;/a&gt; service is a practical example of a Paxos based system. Chubby provides a file system-like interface and is meant to be used for locks, leases and leader elections. One example of use of Chubby (that will be discussed in further detail in the next post) is assigning mastership of partitions in a distributed database to individual nodes.&lt;/p&gt;
&lt;p&gt;Apache &lt;a href=&quot;http://zookeeper.apache.org/&quot;&gt;ZooKeeper&lt;/a&gt; is another practical example of a system built on a Paxos-like distributed commit protocol. In this case, the consensus problem is slightly modified: rather than assume a purely asynchronous network, the &lt;span class=&quot;caps&quot;&gt;TCP&lt;/span&gt; ordering guarantee is &lt;a href=&quot;http://portal.acm.org/citation.cfm?id=1529978&quot;&gt;taken advantage of&lt;/a&gt;. Like Chubby, ZooKeeper exposes a file-system like &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; and is frequently used for leader election, cluster membership services, service discovery and assigning ownership to partitions in shared nothing stateful distributed systems.&lt;/p&gt;
&lt;h3&gt;Limitations of total transactional replication&lt;/h3&gt;
&lt;p&gt;A question arises: why is transactional replication only used for applications such as cluster membership, leader elections and lock managers? Why aren&amp;#8217;t these algorithms used for building distributed applications e.g., databases themselves? Wouldn&amp;#8217;t we all like a fully transactional, fault tolerant, multi-master distributed database? Wouldn&amp;#8217;t we like message queues that promise to deliver exactly the same messages, to exactly the same nodes, in exactly the same order, delivering each message exactly once at the exact same time?&lt;/p&gt;
&lt;p&gt;The above mentioned &lt;span class=&quot;caps&quot;&gt;FLP&lt;/span&gt; impossibility result provides one limitation of these systems: many practical systems require tight latency guarantees in even in the light of machine and network failures. &lt;a href=&quot;http://research.microsoft.com/apps/pubs/default.aspx?id=68247&quot;&gt;&lt;em&gt;The Dangers of Replication and a Solution&lt;/em&gt;&lt;/a&gt; also discusses scalability issues such as increases in network traffic, potential deadlocks in what the authors called &amp;#8220;anywhere-anytime-anyway transactional replication&amp;#8221;.&lt;/p&gt;
&lt;p&gt;In the case of Chubby and ZooKeeper, this is less of an issue: in a well designed distributed system, cluster membership and partition ownership changes are less frequent than updates themselves (much lower throughput, less of a scalability challenge) and are less sensitive to latency. Finally, by limiting our interaction with consensus based systems, we are able to limit the impact of scenarios of where consensus can&amp;#8217;t be reached due to machine, software or network failures.&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s next?&lt;/h2&gt;
&lt;p&gt;The next post will look at common alternatives to total transactional replication as well as several (relatively recent) papers and systems that &lt;em&gt;do&lt;/em&gt; apply some transactional replication techniques at scale.&lt;/p&gt;</content>
 </entry>
 
 
</feed>