etcd v2 API

通过etcd v2 API的HTTP+JSON,很方便的用curl来调用etcd v2 API,有如下的内容:

  • 集群管理API

一、集群管理API

1、查看版本

[root@localhost etcd-v3.3.10-linux-amd64]# curl -L http://127.0.0.1:2379/version
{"etcdserver":"3.3.10","etcdcluster":"3.3.0"}

2、集群状态

# 返回true则是健康的
[root@localhost etcd-v3.3.10-linux-amd64]# curl -L http://127.0.0.1:2379/health
{"health":"true"}

3、leader数据

etcd的集群可以获取整个集群的:

  • 节点时延信息
  • 失败/成功的RPC请求次数
[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/stats/leader
{
    "leader": "57bf4d2527966724",
    "followers": {
        "4c14bc06668e9505": {
            "latency": {
                "current": 0.001479,
                "average": 0.003306272727272727,
                "standardDeviation": 0.0017684453414284075,
                "minimum": 0.000948,
                "maximum": 0.006036
            },
            "counts": {
                "fail": 0,
                "success": 11
            }
        },
        "a11e107c0081dbf8": {
            "latency": {
                "current": 0.001337,
                "average": 0.0033447999999999999,
                "standardDeviation": 0.0036313811091649415,
                "minimum": 0.00096,
                "maximum": 0.011139
            },
            "counts": {
                "fail": 0,
                "success": 10
            }
        }
    }
}

4、节点自身数据

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/stats/self
{
    "name": "etcd2",
    "id": "57bf4d2527966724",
    "state": "StateLeader",
    "startTime": "2021-02-14T08:28:31.154812422+08:00",
    "leaderInfo": {
        "leader": "57bf4d2527966724",
        "uptime": "4h55m26.902989917s",
        "startTime": "2021-02-14T11:23:54.355889296+08:00"
    },
    "recvAppendRequestCnt": 391,
    "sendAppendRequestCnt": 21
}

其中:

  • name 该节点的name
  • id 该节点的唯一标识
  • state 该节点是否是leader
  • startTime 该etcdServer启动时间
  • leaderInfo.leader 集群当前leader的id
  • leaderInfo.uptime 集群当前leade的在任时长
  • leaderInfo.startTime 集群当前leade的启动时间
  • recvAppendRequestCnt 该节点已处理的append请求数
  • sendAppendRequestCnt 该节点已发送的append请求数

5、数据统计

etcd集群中全部节点都会记录修改存储的状态,比如,增加、修改、删除等状态,通过以下API可以获取其计数:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/stats/store
{
    "getsSuccess": 27,
    "getsFail": 33,
    "setsSuccess": 44,
    "setsFail": 0,
    "deleteSuccess": 1,
    "deleteFail": 0,
    "updateSuccess": 1,
    "updateFail": 0,
    "createSuccess": 6,
    "createFail": 1,
    "compareAndSwapSuccess": 0,
    "compareAndSwapFail": 0,
    "compareAndDeleteSuccess": 1,
    "compareAndDeleteFail": 0,
    "expireCount": 2,
    "watchers": 0
}

二、写、读、改、删除

etcd v2的键一般位于路径"v2/keys"路径下,例如,message这个键的完整路径是“/v2/keys/message”,那么如何通过API的形式实现呢?

1、写

[root@localhost etcd-v3.3.10-linux-amd64]# curl -L http://127.0.0.1:2379/v2/keys/message -XPUT -d value="hello"
{
"action":"set",
"node":{
"key":"/message",
"value":"hello",
"modifiedIndex":19,
"createdIndex":19
}
}

  在返回的json数据中,其中action表示请求的动作是set。在v2 API中创建键值或者更新键值使用的都是PUT方法。 在node中,node.key是需要设置的键;node.value是需要设置的值;对etcd来说,每次创建一个键值都会产生一个唯一的createdIndex,第一个key的createdIndex是2而非1;任何更改行为(create、delete、set)都会更该modifiedIndex的值。

2、读

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/message
{
    "action": "get",
    "node": {
        "key": "/message",
        "value": "hello",
        "modifiedIndex": 19,
        "createdIndex": 19
    }
}

3、改

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/message -XPUT -d value="message1"
{
    "action": "set",
    "node": {
        "key": "/message",
        "value": "message1",
        "modifiedIndex": 23,
        "createdIndex": 23
    },
    "prevNode": {
        "key": "/message",
        "value": "hello",
        "modifiedIndex": 19,
        "createdIndex": 19
    }
}

可以看到更改之前的key会多返回一个字段prevNode信息,这是之前存储的key信息。

4、删除

{
    "action": "delete",
    "node": {
        "key": "/message",
        "modifiedIndex": 24,
        "createdIndex": 23
    },
    "prevNode": {
        "key": "/message",
        "value": "message1",
        "modifiedIndex": 23,
        "createdIndex": 23
    }
}

删除键值,它会将之前修改过的记录全部返回。

三、TTL

 etcd的键可以通过TTL设置过期时间,一旦过了设置的时间,键就会被自动删掉。

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/message1 -XPUT -d value="hello" -d ttl=20 
{
    "action": "set",
    "node": {
        "key": "/message1",
        "value": "hello",
        "expiration": "2021-02-14T02:12:27.005370199Z",
        "ttl": 20,
        "modifiedIndex": 25,
        "createdIndex": 25
    }
}

上述的返回值中node.expiration表示在该时刻这个键会过期,ttl表示还有多少秒会过期,一旦到期会自动删除该键。如下:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/message1
{
    "errorCode": 100,
    "message": "Key not found",
    "cause": "/message1",
    "index": 26
}

当然你可以接着刷新ttl:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/message1 -XPUT -d value="hello" -d ttl=20 -d prevExit=true
{
    "action": "set",
    "node": {
        "key": "/message1",
        "value": "hello",
        "expiration": "2021-02-14T02:18:48.300233144Z",
        "ttl": 20,
        "modifiedIndex": 28,
        "createdIndex": 28
    },
    "prevNode": {
        "key": "/message1",
        "value": "hello",
        "expiration": "2021-02-14T02:18:29.321723784Z",
        "ttl": 2,
        "modifiedIndex": 27,
        "createdIndex": 27
    }
}

四、观察者(watch)

watch是观察一个key并且等待接收消息,它有以下内容:

  • watch一个key
  • 带索引的watch
  • stream watch

1、watch一个key

在一个终端中发起一个get请求,并且设置参数wait=true:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/message1?wait=true

此时,会一直阻塞在这里。

接着,再另起一个终端,进行key的更新:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/message1 -XPUT -d value="hello1"
{
    "action": "set",
    "node": {
        "key": "/message1",
        "value": "hello1",
        "modifiedIndex": 30,
        "createdIndex": 30
    }
}

在第一个终端中就能观察这个key的变化:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/message1?wait=true  
{
    "action": "set",
    "node": {
        "key": "/message1",
        "value": "hello1",
        "modifiedIndex": 30,
        "createdIndex": 30
    }
}

一旦监听到key的变化就会退出,这就是“一次性watch”。

2、带索引的watch

 带索引的watch可以观察到历史记录,保证信息的不丢失,上述的watch只是watch当前及以后的发生事件。其步骤如下:

  • 获取key当前的状态
  • 从key当前的modiifiedIndex+1开始watch

获取key当前状态:

[root@localhost ~]# curl -i http://127.0.0.1:2379/v2/keys/message1
HTTP/1.1 200 OK
Content-Type: application/json
X-Etcd-Cluster-Id: 735c420e06827765
X-Etcd-Index: 30
X-Raft-Index: 216
X-Raft-Term: 59
Date: Sun, 14 Feb 2021 02:51:36 GMT
Content-Length: 98

{
    "action": "get",
    "node": {
        "key": "/message1",
        "value": "hello1",
        "modifiedIndex": 30,
        "createdIndex": 30
    }
}

此时可以从31及以后的位置开始watch,比如33:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/message1?wait=true &waitIndex=33

此时,只要等到这个key的modifiedIndex的值等于33是才会有响应。

3、stream watch

也被称为持久化watch,也就是客户端保持长链接,中途不会因为监控到变化有返回值而中断链接。只需要在请求参数中添加stream=true即可:

[root@localhost ~]# curl http://127.0.0.1:2379/v2/keys/message1?wait=true&stream=true

  stream watch即使收到事件也不会退出;“一次性watch”只要收到事件就会退出,然后再重新发起watch。不过stream watch它是持续watch当前及以后的事件,历史事件也是无能为力。

五、原子操作

原子操作包括:

  • CAS
  • CAD

1、CAS(Compare And Swap)

先比较客户端与所提供的条件是否一样,如果不一样就进行交换,CAS的比较条件包括:

  • prevValue 检查key之前的value
  • prevIndex 检查key之前的modifiedIndex
  • prevExist 检查key是否存在,如果存在是一个更新操作,如果不存在是一个新建操作

新建一个键值对:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/msg -XPUT -d value="val"
{
    "action": "set",
    "node": {
        "key": "/msg",
        "value": "val",
        "modifiedIndex": 53,
        "createdIndex": 53
    }
}

prevExist的使用:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/msg?prevExist=false -XPUT -d value="val1"
{
    "errorCode": 105,
    "message": "Key already exists",
    "cause": "/msg",
    "index": 53
}

显然这个key已经存在了,现在参数是false,所以会报错。正确的是参数传递true:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/msg?prevExist=true -XPUT -d value="val1"
{
    "action": "update",
    "node": {
        "key": "/msg",
        "value": "val1",
        "modifiedIndex": 54,
        "createdIndex": 53
    },
    "prevNode": {
        "key": "/msg",
        "value": "val",
        "modifiedIndex": 53,
        "createdIndex": 53
    }
}

prevValue与prevIndex的用法相似。

2、CAD(Compare And Delete)

先比较客户端与所提供的条件是否一样,如果一样就删除对应的key,CAD的比较条件包括:

  • prevValue 检查key之前的value
  • prevIndex 检查key之前的modifiedIndex

使用之前的msg键值:

[root@localhost ~]# curl -L http://127.0.0.1:2379/v2/keys/msg?prevValue=val1 -XDELETE
{
    "action": "compareAndDelete",
    "node": {
        "key": "/msg",
        "modifiedIndex": 55,
        "createdIndex": 53
    },
    "prevNode": {
        "key": "/msg",
        "value": "val1",
        "modifiedIndex": 54,
        "createdIndex": 53
    }
}

prevIndex用法与之类似。

作者:iveBoy
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/shenjianping/p/14401243.html