diff --git a/website/source/docs/guides/leader-election.html.markdown b/website/source/docs/guides/leader-election.html.markdown index 0b26c5ff14..1a2f1fab80 100644 --- a/website/source/docs/guides/leader-election.html.markdown +++ b/website/source/docs/guides/leader-election.html.markdown @@ -3,45 +3,44 @@ layout: "docs" page_title: "Leader Election" sidebar_current: "docs-guides-leader" description: |- - The goal of this guide is to cover how to build client-side leader election using Consul. If you are interested in the leader election used internally to Consul, you want to read about the consensus protocol instead. + This guide describes how to build client-side leader election using Consul. If you are interested in the leader election used internally to Consul, please refer to the consensus protocol documentation instead. --- # Leader Election -The goal of this guide is to cover how to build client-side leader election using Consul. -If you are interested in the leader election used internally to Consul, you want to -read about the [consensus protocol](/docs/internals/consensus.html) instead. +This guide describes how to build client-side leader election using Consul. If you +are interested in the leader election used internally by Consul, please refer to the +[consensus protocol](/docs/internals/consensus.html) documentation instead. There are a number of ways that leader election can be built, so our goal is not to cover all the possible methods. Instead, we will focus on using Consul's support for -[sessions](/docs/internals/sessions.html), which allow us to build a system that can -gracefully handle failures. +[sessions](/docs/internals/sessions.html). Sessions allow us to build a system that +can gracefully handle failures. Note that JSON output in this guide has been pretty-printed for easier reading. Actual values returned from the API will not be formatted. ## Contending Nodes -The first flow we cover is for nodes who are attempting to acquire leadership +Let's imagine we have a set of nodes who are attempting to acquire leadership for a given service. All nodes that are participating should agree on a given -key being used to coordinate. A good choice is simply: +key to coordinate. A good pattern is simply: ```text service//leader ``` -We will refer to this as just `` for simplicity. +We'll abbreviate this pattern as simply `` for the rest of this guide. -The first step is to create a session. This is done using the [/v1/session/create endpoint][session-api]: - -[session-api]: http://www.consul.io/docs/agent/http.html#_v1_session_create +The first step is to create a session using the +[Session HTTP API](/docs/agent/http/session.html#session_create): ```text curl -X PUT -d '{"Name": "dbservice"}' \ http://localhost:8500/v1/session/create ``` -This will return a JSON object contain the session ID: +This will return a JSON object containing the session ID: ```text { @@ -49,35 +48,38 @@ This will return a JSON object contain the session ID: } ``` -The session by default makes use of only the gossip failure detector. Additional checks -can be specified if desired. - -Create `` to represent the local node. This value is opaque to -Consul and should contain whatever information clients require to +The next step is to acquire a session for a given key from this node +using the PUT method on a [KV entry](/docs/agent/http/kv.html) with the +"?acquire=\" query parameter. The `` of the PUT should be a +JSON object representing the local node. This value is opaque to +Consul, but it should contain whatever information clients require to communicate with your application (e.g., it could be a JSON object that contains the node's name and the application's port). -Attempt to `acquire` the `` by doing a `PUT`. This is something like: +Attempt to `acquire` the ``. This will look something like (note that +`` is the ID returned by the call to +[`/v1/session/create`](/docs/agent/http/session.html#session_create)): ```text curl -X PUT -d http://localhost:8500/v1/kv/?acquire= ``` -Where `` is the ID returned by the call to -`/v1/session/create`. - -This will either return `true` or `false`. If `true` is returned, the lock -has been acquired and the local node is now the leader. If `false` is returned, -some other node has acquired the lock. +This will either return `true` or `false`. If `true`, the lock has been acquired and +the local node is now the leader. If `false` is returned, some other node has acquired +the lock. All nodes now remain in an idle waiting state. In this state, we watch for changes on ``. This is because the lock may be released, the node may fail, etc. -The leader must also watch for changes since it's lock may be released by an operator, +The leader must also watch for changes since its lock may be released by an operator or automatically released due to a false positive in the failure detector. -Watching for changes is done by doing a blocking query against ``. If we ever -notice that the `Session` of the `` is blank, then there is no leader, and we should -retry acquiring the lock. Each attempt to acquire the key should be separated by a timed +Note that the session by default makes use of only the gossip failure detector. That +is, the session is considered held by a node as long as the default Serf health check +has not declared the node unhealthy. Additional checks can be specified if desired. + +Watching for changes is done via a blocking query against ``. If we ever +notice that the `Session` of the `` is blank, there is no leader, and we should +retry lock acquisition. Each attempt to acquire the key should be separated by a timed wait. This is because Consul may be enforcing a [`lock-delay`](/docs/internals/sessions.html). If the leader ever wishes to step down voluntarily, this should be done by simply @@ -89,10 +91,11 @@ curl -X PUT http://localhost:8500/v1/kv/?release= ## Discovering a Leader -The second flow is for nodes who are attempting to discover the leader -for a given service. All nodes that are participating should agree on the key -being used to coordinate, including the contenders. This key will be referred -to as just `key`. +Another common practice regarding leader election is for nodes to wish to identify the +leader for a given service. + +As with leader leader election, all nodes that are participating should agree on the key +being used to coordinate. This key will be referred to as just `key`. Clients have a very simple role, they simply read `` to discover who the current leader is: @@ -112,11 +115,12 @@ curl http://localhost:8500/v1/kv/ ] ``` -If the key has no associated `Session`, then there is no leader. -Otherwise, the value of the key will provide all the -application-dependent information required as a base64 encoded blob in -the `Value` key. You can query the `/v1/session/info` endpoint to get -details about the session: +If the key has no associated `Session`, then there is no leader. Otherwise, the value of +the key will provide all the application-dependent information required as a Base64 encoded +blob in the `Value` field. + +You can query the [`/v1/session/info`](/docs/agent/http/session.html#session_info) endpoint +to get details about the session: ```text curl http://localhost:8500/v1/session/info/4ca8e74b-6350-7587-addf-a18084928f3c @@ -135,5 +139,5 @@ curl http://localhost:8500/v1/session/info/4ca8e74b-6350-7587-addf-a18084928f3c ``` Clients should also watch the key using a blocking query for any changes. If the leader -steps down, or fails, then the `Session` associated with the key will be cleared. When +steps down or fails, the `Session` associated with the key will be cleared. When a new leader is elected, the key value will also be updated.