etcd v2文档(1) -- 单体服务端,客户端http请求api

时间:2022-06-26
本文章向大家介绍etcd v2文档(1) -- 单体服务端,客户端http请求api,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

开启一个服务端

也就是只开启一个服务端程序

./bin/etcd

什么参数都不加,那么etcd服务使用默认值。

IANA为etcd分配的端口是2379用于客户端通信2380用于服务器到服务器通信

获得服务端版本信息

发送http 请求获得版本信息

curl -L http://127.0.0.1:2379/version

set (key 空间操作)

etcd中的键是分层的,通常一个"/"分割一个节点(nodes),

设置数据存储区中的第一个键值对。 在这种情况下,键是/message,值为Hello world。

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="Hello world"
{
    "action": "set",
    "node": {
        "createdIndex": 2,
        "key": "/message",
        "modifiedIndex": 2,
        "value": "Hello world"
    }
}
  1. action : 刚才要做什么操作,该请求尝试通过PUT HTTP请求修改node.value,从而设置操作的值。
  2. node.key : 发出请求的HTTP路径. 我们设置 /message的值为 hello world. 所以关键字段是/message。etcd使用类似文件系统的结构来表示键值对,因此所有键以/开始
  3. node.value : 值, 在上例中 请求成功设置为 hello world
  4. node.createdIndex : 每个创建索引(createdIndex)是唯一的。单调递增的整数。在此示例中,索引为2,是发送到服务器的第一个请求。 这个可以用来做内部命令状态使用,比如添加和同步服务器。
  5. node.modifiedIndex : 也是etcd的索引,当 set, delete, update, create, compareAndSwap, compareAndDelete 等操作的时候会改变这个索引的值。 由于 getwatch 命令不改变存储中的状态,所以它们不会改变node.modifiedIndex的值。

http 回复头信息(Response Headers)

etcd在响应中包含几个HTTP头,提供有关为请求提供服务的etcd集群的全局信息:

X-Etcd-Index: 35
X-Raft-Index: 5398
X-Raft-Term: 1
  1. X-Etcd-Index : 当前etcd的索引(index) 的值, 当请求watch命令查看 key空间,X-Etcd-Index为当前 watch命令时的索引值。这意味着观看的事件可能在X-Etcd-Index之后发生。
  2. X-Raft-Index : 类似索引,只是这个是在 raft protocol 协议下的索引值。
  3. X-Raft-Term : 是一个整数。当etcd master 变化的时候会增加。 如果这个数字迅速增加,您可能需要调整选举超时。

调整

etcd中的默认设置应适用于平均网络延迟较低的本地网络上的安装。 但是,当跨多个数据中心或通过高延迟的网络使用etcd时,您可能需要调整心跳间隔和选择超时设置。

网络不是延迟的唯一来源。 每个请求和响应可能会受到领导者和跟随者的慢磁盘的影响。 这些超时表示从另一台机器的请求到成功响应的总时间。

时间参数

底层分布式共识协议依赖于两个单独的时间参数,以确保节点可以在一个停顿或离线时切换领导(主分支)。第一个参数称为心跳间隔。这是领导者通知追随者仍然是领导者的频率。对于最佳实践,参数应该围绕成员之间的往返时间设置。默认情况下,etcd使用100ms的心跳间隔。

第二个参数是选举超时。这个超时是追随者节点在尝试成为领导者之前不会听到心跳的时间。默认情况下,etcd使用1000ms的选举超时。

调整这些值是一个折衷。心跳间隔的值建议在成员之间的平均往返时间(RTT)的最大值,通常为往返时间的0.5-1.5倍。如果心跳间隔太小,etcd将发送不必要的消息,增加CPU和网络资源的使用。另一方面,过高的心跳间隔导致选举超时时间较长。更高的选举超时需要更长的时间来检测领导者的失败。测量往返时间(RTT)的最简单方法是使用PING实用程序。

应根据心跳间隔和成员之间的平均往返时间设置选举超时。选举超时时间必须至少是往返时间的10倍,因此可以考虑网络中的差异。例如,如果您的成员之间的往返时间是10ms,那么您应该至少有100ms的选举超时。

您还应将您的选举超时设置为心跳间隔的至少5到10倍,以解决前导复制中的差异。对于50ms的心跳间隔,您应将您的选举超时设置为至少250ms - 500ms。

选举超时上限为50000ms(50s),只能在部署全局分布式的etcd集群时使用。美国大陆合理的往返时间为130ms,美日之间约为350-400ms。如果您的网络具有不均衡的性能或定期的数据包延迟/丢失,则可能需要进行几次重试才能成功发送数据包。所以5s是全球往返时间的安全上限。由于选举超时时间应大于广播时间的一个数量级,所以在全球分布式集群约为5秒的情况下,50秒成为合理的最大值。

一个群集中的所有成员的心跳间隔和选举超时值应相同。为etcd成员设置不同的值可能会破坏群集的稳定性。

您可以覆盖命令行上的默认值:

# Command line arguments:
$ etcd -heartbeat-interval=100 -election-timeout=500

# Environment variables:
$ ETCD_HEARTBEAT_INTERVAL=100 ETCD_ELECTION_TIMEOUT=500 etcd

这些值以毫秒为单位指定。

快照

etcd将所有关键更改附加到日志文件。 这个日志永远增长,是对键的每一个改变的完整的线性历史。 一个完整的历史记录适用于轻度使用的群集,但是大量使用的群集将携带大型日志。

为了避免有一个巨大的日志等待定期快照。 这些快照为etcd通过保存系统的当前状态和删除旧日志来提供压缩日志的方法。

快照调谐

创建快照可能是昂贵的,因此只能在对etcd进行一定数量的更改后创建。 默认情况下,将在每10,000次更改之后进行快照。 如果etcd的内存使用率和磁盘使用率太高,可以通过在命令行中设置以下命令来降低快照阈值:

# Command line arguments:
$ etcd -snapshot-count=5000

# Environment variables:
$ ETCD_SNAPSHOT_COUNT=5000 etcd

get (根据键获得值)

get 请求获得刚才设置 /message 的值

curl http://127.0.0.1:2379/v2/keys/message
{
    "action": "get",
    "node": {
        "createdIndex": 2,
        "key": "/message",
        "modifiedIndex": 2,
        "value": "Hello world"
    }
}

put (根据键修改值)

put 修改 键 /message 的值 hello world 为 hello etcd.

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="Hello etcd"
{
    "action": "set",
    "node": {
        "createdIndex": 3,
        "key": "/message",
        "modifiedIndex": 3,
        "value": "Hello etcd"
    },
    "prevNode": {
    	"createdIndex": 2,
    	"key": "/message",
    	"value": "Hello world",
    	"modifiedIndex": 2
    }
}

prevNode字段表示在请求之前节点的状态。 prevNode字段格式与之前节点格式相同,并且在给定节点没有先前状态的情况下被省略。

delete (删除键)

delete 请求删除 /message

curl http://127.0.0.1:2379/v2/keys/message -XDELETE
{
    "action": "delete",
    "node": {
        "createdIndex": 3,
        "key": "/message",
        "modifiedIndex": 4
    },
    "prevNode": {
    	"key": "/message",
    	"value": "Hello etcd",
    	"modifiedIndex": 3,
    	"createdIndex": 3
    }
}

ttl (设置过期)

etc中的键可以设置为在指定的秒数后过期。 您可以通过在发送PUT请求时在键上设置TTL(生存时间)来执行此操作:

curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -d ttl=5
{
    "action": "set",
    "node": {
        "createdIndex": 5,
        "expiration": "2013-12-04T12:01:21.874888581-08:00",
        "key": "/foo",
        "modifiedIndex": 5,
        "ttl": 5,
        "value": "bar"
    }
}
  1. expiration :到期时间是该键到期并被删除的时间。
  2. ttl : 是指定的键生存时间,以秒为单位。

注意:键只能由集群管理员设置过期,因此如果成员从集群中断开连接,则其键将不会到期,直到它重新加入。

curl http://127.0.0.1:2379/v2/keys/foo

如果TTL已经过期,该密钥将被删除,您将返回100。

{
    "cause": "/foo",
    "errorCode": 100,
    "index": 6,
    "message": "Key not found"
}

TTL可以取消设置,以避免通过更新操作过期:(删除过期时间)

curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -d ttl= -d prevExist=true
{
    "action": "update",
    "node": {
        "createdIndex": 5,
        "key": "/foo",
        "modifiedIndex": 6,
        "value": "bar"
    },
    "prevNode": {
        "createdIndex": 5,
        "expiration": "2013-12-04T12:01:21.874888581-08:00",
        "key": "/foo",
        "modifiedIndex": 5,
        "ttl": 3,
        "value": "bar"
    }
}

刷新ttl (重新设置过期)

etcd中的键可以刷新,而不通知当前观察者。

这可以通过在更新TTL时将refresh设置为true来实现。

刷新时,无法更新密钥的值。

curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -d ttl=5
curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d ttl=5 -d refresh=true -d prevExist=true
{
    "action": "set",
    "node": {
        "createdIndex": 5,
        "expiration": "2013-12-04T12:01:21.874888581-08:00",
        "key": "/foo",
        "modifiedIndex": 5,
        "ttl": 5,
        "value": "bar"
    }
}
{
   "action":"update",
   "node":{
       "key":"/foo",
       "value":"bar",
       "expiration": "2013-12-04T12:01:26.874888581-08:00",
       "ttl":5,
       "modifiedIndex":6,
       "createdIndex":5
    },
   "prevNode":{
       "key":"/foo",
       "value":"bar",
       "expiration":"2013-12-04T12:01:21.874888581-08:00",
       "ttl":3,
       "modifiedIndex":5,
       "createdIndex":5
     }
}

等待更改 (键更改进行通知)

我们可以观看一个关键字的更改,并通过使用长轮询接收通知。 这也可以通过在curl中传递recursive=true来实现。

curl http://127.0.0.1:2379/v2/keys/foo?wait=true

现在我们正在等待路径/foo的任何更改。

在另一个终端,我们设置键/foo 值bar:

curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar

第一个终端应该得到通知并返回与设置请求相同的响应:

{
    "action": "set",
    "node": {
        "createdIndex": 7,
        "key": "/foo",
        "modifiedIndex": 7,
        "value": "bar"
    },
    "prevNode": {
        "createdIndex": 6,
        "key": "/foo",
        "modifiedIndex": 6,
        "value": "bar"
    }
}

watch 命令可以做更多的事情。 利用索引, 我们可以看到过去发生的命令。这对于确保不要错过watch命令之间的事件很有用。 通常,我们从我们获得的节点的modifiedIndex + 1再次观看。

试一下 index 为 7的情况

curl 'http://127.0.0.1:2379/v2/keys/foo?wait=true&waitIndex=7'

watch 立刻返回和原来一样的情况。

在试一下 8 的情况

curl 'http://127.0.0.1:2379/v2/keys/foo?wait=true&waitIndex=8'

不管9还是800, /foo 第一个返回的是8和当前索引之间的事件进行返回

注意:etcd只保留所有etcd键中最近1000个事件的响应。 建议将响应发送给另一个线程以立即处理,而不是在处理结果时阻止watch。

清除事件索引观察

如果我们错过了所有1000个事件,我们需要通过获取恢复观看密钥空间的当前状态,然后从X-Etcd-Index + 1开始观察。

例如,我们将/other=“bar”设置为2000次,并尝试从索引8中等待。

curl 'http://127.0.0.1:2379/v2/keys/foo?wait=true&waitIndex=8'

我们得到的索引是过时的响应,因为我们错过了保存在etcd中的1000个事件。

{"errorCode":401,"message":"The event in requested index is outdated and cleared","cause":"the requested history has been cleared [1008/8]","index":2007}

要开始观看,首先我们需要获取当前键/foo状态:

curl 'http://127.0.0.1:2379/v2/keys/foo' -vv
< HTTP/1.1 200 OK
< Content-Type: application/json
< X-Etcd-Cluster-Id: 7e27652122e8b2ae
< X-Etcd-Index: 2007
< X-Raft-Index: 2615
< X-Raft-Term: 2
< Date: Mon, 05 Jan 2015 18:54:43 GMT
< Transfer-Encoding: chunked
<
{"action":"get","node":{"key":"/foo","value":"bar","modifiedIndex":7,"createdIndex":7}}

与watch不同,我们使用X-Etcd-Index + 1作为waitIndex,而不是节点的modifiedIndex + 1,原因有二:

  1. 当获取键时,X-Etcd-Index始终大于或等于modifiedIndex,因为X-Etcd-Index是当前的etcd索引,而modifiedIndex是已经存储在etcd中的事件的索引。
  2. modifiedIndex和X-Etcd-Index之间的索引表示的事件都不会与正在获取的密钥相关。

使用modifiedIndex + 1在后续watch上功能上相当,但由于它小于X-Etcd-Index + 1,我们可能会立即收到401 EventIndexCleared错误。

所以第一次看后应该是:

curl 'http://127.0.0.1:2379/v2/keys/foo?wait=true&waitIndex=2008'
连接过早关闭

在发布任何事件之前,服务器可能会关闭长轮询连接。 这可能是由于超时或服务器关闭。 由于HTTP标头在接受连接后立即发送,响应将被视为空:200 OK和空体。 客户应该准备好处理这种情况并重试 watch。

POST (包含目录的key)

(也就是用这个可以创建多层表示的key, 如 /message/001 和 /message/002 互斥)

在目录上 使用post 可以创建原子性的名称。这可以用于各种有用的模式,例如实现需要以严格顺序处理的key的队列。 一个示例用例将确保客户端可以公平地访问互斥体。

curl http://127.0.0.1:2379/v2/keys/queue -XPOST -d value=Job1
{
    "action": "create",
    "node": {
        "createdIndex": 6,
        "key": "/queue/00000000000000000006",
        "modifiedIndex": 6,
        "value": "Job1"
    }
}

如果稍后再创建另一个条目,则保证键名大于之前的键。 还要注意键名使用全局etcd索引,所以下一个键可以超过以前的+ 1。

curl http://127.0.0.1:2379/v2/keys/queue -XPOST -d value=Job2
{
    "action": "create",
    "node": {
        "createdIndex": 29,
        "key": "/queue/00000000000000000029",
        "modifiedIndex": 29,
        "value": "Job2"
    }
}

要将按顺序的键列举为排序列表,请使用“sorted”参数。

curl -s 'http://127.0.0.1:2379/v2/keys/queue?recursive=true&sorted=true'
{
    "action": "get",
    "node": {
        "createdIndex": 2,
        "dir": true,
        "key": "/queue",
        "modifiedIndex": 2,
        "nodes": [
            {
                "createdIndex": 2,
                "key": "/queue/00000000000000000002",
                "modifiedIndex": 2,
                "value": "Job1"
            },
            {
                "createdIndex": 3,
                "key": "/queue/00000000000000000003",
                "modifiedIndex": 3,
                "value": "Job2"
            }
        ]
    }
}

目录ttl

像键一样,etcd中的目录可以设置为在指定的秒数之后到期。 您可以通过在使用PUT创建目录时设置TTL(生存时间)来实现此目的:

curl http://127.0.0.1:2379/v2/keys/dir -XPUT -d ttl=30 -d dir=true
{
    "action": "set",
    "node": {
        "createdIndex": 17,
        "dir": true,
        "expiration": "2013-12-11T10:37:33.689275857-08:00",
        "key": "/dir",
        "modifiedIndex": 17,
        "ttl": 30
    }
}

目录的TTL可以通过更新进行刷新。 您可以通过使用prevExist = true和新的TTL进行PUT来执行此操作。

curl http://127.0.0.1:2379/v2/keys/dir -XPUT -d ttl=30 -d dir=true -d prevExist=true

这个目录下的键照常工作,但当目录过期时,目录下的键上的观察者将获得到期事件:

curl 'http://127.0.0.1:2379/v2/keys/dir?wait=true'
{
    "action": "expire",
    "node": {
        "createdIndex": 8,
        "key": "/dir",
        "modifiedIndex": 15
    },
    "prevNode": {
        "createdIndex": 8,
        "key": "/dir",
        "dir":true,
        "modifiedIndex": 17,
        "expiration": "2013-12-11T10:39:35.689275857-08:00"
    }
}

原子比较和交换

etcd可以用作集群中的集中式协调服务,CompareAndSwap(CAS)是用于构建分布式锁服务的最基本的操作。

只有当客户端提供的条件等于当前条件时,该命令才会设置键的值。

请注意,CompareAndSwap不适用于目录。 如果尝试CompareAndSwap目录,将返回102“不是文件”错误。

目前的可比较条件是:

  1. prevValue : 检查键的上一个值。
  2. prevIndex : 检查以前的modifyIndex的密钥。
  3. prevExist : 检查键的存在:如果prevExist为真,则为更新请求; 如果prevExist为false,则为创建请求。

我们先创建一个键值对:foo = 1。

curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value=one
{
    "action":"set",
    "node":{
        "key":"/foo",
        "value":"one",
        "modifiedIndex":4,
        "createdIndex":4
    }
}

指定noValueOnSuccess选项跳过返回节点作为值。

curl http://127.0.0.1:2379/v2/keys/foo?noValueOnSuccess=true -XPUT -d value=one
# {"action":"set"}

现在让我们尝试一些无效的CompareAndSwap命令。

尝试使用prevExist = false设置此现有键按预期方式失败:

curl http://127.0.0.1:2379/v2/keys/foo?prevExist=false -XPUT -d value=three
{
    "cause": "/foo",
    "errorCode": 105,
    "index": 39776,
    "message": "Key already exists"
}

现在我们来提供一个prevValue参数:

curl http://127.0.0.1:2379/v2/keys/foo?prevValue=two -XPUT -d value=three

这将尝试比较键的先前值和我们提供的先前值。 如果它们相等,则键值将变为3。

{
    "cause": "[two != one]",
    "errorCode": 101,
    "index": 8,
    "message": "Compare failed"
}

这意味着CompareAndSwap失败。 原因解释了测试失败的原因。 注意:条件prevIndex = 0始终通过。

让我们尝试一个有效的条件:

curl http://127.0.0.1:2379/v2/keys/foo?prevValue=one -XPUT -d value=two
{
    "action": "compareAndSwap",
    "node": {
        "createdIndex": 8,
        "key": "/foo",
        "modifiedIndex": 9,
        "value": "two"
    },
    "prevNode": {
    	"createdIndex": 8,
    	"key": "/foo",
    	"modifiedIndex": 8,
    	"value": "one"
    }
}

自从我们给出了正确的上一个值之后,我们成功地将值从“one”更改为“two”。

原子比较和删除

只有当客户端提供的条件等于当前条件时,该命令才会删除一个键。

请注意,CompareAndDelete不适用于目录。 如果尝试CompareAndDelete目录,将返回102“不是文件”错误。

目前的可比较条件是:

  1. prevValue - 检查键的上一个值。
  2. prevIndex - 检查以前的modifyIndex的密钥。

我们先创建一个键:foo = 1。

curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value=one

现在我们来试一下CompareAndDelete命令。

尝试删除与prevValue = 2的键失败如预期:

curl http://127.0.0.1:2379/v2/keys/foo?prevValue=two -XDELETE
{
	"errorCode": 101,
	"message": "Compare failed",
	"cause": "[two != one]",
	"index": 8
}

与具有不匹配的prevIndex的CompareAndDelete一样:

curl http://127.0.0.1:2379/v2/keys/foo?prevIndex=1 -XDELETE
{
	"errorCode": 101,
	"message": "Compare failed",
	"cause": "[1 != 8]",
	"index": 8
}

现在有一个有效的prevValue条件:

curl http://127.0.0.1:2379/v2/keys/foo?prevValue=one -XDELETE
{
	"action": "compareAndDelete",
	"node": {
		"key": "/foo",
		"modifiedIndex": 9,
		"createdIndex": 8
	},
	"prevNode": {
		"key": "/foo",
		"value": "one",
		"modifiedIndex": 8,
		"createdIndex": 8
	}
}

目录

创建目录

在大多数情况下,键的目录是自动创建的。但有些情况下,您需要创建一个目录或删除一个目录。

创建目录就像一个键,除了不能提供一个值,必须添加dir = true参数。

curl http://127.0.0.1:2379/v2/keys/dir -XPUT -d dir=true
{
    "action": "set",
    "node": {
        "createdIndex": 30,
        "dir": true,
        "key": "/dir",
        "modifiedIndex": 30
    }
}

查看目录

在etcd中,我们可以存储两种类型的东西:键和目录。 键存储单个字符串值。 目录存储一组键和/或其他目录。

在这个例子中,我们先创建一些键:

我们已经有/ foo = 2,所以现在我们将创建另一个名为/ foo_dir / foo,值为bar:

curl http://127.0.0.1:2379/v2/keys/foo_dir/foo -XPUT -d value=bar
{
    "action": "set",
    "node": {
        "createdIndex": 2,
        "key": "/foo_dir/foo",
        "modifiedIndex": 2,
        "value": "bar"
    }
}

现在我们可以在root / 下列出键:

curl http://127.0.0.1:2379/v2/keys/
{
    "action": "get",
    "node": {
        "key": "/",
        "dir": true,
        "nodes": [
            {
                "key": "/foo_dir",
                "dir": true,
                "modifiedIndex": 2,
                "createdIndex": 2
            },
            {
                "key": "/foo",
                "value": "two",
                "modifiedIndex": 1,
                "createdIndex": 1
            }
        ]
    }
}

这里我们可以看到/foo是一个键值对,在/ and /foo_dir是一个目录。 我们还可以通过添加recursive = true来递归地获取目录下的所有内容。

curl http://127.0.0.1:2379/v2/keys/?recursive=true
{
    "action": "get",
    "node": {
        "key": "/",
        "dir": true,
        "nodes": [
            {
                "key": "/foo_dir",
                "dir": true,
                "nodes": [
                    {
                        "key": "/foo_dir/foo",
                        "value": "bar",
                        "modifiedIndex": 2,
                        "createdIndex": 2
                    }
                ],
                "modifiedIndex": 2,
                "createdIndex": 2
            },
            {
                "key": "/foo",
                "value": "two",
                "modifiedIndex": 1,
                "createdIndex": 1
            }
        ]
    }
}

删除目录

现在我们试试删除目录/ foo_dir。

您可以使用DELETE动词和dir = true参数删除空目录。

curl 'http://127.0.0.1:2379/v2/keys/foo_dir?dir=true' -XDELETE
{
    "action": "delete",
    "node": {
        "createdIndex": 30,
        "dir": true,
        "key": "/foo_dir",
        "modifiedIndex": 31
    },
    "prevNode": {
    	"createdIndex": 30,
    	"key": "/foo_dir",
    	"dir": true,
    	"modifiedIndex": 30
    }
}

要删除保存键的目录,必须添加recursive = true。

curl http://127.0.0.1:2379/v2/keys/dir?recursive=true -XDELETE
{
    "action": "delete",
    "node": {
        "createdIndex": 10,
        "dir": true,
        "key": "/dir",
        "modifiedIndex": 11
    },
    "prevNode": {
    	"createdIndex": 10,
    	"dir": true,
    	"key": "/dir",
    	"modifiedIndex": 10
    }
}

创建一个隐藏节点

我们可以通过添加_前缀来创建一个隐藏的键值对或目录。 当发送目录的GET请求时,隐藏的项目将不被列出。

首先我们将添加一个名为/_message的隐藏键:

curl http://127.0.0.1:2379/v2/keys/_message -XPUT -d value="Hello hidden world"
{
    "action": "set",
    "node": {
        "createdIndex": 3,
        "key": "/_message",
        "modifiedIndex": 3,
        "value": "Hello hidden world"
    }
}

现在让我们尝试获得根目录下的键列表,/:

curl http://127.0.0.1:2379/v2/keys/
{
    "action": "get",
    "node": {
        "dir": true,
        "key": "/",
        "nodes": [
            {
                "createdIndex": 2,
                "dir": true,
                "key": "/foo_dir",
                "modifiedIndex": 2
            },
            {
                "createdIndex": 4,
                "key": "/message",
                "modifiedIndex": 4,
                "value": "Hello world"
            }
        ]
    }
}

这里我们看到/message键,但我们隐藏的/_message键不会被返回。

从文件设置一个键

您还可以使用etcd直接存储小型配置文件,JSON文档,XML文档等。 例如,您可以使用curl上传一个简单的文本文件并进行编码:

echo "HellonWorld" > afile.txt
curl http://127.0.0.1:2379/v2/keys/afile -XPUT --data-urlencode value@afile.txt
{
    "action": "get",
    "node": {
        "createdIndex": 2,
        "key": "/afile",
        "modifiedIndex": 2,
        "value": "HellonWorldn"
    }
}

线性化读取 (没理解)

如果你想要一个完全线性化的阅读,你可以使用一个quorum = true GET。 读取将采取非常类似的写入路径,并将具有相似的速度。 如果您不确定是否需要此功能,请随时发送电子邮件至etcd-dev以获取建议。

统计

一个etcd集群跟踪一些统计数据,包括延迟,带宽和正常运行时间。 这些通过统计端点公开,以了解集群的内部运行状况。

Leader 统计

Leader可以看到整个集群,并跟踪两个有趣的统计信息:集群中每个对等体的延迟以及失败和成功的Raft RPC请求数。 您可以从/v2/stats/leader端点获取这些统计信息:

curl http://127.0.0.1:2379/v2/stats/leader
{
    "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"
}

自我统计

  1. 领导者(follower)
  2. 追随者(follower)

每个节点保留一些内部统计信息:

  • id:成员的唯一标识符
  • leaderInfo.leader:当前领导成员的ID
  • leaderInfo.uptime:领导者领导的时间
  • name:这个成员的名字
  • recvAppendRequestCnt:此节点已处理的附加请求数
  • recvBandwidthRate:此节点接收的每秒字节数(仅限随机数)
  • recvPkgRate:此节点接收的每秒请求数(仅跟随者)
  • sendAppendRequestCnt:此节点发送的请求数
  • sendBandwidthRate:此节点发送的每秒字节数(仅限于引导者)。 该值在单个成员集群上未定义。
  • sendPkgRate:此节点发送的每秒请求数(仅限于引导者)。 该值在单个成员集群上未定义。
  • state:任何领导者或追随者
  • startTime:此节点启动的时间

这是来自跟随者成员的示例响应:

curl http://127.0.0.1:2379/v2/stats/self
{
    "id": "eca0338f4ea31566",
    "leaderInfo": {
        "leader": "8a69d5f6b7814500",
        "startTime": "2014-10-24T13:15:51.186620747-07:00",
        "uptime": "10m59.322358947s"
    },
    "name": "node3",
    "recvAppendRequestCnt": 5944,
    "recvBandwidthRate": 570.6254930219969,
    "recvPkgRate": 9.00892789741075,
    "sendAppendRequestCnt": 0,
    "startTime": "2014-10-24T13:15:50.072007085-07:00",
    "state": "StateFollower"
}

这是领导成员的一个例子:

curl http://127.0.0.1:2379/v2/stats/self
{
    "id": "924e2e83e93f2560",
    "leaderInfo": {
        "leader": "924e2e83e93f2560",
        "startTime": "2015-02-09T11:38:30.177534688-08:00",
        "uptime": "9m33.891343412s"
    },
    "name": "infra3",
    "recvAppendRequestCnt": 0,
    "sendAppendRequestCnt": 6535,
    "sendBandwidthRate": 824.1758351191694,
    "sendPkgRate": 11.111234716807138,
    "startTime": "2015-02-09T11:38:28.972034204-08:00",
    "state": "StateLeader"
}

存储统计

存储统计信息包括有关此节点处理的操作的信息。 请注意,v2存储统计信息存储在内存中。 当成员停止时,重新启动时将重新存储统计信息。

整个群集都会看到修改商店状态(如创建,删除,设置和更新)的操作,所有节点上的数量都会增加。 像get和watch这样的操作是本地节点,只能在这个节点上看到。

curl http://127.0.0.1:2379/v2/stats/store
{
    "compareAndSwapFail": 0,
    "compareAndSwapSuccess": 0,
    "createFail": 0,
    "createSuccess": 2,
    "deleteFail": 0,
    "deleteSuccess": 0,
    "expireCount": 0,
    "getsFail": 4,
    "getsSuccess": 75,
    "setsFail": 2,
    "setsSuccess": 4,
    "updateFail": 0,
    "updateSuccess": 0,
    "watchers": 0
}

后面继续补充

PS: 觉得不错的请点个赞吧!! (ง •̀_•́)ง