0x01 endpoint

endpoint即意为端点,指向客户端提供服务的一个服务入口。Etcd集群中每个节点都可以提供一个端点。严格来说,endpoint不属于数据操作范畴,但与后续defrag有关联,是理解defrag的前提,就先放这里了。

提供了3个子命令。

  1. hashkv 打印出KV历史的hash值。是用来检查请求发生时各端点的记录是否一致。可以计算指定的revison版本。
  2. health 检查端点是否健康。可以用于检查端点是否健康。可以通过-w json的全局选项,返回json格式,方便使用方解析。
  3. status 返回端点的状态。包含集群ID,成员ID和当前的leader节点,对管理Etcd集群非常有帮助。

小结:

设计基础服务时,要考虑方便使用者,尽可能多提供一些选项。对于输出信息来说,最好有全局的能用选项。如-w选项指定输出的格式。

0x02 碎片整理 defrag

根据文档中的说明可知,当通过删除和压缩key回收空间时,Etcd仅是把空间挂在一个空闲列表上了,对应的后端DB文件大小是不变的。经过碎片整理,Etcd可以真正减小DB文件的大小,将磁盘空间归还给系统。

通过了解其功能知道,对于管理Etcd来说,这个特性是必须的,特别是k8s环境中会经常删除一些资源的(升级时旧的pod、水平缩容时删除的pod),key删除磁盘空间却没释放的话,用户就会困惑。

defrag的参数很少,但也能看出设计很灵活。

  1. --cluster 用来指定操作的端点范围。默认为false,为true时代表使用集群中所有的endpoint。
  2. --data-dir 可选的。可以用来对一个已经有的Etcd DB目录操作,即offline。通常可以去操作Etcd的备份。

0x03 compaction

Etcd为每个key都维护了多个版本revision。get查询时,可以获取到指定版本的数据,但这对存储造成非常大的压力,所以Etcd也支持清除指定revision之前的数据。compaction只支持一个参数就是要清除的坐标revision值,这是全局的,一旦清除,所有key的旧revision值都不再可用。同时学习到,Etcd中的revision是个全局的,不是某个key独有的。所有的修改是在指定的revision中进行的。revision是全局递增的。

做以下实验观察一下。

$ etcdctl put lin hello
OK

$ etcdctl get lin -w json
{"header":{"cluster_id":17237436991929493444,"member_id":9372538179322589801,"revision":26,"raft_term":8},"kvs":[{"key":"bGlu","create_revision":26,"mod_revision":26,"version":1,"value":"aGVsbG8="}],"count":1}

$ etcdctl put lin hello2
OK

$ etcdctl get lin -w json
{"header":{"cluster_id":17237436991929493444,"member_id":9372538179322589801,"revision":27,"raft_term":8},"kvs":[{"key":"bGlu","create_revision":26,"mod_revision":27,"version":2,"value":"aGVsbG8y"}],"count":1}

$ etcdctl get lin --rev 26
lin
hello

$ etcdctl get lin --rev 27 
lin
hello2

先创建了一个节点lin。通过-w json观察它的详细信息。它创建的revision不是1,而是26。然后修改它,再次查询。revision为27,同时它的修改revison也为27。通过指定–rev可以分别访问到它的26,27 revision时的值。

执行compaction后,查询之前的revision时就会报错了。

etcdctl compaction 26

$ etcdctl get lin --rev 25
{"level":"warn","ts":"2022-04-30T23:21:18.174+0800","logger":"etcd-client","caller":"v3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc0003f8380/127.0.0.1:2379","attempt":0,"error":"rpc error: code = OutOfRange desc = etcdserver: mvcc: required revision has been compacted"}
Error: etcdserver: mvcc: required revision has been compacted

0x04 小结

  1. 数据操作主要是运维角度的特性。与ZooKeeper对比来说,真的太方便了。ZooKeeper查询一个节点是为Leader,需要去访问Admin Service,客户端并不能查到,对使用者不友好。
  2. 同时,一个基础服务在设计时要提供丰富的接口。
  3. 通过学习compaction,纠正了对revision的理解,原来一直认为是每个key都有独立的revision。