发布网友 发布时间:2023-02-17 09:25
共1个回答
热心网友 时间:2023-10-12 02:44
V2版本的key在etcd是按照目录格式来存储的:
对于createdIndex 和 modifiedIndex两个值,基本上是一直相等的,当你-XPUT的时候,会同步更新这两个值,但delete和update的时候这两个值就会不同了,只有modifiedIndex会增加。
etcd的回复里面,包含了简单的消息头,里面的数据也比较重要。
数据读取比较简单,直接读取某个key就可以。
和设置一样,更改的时候用也是PUT操作
TTL就是给key设置一个timeout,时间到了之后,key会被自动删除,当然你可以在超时之前删除timeout,这样key就不会有超期了。同样的你也可以不断的去刷新key的timeout,这样可以起到看门狗的作用(可以用来探测etcd的存活)。
需要注意的一点是,timeout只会由leader来触发,如果一个instance(不是leader)因为某种原因退出集群了,那么该instance的超时key就不会删除了,除非它重新加入集群,leader会帮它删掉(个人认为这时候不再是timeout删除,而是raft底层的数据同步,会把删除操作append到节点,节点会删除数据.如果leader退出了,那么新的leader会执行timeout操作。
上面说过,在超时之前可以用命令重新更新key的ttl。
watch功能是etcd里面一个很重要的功能,现在有v2和v3两个版本。分别对应了不同的设计,可以参照下面的链接:
https://blog.csdn.net/zl1zl2zl3/article/details/79627412
我们可以通过常轮训来监听key的变化,同时可以使用recursive=true参数来对子key(目录)监听。
注意:
etcd的watch智能保持100条记录(V2版本,v3没这个*),所以收到通知之后应该将response交给其它线程去处理,不要在watch线程里处理,不然容易阻塞!!
前面已经说过etcd的v2版本只能保存1000个事件,如果已经事件丢失,我们需要先得到目前的状态,然后再开始监听。比如我们对一个key设置了2000次,那么etcd里面保存的直邮1000-2000的事件,如果这时候我们用下面命令:
那现在我们怎么开始监听这个key那,因为我们也不知道etcd里面保存的事件是从哪里开始的。所以我们可以使用下面命令得到etcd现在的状态。
前面已经解释过返回的信息的标志位的意思了。X-Etcd-Index代表的是etcd的状态,modifiedIndex代表的是上次修改这个key的index,X-Etcd-Index是大于等于modifiedIndex的,理论上来讲用两个index + 1是相同效果,但是用modifiedIndex可能会导致上面说的401error,所以我们一般都用X-Etcd-Index。
连接关闭指的是可能server还没来的及发送event,但由于超时或者server发生了关机,因为http的header是一旦接收到连接就会返回头部的,所以返回值会是200:ok和空的消息体。client需要自己处理这种情况。
在一个目录下使用POST可以创建出顺序的key,有时候这个功能很有用,比如需要严格按照顺序处理的事件。可以保证cleint可以公平的访问mutex锁(这个点没太搞懂)
创建一个顺序的key很简单:
这里的key的后缀是全局的etcd的index。
etcd的存储是以目录树的结构来的,所以我们可以对某个目录设置一个TTL。
目录的ttl超时的时候,如果有监听线程正在监听它下面的key,那么watch会收到一个expire的事件。
etcd主要通过三个标志位来对etcd的数据进行原子操作,注意etcd的原子操作只能针对key,不能针对目录,否则会返回102“Not a file” error。
1.prevValue - 检查key的上一个状态.
2.prevIndex -检查key的modifiedIndex.(保证没别的线程修改过)
3.prevExist - 如果是true,代表"update"请求,否则是create请求。
下面看几个例子:
etcd的删除操作也支持原子操作,标志位和上面的比少了prevExist。其它的是一样的。看例子:
在大多数情况下,目录都会在创建key的时候自动创建,但有时候我们需要自己去创建一个目录或者删除一个目录。用参数dir=true就可以了。
在etcd中,如果想获得目录下所有的key,可以用下面的命令:
如果没有recursive,那么只会显示目录,不会现在目录下面的key或者子目录。
删除etcd的目录的时候,如果目录下面有key或者别的目录存在,你删除的时候会返回下面的错误:
所以如果想直接删除整个目录,可以用下面的命令(recursive=true):
etcd可以通过添加_前缀创建隐藏的key或者目录,这时候你通过GET指令是看不到这个node的。
etcd隐藏的node主要作用是为了安全性,特地去github上看了一下作者的解释。
https://github.com/etcd-io/etcd/issues/6375
就是说隐藏key你通过etcd的api是看不到的,除非你能登陆本地的disk,然后查看本地的存储文件。保密性高,我们可以将我们一些key放在里面。创建的指令如下:
我们可以用etcd存储一些小的配置文件。
大家都知道etcd的写操作是都要经过raft协议同步的,线性化读取也是同样的道理。如果 Get的时候使用参数quorum=true,那么GET操作也要走raft协议,不是本地直接返回。
我们可以查看etcd的一些内部统计信息来观察etcd的状态。主要就分为etcd的状态和存储状态。
每个标志位的含义:
etcd的存储的状态是存储在内存中的,所以重启之后是会重置各个参数。
掌握etcd的API是使用etcd的前提条件,所以把v2版本的按照个人理解和操作整理出来。后面会整理v3版本的API。