Merge pull request #518 from larsks/master

updates to leader election documentation
This commit is contained in:
Armon Dadgar 2014-12-05 18:59:39 -08:00
commit 165e282e1c
1 changed files with 76 additions and 17 deletions

View File

@ -17,6 +17,9 @@ cover all the possible methods. Instead, we will focus on using Consul's support
[sessions](/docs/internals/sessions.html), which allow us to build a system that can [sessions](/docs/internals/sessions.html), which allow us to build a system that can
gracefully handle failures. 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 ## Contending Nodes
The first flow we cover is for nodes who are attempting to acquire leadership The first flow we cover is for nodes who are attempting to acquire leadership
@ -27,33 +30,53 @@ key being used to coordinate. A good choice is simply:
service/<service name>/leader service/<service name>/leader
``` ```
We will refer to this as just `key` for simplicity. We will refer to this as just `<key>` for simplicity.
The first step is to create a session. This is done using the /v1/session/create endpoint. The first step is to create a session. This is done using the [/v1/session/create endpoint][session-api]:
The session by default makes use of only the gossip failure detector. Additional checks
can be specified if desired. The session ID returned will be referred to as `session`.
Create `body` to represent the local node. This can be a simple JSON object [session-api]: http://www.consul.io/docs/agent/http.html#_v1_session_create
that contains the node's name, port or any application specific information
that may be needed.
Attempt to `acquire` the `key` by doing a `PUT`. This is something like:
```text ```text
curl -X PUT -d body http://localhost:8500/v1/kv/key?acquire=session curl -X PUT -d '{"Name": "dbservice"}' \
http://localhost:8500/v1/session/create
``` ```
This will return a JSON object contain the session ID:
```text
{
"ID": "4ca8e74b-6350-7587-addf-a18084928f3c"
}
```
The session by default makes use of only the gossip failure detector. Additional checks
can be specified if desired.
Create `<body>` to represent the local node. This value is opaque to
Consul and 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 `<key>` by doing a `PUT`. This is something like:
```text
curl -X PUT -d <body> http://localhost:8500/v1/kv/<key>?acquire=<session>
```
Where `<session>` is the ID returned by the call to
`/v1/session/create`.
This will either return `true` or `false`. If `true` is returned, the lock 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, has been acquired and the local node is now the leader. If `false` is returned,
some other node has acquired the lock. some other node has acquired the lock.
All nodes now remain in an idle waiting state. In this state, we watch for changes All nodes now remain in an idle waiting state. In this state, we watch for changes
on `key`. This is because the lock may be released, the node may fail, etc. on `<key>`. 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 it's lock may be released by an operator,
or automatically released due to a false positive in the failure detector. or automatically released due to a false positive in the failure detector.
Watching for changes is done by doing a blocking query against `key`. If we ever Watching for changes is done by doing a blocking query against `<key>`. If we ever
notice that the `Session` of the `key` is blank, then there is no leader, and we should notice that the `Session` of the `<key>` 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 retry acquiring the lock. 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). wait. This is because Consul may be enforcing a [`lock-delay`](/docs/internals/sessions.html).
@ -61,7 +84,7 @@ If the leader ever wishes to step down voluntarily, this should be done by simpl
releasing the lock: releasing the lock:
```text ```text
curl -X PUT http://localhost:8500/v1/kv/key?release=session curl -X PUT http://localhost:8500/v1/kv/<key>?release=<session>
``` ```
## Discovering a Leader ## Discovering a Leader
@ -71,9 +94,45 @@ 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 being used to coordinate, including the contenders. This key will be referred
to as just `key`. to as just `key`.
Clients have a very simple role, they simply read `key` to discover who the current Clients have a very simple role, they simply read `<key>` to discover who the current
leader is. If the key has no associated `Session`, then there is no leader. Otherwise, leader is:
the value of the key will provide all the application-dependent information required.
```text
curl http://localhost:8500/v1/kv/<key>
[
{
"Session": "4ca8e74b-6350-7587-addf-a18084928f3c",
"Value": "Ym9keQ==",
"Flags": 0,
"Key": "<key>",
"LockIndex": 1,
"ModifyIndex": 29,
"CreateIndex": 29
}
]
```
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 blog in
the `Value` key. You can query the `/v1/session/info` endpoint to get
details about the session:
```text
curl http://localhost:8500/v1/session/info/4ca8e74b-6350-7587-addf-a18084928f3c
[
{
"LockDelay": 1.5e+10,
"Checks": [
"serfHealth"
],
"Node": "consul-master-bjsiobmvdij6-node-lhe5ihreel7y",
"Name": "dbservice",
"ID": "4ca8e74b-6350-7587-addf-a18084928f3c",
"CreateIndex": 28
}
]
```
Clients should also watch the key using a blocking query for any changes. If the leader 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, then the `Session` associated with the key will be cleared. When