2016/06/17/raft-consensus-single-node.html (235 lines of code) (raw):

<!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 completes Hadoop's storage layer to enable fast analytics on fast data" /> <meta name="author" content="Cloudera" /> <title>Apache Kudu - Using Raft Consensus on a Single Node</title> <!-- Bootstrap core CSS --> <link rel="stylesheet" href="/css/bootstrap.min.css"/> <!-- Custom styles for this template --> <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="/css/font-awesome.min.css" /> <link rel="alternate" type="application/atom+xml" title="RSS Feed for Apache Kudu blog" href="/feed.xml" /> </head> <body> <div class="kudu-site container-fluid"> <!-- Static navbar --> <nav class="navbar navbar-default"> <div class="container-fluid"> <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/apachekudu_logo_0716_80px.png" srcset="/img/apachekudu_logo_0716_80px.png 1x, /img/apachekudu_logo_0716_160px.png 2x" alt="Apache Kudu"/></a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav navbar-right"> <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/">Releases</a> </li> <li class="active"> <a href="/blog/">Blog</a> </li> <!-- NOTE: this dropdown menu does not appear on Mobile, so don't add anything here that doesn't also appear elsewhere on the site. --> <li class="dropdown"> <a href="/community.html" role="button" aria-haspopup="true" aria-expanded="false">Community <span class="caret"></span></a> <ul class="dropdown-menu"> <li class="dropdown-header">GET IN TOUCH</li> <li><a class="icon email" href="/community.html">Mailing Lists</a></li> <li><a class="icon slack" href="https://join.slack.com/t/getkudu/shared_invite/zt-244b4zvki-hB1q9IbAk6CqHNMZHvUALA">Slack Channel</a></li> <li role="separator" class="divider"></li> <li><a href="/community.html#meetups-user-groups-and-conference-presentations">Events and Meetups</a></li> <li><a href="/committers.html">Project Committers</a></li> <li><a href="/ecosystem.html">Ecosystem</a></li> <!--<li><a href="/roadmap.html">Roadmap</a></li>--> <li><a href="/community.html#contributions">How to Contribute</a></li> <li role="separator" class="divider"></li> <li class="dropdown-header">DEVELOPER RESOURCES</li> <li><a class="icon github" href="https://github.com/apache/incubator-kudu">GitHub</a></li> <li><a class="icon gerrit" href="http://gerrit.cloudera.org:8080/#/q/status:open+project:kudu">Gerrit Code Review</a></li> <li><a class="icon jira" href="https://issues.apache.org/jira/browse/KUDU">JIRA Issue Tracker</a></li> <li role="separator" class="divider"></li> <li class="dropdown-header">SOCIAL MEDIA</li> <li><a class="icon twitter" href="https://twitter.com/ApacheKudu">Twitter</a></li> <li><a href="https://www.reddit.com/r/kudu/">Reddit</a></li> <li role="separator" class="divider"></li> <li class="dropdown-header">APACHE SOFTWARE FOUNDATION</li> <li><a href="https://www.apache.org/security/" target="_blank">Security</a></li> <li><a href="https://www.apache.org/foundation/sponsorship.html" target="_blank">Sponsorship</a></li> <li><a href="https://www.apache.org/foundation/thanks.html" target="_blank">Thanks</a></li> <li><a href="https://www.apache.org/licenses/" target="_blank">License</a></li> </ul> </li> <li > <a href="/faq.html">FAQ</a> </li> </ul><!-- /.nav --> </div><!-- /#navbar --> </div><!-- /.container-fluid --> </nav> <div class="row header"> <div class="col-lg-12"> <h2><a href="/blog">Apache Kudu 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 class="language-plaintext highlighter-rouge">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 class="language-plaintext highlighter-rouge">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="/2024/11/13/apache-kudu-1-17-1-release.html">Apache Kudu 1.17.1 Released</a> </li> <li> <a href="/2024/03/07/introducing-auto-incrementing-column.html">Introducing Auto-incrementing Column in Kudu</a> </li> <li> <a href="/2023/09/07/apache-kudu-1-17-0-released.html">Apache Kudu 1.17.0 Released</a> </li> <li> <a href="/2022/06/17/apache-kudu-1-16-0-released.html">Apache Kudu 1.16.0 Released</a> </li> <li> <a href="/2021/06/22/apache-kudu-1-15-0-released.html">Apache Kudu 1.15.0 Released</a> </li> <li> <a href="/2021/01/28/apache-kudu-1-14-0-release.html">Apache Kudu 1.14.0 Released</a> </li> <li> <a href="/2021/01/15/bloom-filter-predicate.html">Optimized joins & filtering with Bloom filter predicate in Kudu</a> </li> <li> <a href="/2020/09/21/apache-kudu-1-13-0-release.html">Apache Kudu 1.13.0 released</a> </li> <li> <a href="/2020/08/11/fine-grained-authz-ranger.html">Fine-Grained Authorization with Apache Kudu and Apache Ranger</a> </li> <li> <a href="/2020/07/30/building-near-real-time-big-data-lake.html">Building Near Real-time Big Data Lake</a> </li> <li> <a href="/2020/05/18/apache-kudu-1-12-0-release.html">Apache Kudu 1.12.0 released</a> </li> <li> <a href="/2019/11/20/apache-kudu-1-11-1-release.html">Apache Kudu 1.11.1 released</a> </li> <li> <a href="/2019/11/20/apache-kudu-1-10-1-release.html">Apache Kudu 1.10.1 released</a> </li> <li> <a href="/2019/07/09/apache-kudu-1-10-0-release.html">Apache Kudu 1.10.0 Released</a> </li> <li> <a href="/2019/04/30/location-awareness.html">Location Awareness in Kudu</a> </li> </ul> </div> </div> <footer class="footer"> <div class="row"> <div class="col-md-9"> <p class="small"> Copyright &copy; 2023 The Apache Software Foundation. </p> <p class="small"> Apache Kudu, Kudu, Apache, the Apache feather logo, and the Apache Kudu project logo are either registered trademarks or trademarks of The Apache Software Foundation in the United States and other countries. </p> </div> <div class="col-md-3"> <a class="pull-right" href="https://www.apache.org/events/current-event.html"> <img src="https://www.apache.org/events/current-event-234x60.png"/> </a> </div> </div> </footer> </div> <script src="/js/jquery.min.js"></script> <script> // Try to detect touch-screen devices. Note: Many laptops have touch screens. $(document).ready(function() { if ("ontouchstart" in document.documentElement) { $(document.documentElement).addClass("touch"); } else { $(document.documentElement).addClass("no-touch"); } }); </script> <script src="/js/bootstrap.min.js"></script> <script src="/js/anchor.js"></script> <script> anchors.options = { placement: 'right', visible: 'touch', }; anchors.add(); </script> </body> </html>