1.`action`: the action of the request that was just made.
The request attempted to modify `node.value` via a `PUT` HTTP request, thus the value of action is `set`.
2.`node.key`: the HTTP path to which the request was made.
We set `/message` to `Hello world`, so the key field is `/message`.
etcd uses a file-system-like structure to represent the key-value pairs, therefore all keys start with `/`.
3.`node.value`: the value of the key after resolving the request.
In this case, a successful request was made that attempted to change the node's value to `Hello world`.
4.`node.createdIndex`: an index is a unique, monotonically-incrementing integer created for each change to etcd.
This specific index reflects the point in the etcd state member at which a given key was created.
You may notice that in this example the index is `2` even though it is the first request you sent to the server.
This is because there are internal commands that also change the state behind the scenes, like adding and syncing servers.
5.`node.modifiedIndex`: like `node.createdIndex`, this attribute is also an etcd index.
Actions that cause the value to change include `set`, `delete`, `update`, `create`, `compareAndSwap` and `compareAndDelete`.
Since the `get` and `watch` commands do not change state in the store, they do not change the value of `node.modifiedIndex`.
### Response Headers
etcd includes a few HTTP headers in responses that provide global information about the etcd cluster that serviced a request:
```
X-Etcd-Index: 35
X-Raft-Index: 5398
X-Raft-Term: 1
```
*`X-Etcd-Index` is the current etcd index as explained above. When request is a watch on key space, `X-Etcd-Index` is the current etcd index when the watch starts, which means that the watched event may happen after `X-Etcd-Index`.
*`X-Raft-Index` is similar to the etcd index but is for the underlying raft protocol.
*`X-Raft-Term` is an integer that will increase whenever an etcd master election happens in the cluster. If this number is increasing rapidly, you may need to tune the election timeout. See the [tuning][tuning] section for details.
### Get the value of a key
We can get the value that we just set in `/message` by issuing a `GET` request:
```sh
curl http://127.0.0.1:2379/v2/keys/message
```
```json
{
"action": "get",
"node": {
"createdIndex": 2,
"key": "/message",
"modifiedIndex": 2,
"value": "Hello world"
}
}
```
### Changing the value of a key
You can change the value of `/message` from `Hello world` to `Hello etcd` with another `PUT` request to the key:
Here we introduce a new field: `prevNode`. The `prevNode` field represents what the state of a given node was before resolving the request at hand. The `prevNode` field follows the same format as the `node`, and is omitted in the event that there was no previous state for a given node.
### Deleting a key
You can remove the `/message` key with a `DELETE` request:
We get the index is outdated response, since we miss the 1000 events kept in etcd.
```
{"errorCode":401,"message":"The event in requested index is outdated and cleared","cause":"the requested history has been cleared [1008/8]","index":2007}
```
To start watch, first we need to fetch the current state of key `/foo`:
etcd can be used as a centralized coordination service in a cluster, and `CompareAndSwap` (CAS) is the most basic operation used to build a distributed lock service.
This command will set the value of a key only if the client-provided conditions are equal to the current conditions.
*Note that `CompareAndSwap` does not work with [directories][directories]. If an attempt is made to `CompareAndSwap` a directory, a 102 "Not a file" error will be returned.*
The current comparable conditions are:
1.`prevValue` - checks the previous value of the key.
2.`prevIndex` - checks the previous modifiedIndex of the key.
3.`prevExist` - checks existence of the key: if `prevExist` is true, it is an `update` request; if `prevExist` is `false`, it is a `create` request.
This will try to compare the previous value of the key and the previous value we provided. If they are equal, the value of the key will change to three.
```json
{
"cause": "[two != one]",
"errorCode": 101,
"index": 8,
"message": "Compare failed"
}
```
which means `CompareAndSwap` failed. `cause` explains why the test failed.
We successfully changed the value from "one" to "two" since we gave the correct previous value.
### Atomic Compare-and-Delete
This command will delete a key only if the client-provided conditions are equal to the current conditions.
*Note that `CompareAndDelete` does not work with [directories]. If an attempt is made to `CompareAndDelete` a directory, a 102 "Not a file" error will be returned.*
The current comparable conditions are:
1.`prevValue` - checks the previous value of the key.
2.`prevIndex` - checks the previous modifiedIndex of the key.
Here is a simple example. Let's first create a key: `foo=one`.
If you want a read that is fully linearized you can use a `quorum=true` GET.
The read will take a very similar path to a write and will have a similar
speed. If you are unsure if you need this feature feel free to email etcd-dev
for advice.
## Statistics
An etcd cluster keeps track of a number of statistics including latency, bandwidth and uptime.
These are exposed via the statistics endpoint to understand the internal health of a cluster.
### Leader Statistics
The leader has a view of the entire cluster and keeps track of two interesting statistics: latency to each peer in the cluster, and the number of failed and successful Raft RPC requests.
You can grab these statistics from the `/v2/stats/leader` endpoint:
```sh
curl http://127.0.0.1:2379/v2/stats/leader
```
```json
{
"followers": {
"6e3bd23ae5f1eae0": {
"counts": {
"fail": 0,
"success": 745
},
"latency": {
"average": 0.017039507382550306,
"current": 0.000138,
"maximum": 1.007649,
"minimum": 0,
"standardDeviation": 0.05289178277920594
}
},
"a8266ecf031671f3": {
"counts": {
"fail": 0,
"success": 735
},
"latency": {
"average": 0.012124141496598642,
"current": 0.000559,
"maximum": 0.791547,
"minimum": 0,
"standardDeviation": 0.04187900156583733
}
}
},
"leader": "924e2e83e93f2560"
}
```
### Self Statistics
Each node keeps a number of internal statistics:
-`id`: the unique identifier for the member
-`leaderInfo.leader`: id of the current leader member
-`leaderInfo.uptime`: amount of time the leader has been leader
-`name`: this member's name
-`recvAppendRequestCnt`: number of append requests this node has processed
-`recvBandwidthRate`: number of bytes per second this node is receiving (follower only)
-`recvPkgRate`: number of requests per second this node is receiving (follower only)
-`sendAppendRequestCnt`: number of requests that this node has sent
-`sendBandwidthRate`: number of bytes per second this node is sending (leader only). This value is undefined on single member clusters.
-`sendPkgRate`: number of requests per second this node is sending (leader only). This value is undefined on single member clusters.
-`state`: either leader or follower
-`startTime`: the time when this node was started
This is an example response from a follower member: