| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8" /> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> |
| <meta name="description" content="A new open source Apache Hadoop ecosystem project, Apache Kudu (incubating) completes Hadoop's storage layer to enable fast analytics on fast data" /> |
| <meta name="author" content="Cloudera" /> |
| <title>Apache Kudu (incubating) - Using Raft Consensus on a Single Node</title> |
| <!-- Bootstrap core CSS --> |
| <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" |
| integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" |
| crossorigin="anonymous"> |
| |
| <!-- Custom styles for this template --> |
| <link href="/css/justified-nav.css" rel="stylesheet" /> |
| |
| <link href="/css/kudu.css" rel="stylesheet"/> |
| <link href="/css/asciidoc.css" rel="stylesheet"/> |
| <link rel="shortcut icon" href="/img/logo-favicon.ico" /> |
| <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css" /> |
| |
| |
| <link rel="alternate" type="application/atom+xml" |
| title="RSS Feed for Apache Kudu blog" |
| href="/feed.xml" /> |
| |
| |
| <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> |
| <!--[if lt IE 9]> |
| <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> |
| <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> |
| <![endif]--> |
| </head> |
| <body> |
| <!-- Fork me on GitHub --> |
| <a class="fork-me-on-github" href="https://github.com/apache/incubator-kudu"><img src="//aral.github.io/fork-me-on-github-retina-ribbons/right-cerulean@2x.png" alt="Fork me on GitHub" /></a> |
| |
| <div class="kudu-site container-fluid"> |
| <!-- Static navbar --> |
| <nav class="container-fluid navbar-default"> |
| <div class="navbar-header"> |
| <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> |
| <span class="sr-only">Toggle navigation</span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| </button> |
| |
| <a class="logo" href="/"><img src="/img/logo_small.png" width="80" /></a> |
| |
| </div> |
| <div id="navbar" class="navbar-collapse collapse navbar-right"> |
| <ul class="nav navbar-nav"> |
| <li > |
| <a href="/">Home</a> |
| </li> |
| <li > |
| <a href="/overview.html">Overview</a> |
| </li> |
| <li > |
| <a href="/docs/">Documentation</a> |
| </li> |
| <li > |
| <a href="/releases/">Download</a> |
| </li> |
| <li class="active"> |
| <a href="/blog/">Blog</a> |
| </li> |
| <li > |
| <a href="/community.html">Community</a> |
| </li> |
| <li > |
| <a href="/faq.html">FAQ</a> |
| </li> |
| </ul> |
| </div><!--/.nav-collapse --> |
| </nav> |
| |
| <div class="row header"> |
| <div class="col-lg-12"> |
| <h2><a href="/blog">Apache Kudu (incubating) Blog</a></h2> |
| </div> |
| </div> |
| |
| <div class="row-fluid"> |
| <div class="col-lg-9"> |
| <article> |
| <header> |
| <h1 class="entry-title">Using Raft Consensus on a Single Node</h1> |
| <p class="meta">Posted 17 Jun 2016 by Mike Percy</p> |
| </header> |
| <div class="entry-content"> |
| <p>As Kudu marches toward its 1.0 release, which will include support for |
| multi-master operation, we are working on removing old code that is no longer |
| needed. One such piece of code is called LocalConsensus. Once LocalConsensus is |
| removed, we will be using Raft consensus even on Kudu tables that have a |
| replication factor of 1.</p> |
| |
| <!--more--> |
| |
| <p>Using Raft consensus in single-node cases is important for multi-master |
| support because it will allow people to dynamically increase their Kudu |
| cluster’s existing master server replication factor from 1 to many (3 or 5 are |
| typical).</p> |
| |
| <h1 id="the-consensus-interface">The Consensus interface</h1> |
| |
| <p>In Kudu, the |
| <a href="https://github.com/apache/incubator-kudu/blob/branch-0.9.x/src/kudu/consensus/consensus.h">Consensus</a> |
| interface was created as an abstraction to allow us to build the plumbing |
| around how a consensus implementation would interact with the underlying |
| tablet. We were able to build out this “scaffolding” long before our Raft |
| implementation was complete.</p> |
| |
| <p>The Consensus API has the following main responsibilities:</p> |
| |
| <ol> |
| <li>Support acting as a Raft <code>LEADER</code> and replicate writes to a local |
| write-ahead log (WAL) as well as followers in the Raft configuration. For |
| each operation written to the leader, a Raft implementation must keep track |
| of how many nodes have written a copy of the operation being replicated, and |
| whether or not that constitutes a majority. Once a majority of the nodes |
| have written a copy of the data, it is considered committed.</li> |
| <li>Support acting as a Raft <code>FOLLOWER</code> by accepting writes from the leader and |
| preparing them to be eventually committed.</li> |
| <li>Support voting in and initiating leader elections.</li> |
| <li>Support participating in and initiating configuration changes (such as going |
| from a replication factor of 3 to 4).</li> |
| </ol> |
| |
| <p>The first implementation of the Consensus interface was called LocalConsensus. |
| LocalConsensus only supported acting as a leader of a single-node configuration |
| (hence the name “local”). It could not replicate to followers, participate in |
| elections, or change configurations. These limitations have led us to |
| <a href="https://gerrit.cloudera.org/3350">remove</a> LocalConsensus from the code base |
| entirely.</p> |
| |
| <p>Because Kudu has a full-featured Raft implementation, Kudu’s RaftConsensus |
| supports all of the above functions of the Consensus interface.</p> |
| |
| <h1 id="using-a-single-node-raft-configuration">Using a Single-node Raft configuration</h1> |
| |
| <p>A common question on the Raft mailing lists is: “Is it even possible to use |
| Raft on a single node?” The answer is yes.</p> |
| |
| <p>Fundamentally, Raft works by first electing a leader that is responsible for |
| replicating write operations to the other members of the configuration. In |
| order to elect a leader, Raft requires a (strict) majority of the voters to |
| vote “yes” in an election. When there is only a single eligible node in the |
| configuration, there is no chance of losing the election. Raft specifies that |
| when starting an election, a node must first vote for itself and then contact |
| the rest of the voters to tally their votes. If there is only a single node, no |
| communication is required and an election succeeds instantaneously.</p> |
| |
| <p>So, when does it make sense to use Raft for a single node?</p> |
| |
| <p>It makes sense to do this when you want to allow growing the replication factor |
| in the future. This is something that Kudu needs to support. When deploying |
| Kudu, someone may wish to test it out with limited resources in a small |
| environment. Eventually, they may wish to transition that cluster to be a |
| staging or production environment, which would typically require the fault |
| tolerance achievable with multi-node Raft. Without a consensus implementation |
| that supports configuration changes, there would be no way to gracefully |
| support this. Because single-node Raft supports dynamically adding an |
| additional node to its configuration, it is possible to go from one replica to |
| 2 and then 3 replicas and end up with a fault-tolerant cluster without |
| incurring downtime.</p> |
| |
| <h1 id="more-about-raft">More about Raft</h1> |
| |
| <p>To learn more about how Kudu uses Raft consensus, you may find the relevant |
| <a href="https://github.com/apache/incubator-kudu/blob/master/docs/design-docs/README.md">design docs</a> |
| interesting. In the future, we may also post more articles on the Kudu blog |
| about how Kudu uses Raft to achieve fault tolerance.</p> |
| |
| <p>To learn more about the Raft protocol itself, please see the <a href="https://raft.github.io/">Raft consensus |
| home page</a>. The design of Kudu’s Raft implementation |
| is based on the extended protocol described in Diego Ongaro’s Ph.D. |
| dissertation, which you can find linked from the above web site.</p> |
| |
| </div> |
| </article> |
| |
| |
| </div> |
| <div class="col-lg-3 recent-posts"> |
| <h3>Recent posts</h3> |
| <ul> |
| |
| <li> <a href="/2016/07/18/weekly-update.html">Apache Kudu (incubating) Weekly Update July 18, 2016</a> </li> |
| |
| <li> <a href="/2016/07/11/weekly-update.html">Apache Kudu (incubating) Weekly Update July 11, 2016</a> </li> |
| |
| <li> <a href="/2016/07/01/apache-kudu-0-9-1-released.html">Apache Kudu (incubating) 0.9.1 released</a> </li> |
| |
| <li> <a href="/2016/06/27/weekly-update.html">Apache Kudu (incubating) Weekly Update June 27, 2016</a> </li> |
| |
| <li> <a href="/2016/06/24/multi-master-1-0-0.html">Master fault tolerance in Kudu 1.0</a> </li> |
| |
| <li> <a href="/2016/06/21/weekly-update.html">Apache Kudu (incubating) Weekly Update June 21, 2016</a> </li> |
| |
| <li> <a href="/2016/06/17/raft-consensus-single-node.html">Using Raft Consensus on a Single Node</a> </li> |
| |
| <li> <a href="/2016/06/13/weekly-update.html">Apache Kudu (incubating) Weekly Update June 13, 2016</a> </li> |
| |
| <li> <a href="/2016/06/10/apache-kudu-0-9-0-released.html">Apache Kudu (incubating) 0.9.0 released</a> </li> |
| |
| <li> <a href="/2016/06/06/weekly-update.html">Apache Kudu (incubating) Weekly Update June 6, 2016</a> </li> |
| |
| <li> <a href="/2016/06/02/no-default-partitioning.html">Default Partitioning Changes Coming in Kudu 0.9</a> </li> |
| |
| <li> <a href="/2016/06/01/weekly-update.html">Apache Kudu (incubating) Weekly Update June 1, 2016</a> </li> |
| |
| <li> <a href="/2016/05/23/weekly-update.html">Apache Kudu (incubating) Weekly Update May 23, 2016</a> </li> |
| |
| <li> <a href="/2016/05/16/weekly-update.html">Apache Kudu (incubating) Weekly Update May 16, 2016</a> </li> |
| |
| <li> <a href="/2016/05/09/weekly-update.html">Apache Kudu (incubating) Weekly Update May 9, 2016</a> </li> |
| |
| </ul> |
| </div> |
| </div> |
| |
| <footer class="footer"> |
| <p class="pull-left"> |
| <a href="http://incubator.apache.org"><img src="/img/apache-incubator.png" width="225" height="53" align="right"/></a> |
| </p> |
| <p class="small"> |
| Apache Kudu (incubating) is an effort undergoing incubation at the Apache Software |
| Foundation (ASF), sponsored by the Apache Incubator PMC. Incubation is |
| required of all newly accepted projects until a further review |
| indicates that the infrastructure, communications, and decision making |
| process have stabilized in a manner consistent with other successful |
| ASF projects. While incubation status is not necessarily a reflection |
| of the completeness or stability of the code, it does indicate that the |
| project has yet to be fully endorsed by the ASF. |
| |
| Copyright © 2016 The Apache Software Foundation. |
| </p> |
| </footer> |
| </div> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> |
| <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" |
| integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" |
| crossorigin="anonymous"></script> |
| <script> |
| (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ |
| (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), |
| m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) |
| })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); |
| |
| ga('create', 'UA-68448017-1', 'auto'); |
| ga('send', 'pageview'); |
| </script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/3.1.0/anchor.js"></script> |
| <script> |
| anchors.options = { |
| placement: 'right', |
| visible: 'touch', |
| }; |
| anchors.add(); |
| </script> |
| </body> |
| </html> |
| |