etcd 的基本使用和原理
etcd 诞生于 CoreOS 公司,最初用于解决集群管理系统中 OS 升级的分布式并发控制,配置文件的存储与分发等问题。基于此,etcd 被设计为提供高可用,强一致的小型 key-value 数据存储服务,该项目当前隶属于 cncf 基金会。目前根据不完全统计有超过 30 个公司在自己的项目中使用了 etcd,其中最出名的就是 google 公司开源的 kubernetes,kubernetes 使用 etcd 来存储关键的元数据。
etcd 的安装
etcd 可以通过多种方式安装,可以直接下载官方提供的 tar 包或者通过使用官方镜像容器启动。
我们这里采用下载 tar 包的方式安装 etcd (以 linux 为例)
- 下载安装包
curl -L https://github.com/etcd-io/etcd/releases/download/v3.4.14/etcd-v3.4.14-linux-amd64.tar.gz -o /tmp/etcd-v3.4.14-linux-amd64.tar.gz
- 创建工作文件夹
mkdir -p /tmp/etcd-download-test
- 解压
tar -xzvf /tmp/etcd-v3.4.14-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
通过 ./etcd --version
查看 etcd 版本
- 启动
./etcd &>etcd.log &
核心概念
etcd 是分布式的,可靠的,key-value 存储系统,用于存储分布式系统中的关键数据的。
在一个 etcd 集群中通常会由 3 个或者 5 个节点组成,多个节点之间会由一个叫 Raft 的一致性算法方式来完成分布式一致性协同,多个节点之间算法会选举出一个 leader,由 leader 来负责数据的同步与分发,当 leader 发生故障的时候,系统自动选取另一个节点成为 leader 并重新完成数据的同步与分发
API
etcd 对外暴露非常简单的 http 接口,etcd 还提供 watch 的机制实时的拿到数据的增量更新从而保持与 etcd 中的数据保持一致
数据版本号机制
- term 当 etcd 集群的 leader 发生故障或者其他原因导致 leader 发生切换时,term 值会加一
- revision 代表了全局数据的版本,当数据发生变更时包括创建,修改,删除,revision 都会加一,在整个 leader 任期内 revision 都会保持单调递增,正是 revision 的存在才使得 etcd 可以支持 mvcc 和数据的 watch
- 对于每一个 k-v 数据,etcd 都会记录三个版本
- create_revision 就是在创建的时候的对应的版本号
- mod_revision 就是修改的时候对应的版本号,当此数据被修改时,mod_revision 会变为上面全局的 revision
- version 代表了该数据被修改了多少次
多版本并发控制 mvcc 和 watch
etcd 支持对一个 key 发起多次修改,而且通过上面可以知道每一次修改都对应了一个版本号,这样我们查询数据的时候可以指定版本号获取指定版本的数据,如果不指定数据就会返回最新的版本数据。
我们还可以在 watch 的时候指定数据的版本,通过这种方式创建一个 watcher,并且通过这个 watcher 提供的数据管道能够获取制定版本之后所有的数据变更,如果我们指定的是一个旧版本,那我们可以马上拿到从旧版本到新版本的数据更新。
数据存储结构
在 etcd 中所有的数据都存储在一棵 B+ 树中,这颗 B+ 树是保存在磁盘中的如下图灰色的部分,这棵树维护着 revision 到 value 的映射关系,当我们指定 revsion 的时候可以通过这颗 b+ 树直接返回数据,当使用 watch 的来订阅数据的时候也可以通过这颗 b+ 树中维护的 revision 到 value 的映射关系从而通过指定的 revision 之后遍历 b+ 树从而获取数据的增量更新
同时在 etcd 内部还维护了另一颗 b+ 树,它维护着 key-revision 的映射关系,这样我们如果想通过 key 查找数据的时候,我们通过这两颗 b+ 树就可以实现
在这种多版本历史数据的机制下,可能会造成内存和磁盘的大量消耗,这样对资源有限的场景是不能接受的,所以 etcd 中有 Compaction 的机制来定期清理历史数据
事物机制
etcd 的 transaction 的机制比较简单,可以理解为一段 if-else 的程序
在 etcd 内部会保证整个事务操作的原子性
通过 etcd 的事务机制来保证 kubernetes 中多个 APIServer 的对同样一份数据修改的一致性
lease 机制
lease 是分布式系统中常见的一个概念,用于代表一个租约
如上图创建了一个 10 的租约,如果在 10 内不做任何操作,这个租约就会过期
然后创建了 key1 和 key2 两个数据并绑定到这个租约上,如果租约过期,etcd 就会自定清理掉 key1 和 key2 的数据
我们也可以通过调用 KeepAlive 方法来续约
etcd 可以允许将多个 key 绑定到同一个 lease 对象上,这样可以大幅减少 lease 对象个数和刷新时间
实际操作
数据的插入和查询
创建 key0 到 key9
查询范围
./etcdctl get key1 key6
指定前缀查询
./etcdctl get key --prefix
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于