《kubernetes 系列》2. 云原生和分布式系统的存储基石 etcd 的介绍、架构和概念解析

楔子

本次来介绍 etcd,它负责 k8s 元数据的存储,k8s 的状态数据全部存储在 etcd 上面。随着 k8s 的火热,etcd 也越来越受到重视,截止到此刻,它在 GitHub 的 star 数已经达到了 43.5k,很多软件工程师都在使用 etcd 去解决业务场景中遇到的痛点。etcd 的使用场景非常广泛,从服务发现到分布式锁,从配置存储到分布式协调等等,可以这么说,etcd 已经成为了云原生和分布式系统的存储基石。

另外 etcd 作为最热门的云原生存储之一,也被大量公司应用在和 k8s 无关的业务上。因此哪怕后续你不从事 k8s 开发,我觉得 etcd 也是有必要掌握的。

那么问题来了,etcd 说到底就是个分布式键值对存储系统,负责存储各种元数据。而说到键值对存储系统,很多人首先会想到 zookeeper,它起源于 hadoop,历史比 etcd 更加悠久,具有成熟、健壮以及丰富的特性,那 k8s 为啥不选择 zookeeper 呢?原因有以下几点:

  • 1)zookeeper 的部署和维护比较复杂,管理员需要掌握一系列的知识和技能。而 zookeeper 所使用的 Paxos 强一致性算法也是以复杂难懂而闻名于世;
  • 2)java 编写,由于 java 偏向于重型应用,会引入大量的依赖。而运维人员则希望保持强一致、高可用的机器集群尽可能简单,维护起来也不容易出错;
  • 3)发展缓慢,Apache基金会庞大的结构以及松散的管理导致项目发展缓慢;

而现在 etcd 是更好的选择,与 zookeeper 相比它更简单,安装、部署和使用更加容易,并且 etcd 的某些功能是 zookeeper 所没有的。因此 etcd 比 zookeeper 更受用户的青睐,具体表现在如下几个方面:

  • 1)etcd 更加稳定可靠,它的唯一目标就是把分布式一致性键值对存储系统做到极致,所以它更注重稳定性和扩展性;
  • 2)在服务发现的实现上,etcd 使用的是节点租约(Lease),并且支持 Group(多key);而 zookeeper 使用的是临时节点,临时节点存在不少的问题,这些问题后面会提到;
  • 3)etcd 支持稳定的 watch(监视 key 的变更),而不是像 zookeeper 那样使用简单的单次触发式(one time trigger)watch。因为在未来微服务的环境下,通过调度系统调度,一个服务随时可能会下线,也可能为应对临时的访问压力而增加新的服务节点,而很多调度系统是需要得到完整的节点历史记录的。在这方面,etcd 表现的更优秀,可以存储数十万个历史变更;
  • 4)etcd 支持 MVCC(多版本并发控制),因为有协同系统需要无锁操作;
  • 5)etcd 支持更大的数据规模,支持存储百万到千万级别的 key;
  • 6)etcd 的性能比 zookeeper 更好,在一个由 3 台 8 核节点组成的云服务器上,etcd v3 版本可以做到每秒数万次的写操作和数十万次的读操作;

etcd 这么优秀,还有什么理由不去学习它呢?下面就来开始 etcd 的学习。

初识 etcd

我们说 etcd 是一个分布式键值对存储系统,那么官方是怎么定义它的呢?

A highly-available key value store for shared configuration and service discovery

所以 etcd 是一个分布式、高可用的一致性键值对存储系统,用于提供可靠的分布式键值存储、配置共享和服务发现等功能。etcd 以一致和容错的方式存储数据和实现分布式调度,在现代化的集群运行中起到关键性的作用。常见的 etcd 使用场景包括:服务发现、分布式锁、分布式数据队列、分布式通知和协调、主备选举等等。

补充:对于一个分布式系统来说,分布式数据存储功能是必不可少的,如果不支持数据分布式存储,那么这个系统就不能叫分布式。因此当你想自己实现一个分布式系统时,那么不妨把分布式存储的功能交给 etcd 负责吧。

另外 etcd 采用的是强一致性模型,基于 Raft 协议,通过复制日志文件的方式来保证数据的强一致性。当客户端写入一个键值对时,首先会存储到 etcd 集群的 Leader 上,然后再通过 Raft 协议复制到 etcd 集群的所有成员中,以此维护各成员(节点)状态的一致性与 可靠性。虽然 etcd 是一个强一致性的系统,但也支持从非 Leader 节点读取数据以提高性能,但是写操作仍然需要 Leader,所以当发生网络分区时,写操作仍可能失败。

关于 Raft 协议,etcd 专门提供了 Go 语言版本的代码实现 ,并广泛应用于各种项目,除了 etcd 之外,还包括 docker swarm kit等。

然后作为一个分布式系统,etcd 的容错能力也是不错的。假设集群中共有 n 个节点,即便集群中 (n - 1) / 2 个节点发生了故障,只要剩下的 (n + 1) / 2 个节点达成一致,也能操作成功,因此它能够有效地应对网络分区和机器故障带来的数据丢失风险。

etcd 架构简介

etcd 在设计的时候重点考虑了如下的四个要素。

1. 简单

  • 1. 支持 RESTful 风格的 HTTP+JSON API
  • 2. 从性能角度考虑,etcd 增加了对 gRPC 的支持,同时也提供 rest gateway 进行转化
  • 3. 使用 Go 语言编写,跨平台、部署和维护简单
  • 4. 使用 Raft 算法保证强一致性,Raft 算法可理解性好

2. 安全

  • 支持 TLS 客户端安全认证

3. 性能

  • 单实例支持每秒一千次以上的写操作(v2 版本),极限写性能可达 10K+ 的QPS(v3 版本),现在都用 v3 不用 v2 了

4. 可靠

  • 使用 Raft 算法充分保证了分布式系统数据的强一致性;etcd 集群是一个分布式系统,由多个节点相互通信构成整体对外服务,每个节点都存储了完整的数据,并且通过 Raft 协议保证了每个节点维护的数据都是一致的

简单地说,etcd 可以扮演两大角色,具体如下:

  • 持久化的键值存储系统
  • 提供分布式系统的数据一致性

在分布式系统中,如何管理节点间的状态一直是一个难题,etcd 像是专门为集群环境的服务发现和注册而设计的。它提供了数据 TTL 失效、数据改变监视、多值、目录、分布式锁原子操作等功能,可以方便地跟踪并管理集群节点的状态。

etcd 大体上可以分为如下几个部分:

按照分层模型,etcd 可以分为客户端、API 网络层、Raft 算法层、逻辑层和存储层,这些层的功能如下。

  • 客户端:和 zookeeper 一样,etcd 也提供了一个客户端(etcdctl),可以直接输入命令让 etcd 服务端执行。当然客户端也可以是 Python、Go 等编程语言实现的客户端,并且 API 有 v2 和 v3 两个版本,现在用 v3 即可;
  • API 网络层:主要包括 client 访问 server、以及 server 之间通信(当通过 Raft 算法实现数据复制、以及 Leader 选举时)所使用的协议,v2 API 使用 HTTP/1.1 协议,v3 API 使用 gRPC 协议。同时 v3 API 通过 etcd grpc-gateway 组件也支持 HTTP/1.1,便于各种语言的服务调用;
  • Raft 算法层:实现了 Leader 选举、日志复制、ReadIndex 等核心算法特性,用于保障 etcd 多个节点间的数据一致性、提升服务可用性等,是 etcd 的基石和亮点;
  • 功能逻辑层:etcd 核心特性实现层,如典型的 KVServer 模块、MVCC 模块、Auth 鉴权模块、Lease 租约模块、Compactor 压缩模块等,其中 MVCC 模块主要由 treeIndex 模块和 boltdb 模块组成;
  • 存储层:存储层包含预写日志(WAL)模块、快照(Snapshot)模块、boltdb 模块,其中 WAL 可保障 etcd 宕掉后数据不丢失,因为所有的数据提交前都会先写入日志。Snapshot 是为了防止数据过多而进行的状态快照,boltdb 负责保存集群元数据和用户写入的数据(提交前先写入 WAL);

当一个请求到来时,API 层会先转发给逻辑层进行具体的事务处理,如果涉及到节点的修改,则交给 Raft 层进行仲裁和日志记录。而 etcd 是采用 Raft 协议的 Leader-Follower 架构,满足以下几个特点:

  • 多个副本节点中,有且只有一个副本会被指定为「领导者」,它是整个分布式系统中的霸道总裁,一切都要以它为准。当客户端要向系统中写入数据时,它必须将请求发给领导者,领导者会将其持久化到 WAL 中;
  • 其它副本被称为「追随者」,每当领导者将数据持久化到 WAL 时,它也会将数据变更广播给追随者,这个过程就是「复制日志」。每个追随者从领导者拉取日志,并相应更新本地的副本,并且顺序和领导者写入的顺序保持一致;
  • 当客户端想从系统读取数据时,它可以向领导者或追随者查询,但只有领导者才能接收写操作(从客户端的视角来看,追随者都是只读的);

然后重点来了,领导者将新请求的数据持久化到 WAL 的时候,还会广播给其它节点。如果有一半以上的节点成功完成 WAL 持久化,则该请求对应的日志条目就会被标记为已提交,然后异步拉取已提交的日志条目,并应用到状态机(boltdb)。

而为了保证数据的强一致性,etcd 集群中所有的数据流向都是一个方向,从 Leader(主节点)流向 Follower,也就是所有 Follower 的数据必须与 Leader 保持一致,如果不一致会被覆盖。

简单点说就是,客户端可以对 etcd 集群中的所有节点进行读写。首先读取非常简单,因为每个节点保存的数据是强一致的。对于写入来说,etcd 集群会选举出 Leader 节点,如果写入请求来自 Leader 节点,则可以直接写入,然后 Leader 节点会把写入分发给所有的 Follower;如果写入请求来自其它 Follower 节点,那么写入请求会给转发给 Leader 节点,由 Leader 节点写入之后再分发给集群上所有其它节点。

etcd 典型应用场景

正如上面介绍的那样,etcd 的定位是通用的一致性 key/value 存储,但也有服务发现和共享配置的功能。因此典型的 etcd 应用场景包括但不限于分布式数据库、服务注册与发现、分布式锁、分布式消息队列、分布式系统选主等 。etcd 的定位是通用的一致性 key/value 存储,同时也面向服务注册与发现的应用场景。下面将对 etcd 的一些典型应用场景进行简单概括。

服务注册与发现

服务发现(Service Discovery)要解决的是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务如何才能找到对方并建立连接。从本质上说,服务发现就是要了解集群中是否有进程在监听指定的 UDP 或 TCP 端口,并且通过名字就可以进行查找和链接。而要解决服务发现的问题,需要具备如下三个条件:

  • 需要一个强一致性、高可用的服务存储目录,而基于 Raft 算法的 etcd 天生就完美符合这一点。
  • 可以对服务进行注册,并且还能监控服务的健康状况;而用户可以在 etcd 中注册服务,并且对注册的服务配置 key TTL,定义保持服务的心跳以达到监控健康状态的效果。
  • 具备查找和连接服务的机制,在 etcd 指定的主题下注册的服务也能在该主题下被找到;为了确保连接,我们可以在各个服务机器上都部署一个代理模式的 etcd,这样就可以确保访问 etcd 集群的服务都可以互相连接。

图上有三个角色,分别是服务请求方、服务提供方、服务注册方。假设有三台机器:A、B、C,用于提供邮件发送服务,这个时候服务请求方如果想要使用邮件发送服务,那么就会去找服务提供方。但服务请求方并不是直接寻找服务提供方,因为它不知道提供请求的是谁,所以它会寻找服务注册方,然后服务注册方将服务提供方的信息返回给服务请求方,比如:返回 A、B、C 的 IP 和端口,表示这三台机器是用来提供服务的。

但是服务注册方如何才能准确返回服务提供方的信息呢?显然服务提供方是要先进行注册的,服务注册方保存了提供方的信息。并且提供方还要不断地向注册方发送心跳信息,表示自己还活着。假设 B 机器挂掉了,那么请求方向注册方寻找服务方的时候,注册方就不会再返回 B 机器的信息了。所以服务请求方首先找的是服务注册方,而我们的 etcd 充当的就是服务注册方这一角色,当然 zookeeper 也是类似。

消息发布和订阅

在分布式系统中,组件之间的通信机制最为适用的是消息的发布和订阅机制。具体而言就是,设置一个配置共享中心,消息提供者在这个配置中心发布消息,而消息使用者则订阅它们关心的主题,一旦所关心的主题有消息发布,就会实时通知订阅者。通过这种方式,我们可以实现分布式系统配置的集中式管理和实时动态更新,比如:

etcd 管理应用配置信息更新

这类场景的使用方式通常是,应用在启动的时候主动从 etcd 获取一次配置信息,同时在 etcd 节点上注册 Watcher 并等待。以后每当配置有更新的时候,etcd 都会实时通知订阅者,以此达到获取最新配置信息的目的。

分布式日志收集系统

这个系统的核心工作是收集分布在不同机器上的日志。

收集器通常按应用(或主题)来分配收集任务单元,因此可以在 etcd 上创建一个以应用(或主题)为名字的目录,并将这个应用(或主题)相关的所有机器 IP 以子目录的形式存储在目录下。然后设置一个递归的 etcd Watcher,递归式地监控应用(或主题)目录下所有信息的变动。这样就能够实现在节点 IP(消息)发生变动时,系统能够实时接受收集器调整的任务分配。

负载均衡

在分布式系统中,为了保证服务的高可用以及数据的一致性,通常都会把数据和服务部署为多份,以此达到对等服务,即使其中的某一个服务失效了,也不会影响使用。

这样的实现虽然会导致一定程度上数据写入性能的下降,但是却能够实现数据访问时的负载均衡 。因为每个对等服务节点上都存储有完整的数据,因此所有用户的访问流量都可以分流到不同的机器上。

分布式通知与协调

这里讨论的分布式通知与协调,和消息的发布订阅有点相似。两者都使用了 etcd 的 Watcher 机制,通过注册与异步通知机制, 实现分布式环境下不同系统之间的通知与协调,从而对数据变更进行实时处理。

实现方式是不同的系统都在 etcd 上对同一个目录进行注册,同时设置 Watcher 监控该目录的变化(如果子目录的变化也有需求,那么可以设置成递归模式)。若某个系统更新了 etcd 的目录,那么设置了 Watcher 的系统就会收到通知,并也做出相应的通知,然后进行相应的处理。

分布式锁

因为 etcd 使用 Raft 算法保证了数据的强一致性,操作之后存储到集群中的值就必然是全局一致的,所以 etcd 很容易实现分布式锁。

而锁服务包含两种使用方式:保持独占,以及控制时序。

保持独占

即所有试图获取锁的用户最终只有一个可以得到。etcd 为此提供了一套实现分布式锁原子操作 CAS(ComparaAndSwap)的 API,通过设置 prevExist 值,可以保证在多个节点上同时创建某个目录时,只有一个节点能够成功,而成功的那个即可获得分布式锁。

控制时序

试图获取锁的所有用户都会进入等待队列,获得锁的顺序是全局唯一的,同时还能决定队列的执行顺序。etcd 为此也提供了一套 API(自动创建有序键),它会将一个目录的键值指定为 POST 动作,这样 etcd 就会在目录下生成一个当前最大的值作为 key。

同时还可以使用 API 按顺序列出所有目录下的键值,此时这些 key 就是客户端的时序,而 value 则可以是代表客户端的编号。

分布式队列

分布式队列的常规用法与分布式锁的控制时序类似,即通过创建一个先进先出的队列来保证顺序。

另一种比较有意思的实现是在保证队列达到某个条件时再统一按顺序执行,要实现这种方法,可以创建一个 /queue 目录,然后在里面另外建立一个 /queue/condition 节点,如图所示:

  • condition 可以表示队列的大小,比如一个大的任务需要在很多小任务都就绪的情况下才能执行,那么每当有一个小任务就绪时,就将这个 condition 的数值加 1,直到到达大任务规定的数字,然后再开始执行队列里的一系列小任务,直至最终执行大任务。
  • condition 可以表示某个任务不在队列中,这个任务既可以是所有排序任务的首个执行程序,也可以是拓扑结构中没有依赖的点。通常必须在执行这些任务之后才能执行队列中的其他任务。
  • condition 还可以表示开始执行任务的通知,可以由控制程序来指定,当 condition 发生变化时,开始执行队列任务。

集群监控与 Leader 竞选

通过 etcd 来进行监控的功能实现起来非常简单并且实时性较强,主要会用到如下两点特性:

  • 前面几个场景已经提到了 Watcher 机制,当某个节点消失或发生变动时,Watcher 会第一时间发现并告知用户;
  • 节点可以设置 TTL key,比如每隔 30s 向 etcd 发送一次心跳信号,代表该节点依然存活着,否则就说明节点已经消失了;

这样就可以第一时间检测到各节点的健康状态,以完成集群的监控要求。

另外,使用分布式锁还可以完成 Leader 竞选,并且对于一些需要长时间进行 CPU 计算或使用 I/O 的操作,只需要由竞选出 Leader 计算或处理一次,再把结果复制给其他的 Follower 即可,从而避免重复劳动,节省计算资源。

Leader 应用的经典场景是在搜索系统中建立全量索引,如果各个机器都进行索引的建立,那么将很难保证索引的一致性。通过 etcd 的 CAS 机制竞选 Leader,再由 Leader 进行索引计算,最后将计算结果分发到其它节点即可。

etcd 与其它键值存储系统的对比

这里我们主要探讨 etcd 和 zookeeper 之间的区别。zookeeper 是一个用于维护配置信息 、命名、分布式同步以及分组服务的集中式服务框架,它使用 Java 语言编写,通过 Zab 协议来保证节点的一致性。因为 zookeeper 是一个 CP 型系统,所以在发生网络分区问题时,系统不能注册或查找服务。

zookeeper 和 etcd 可用于解决的问题:分布式系统的协同和元数据存储。然而,etcd 却有着 zookeeper 的设计和实现的后见之明,zookeeper 最大的问题就是太复杂了,etcd 吸取了 zookeeper 的教训后具备更好的工程和运维体验。相比 zookeeper,etcd 的改进之处在如下几个方面:

  • 动态的集群节点关系重配置
  • 高负载条件下的稳定读写
  • 多版本并发控制的数据模型
  • 持久、稳定的 watch,而不是简单的单次触发式 watch。zookeeper 的单次触发式 watch 是指监听到一次事件之后,需要客户端重新发起监听,这样 zookeeper 服务器在接收到客户端的监听请求之前的事件是获取不到的;而且在两次监昕请求的时间间隔内发生的事件,客户端也是没法感知的。etcd 的持久监听是每当有事件发生时,就会连续触发,不需要客户端重新发起监听;
  • 租约(lease)原语实现了连接和会话的解耦
  • 安全的分布式共享锁 API

另外 etcd 广泛支持各种各样的语言和框架,但 zookeeper 只有它自己的客户端协议:Jute RPC 协议。 Jute 是 zookeeper 独一无二的协议,且只在特定的语言库(Java 和 C)中绑定。etcd 的客户端协议 gRPC,它是一个流行的 RPC 框架,支持的语言非常多。gRPC 也能序列化成通过 HTTP 传输的 JSON,所以通用的命令行工具 curl 也能与它进行交互。这就为分布式系统的构建者提供了丰富的选择,他们能够用操作系统原生的工具来构建,而不是非得围绕 etcd 用指定的技术,也就是无需迎合 etcd,而是让 etcd 配合你。

至于其它的分布式键值存储系统就不对比了,总之 etcd 绝对是脱颖而出的。

etcd 相关概念

etcd 中存在许多概念,或者说术语,来看一下,先有一个印象。

  • Raft:etcd 所采用的保证分布式系统强一致性的算法
  • Node:一个 Raft 状态机实例,就是里面的 boltdb
  • Member:一个 etcd 实例,它管理着一个 Node,并且可以为客户端请求提供服务
  • Cluster:由多个 Member 构成的,遵循 Raft 一致性协议的 etcd 集群
  • Peer:对同一个 etcd 集群中的其它 Member 的叫法
  • Client:客户端,凡是连接 etcd 服务器请求服务的,比如获取 key-value、写数据等等,都统称为 Client;所以 etcd 命令行连接工具、编写的连接 etcd 服务的代码对应的进程都是 Client
  • Proposal:一个需要经过 Raft 一致性协议的请求,例如写请求或配置更新请求
  • Quorum:Raft 协议需要的、能够修改集群状态的、活跃的 etcd 集群成员数量称为 Quorum(法定人数)。etcd 使用仲裁机制,若集群中存在 n 个节点,那么有 (n+ 1) / 2 个节点达成一致,则操作成功。所以建议的最优节点数 3、5、7、9,也就是奇数个。大多数用户场景中, 一个包含 7 个节点的集群是足够的,更多的节点(比如 9、11 等)可以最大限度地保证数据安全,但是写性能会受影响,因为需要向更多的节点写入数据
  • WAL:预写式日志,etcd 用于持久化存储的日志格式
  • Raft:etcd 集群在某一时间点的快照(备份),etcd 为防止 WAL 文件过多而设置的快照,用于存储 etcd 的数据状态
  • Proxy:etcd 的一种模式,为 etcd 集群提供反向代理服务
  • LeaderRaft 算法中通过竞选而产生的负责客户端写请求的节点,即领导者节点
  • Follower:如果竞选失败没能成为 Leader,那么节点会自动成为 Raft 中的 Follower 节点,即追随者节点,负责为算法提供强一致性保证
  • Candidate:Follower 超过一定的时间接收不到 Leader 的心跳时,它会认为 Leader 已经挂掉了,于是决定咸鱼翻身成为 Leader。但想成为 Leader 需要竞选,而竞选需要节点从 Follower 转变为 Candidate,然后才能发起投票
  • Term:某个节点从成为 Leader 到下一次竞选的时间,称为一个 Term
  • IndexWAL 日志数据项编号,在 Raft 中通过 Term 和 Index 来定位数据
  • Key:键
  • Key space:键空间,etcd 集群内所有键的集合
  • Revision:etcd 集群范围内 64 位的计数器,键空间的每次修改都会导致该计数器的增加
  • Modification Revision:一个 key 最后一次修改的 revision
  • Lease:一个短时的(会过期)、可续订的契约(租约),当它过期时,会删除与之关联的所有键
  • Transition:事务,一个自动执行的操作集,要么一块成功,要么一块失败
  • Watcher:观察者,etcd 最具特色的概念之一。客户端通过打开一个观察者来获取一个指定键范围的更新
  • Key Range键范围,一个键的集合。这个集合既可以是一个 key、也可以是在一个字典区间,例如(a, b],或者是大于某个 key 的所有 key
  • Endpoint:指向 etcd 服务或资源的 URL
  • Compaction:etcd 的压缩(Compaction)操作,丢弃所有 etcd 的历史数据并且取代一个给定 revision 之前的所有 key;压缩操作通常用于重新声明 etcd 后端数据库的存储空间,和 Raft 的日志压缩是一个原理
  • Key version:键版本,即一个键从创建开始的写(修改)次数,从 1 开始;一个不存在或已删除的键版本是 0,注意 key version 和 revision 的概念不同

etcd 发展里程碑

etcd 已经进化到 3.x 版本了,发展到现在总共有 3 个可以成为里程碑的版本,分别是 0.4、2.0、3.0,我们分别介绍一下。

etcd 0.4

该版本是 etcd 对外发布的第一个稳定版本,很多特性均在这个版本成型。比如以下几个特性:

  • 使用 Raft 算法做分布式协同
  • HTTP + JSON 的 API
  • 使用 SSL 客户端证书验证
  • 基准测试在每个实例中每秒写入 1000 次等等

etcd 2.0

该版本是 etcd 第一个真正意义上的大版本,其引入了如下几个重要特性:

  • 内部 etcd 协议的优化能够有效避免意外的错误配置
  • etcdctl 增加了 backup 子命令, 便于从集群异常中恢复数据
  • 运行时动态更新集群 member 配置, 通过 etcdctl 客户端的 member 子命令: etcd member list/add/remove 可以动态查看集群信息和调整集群大小
  • 通过 CRC校验 和append-only的行为提高了存盘数据的安全性
  • 优化的 Raft 一致性算法实现, 该实现被其他项目, 例如 CockroachDB 引用
  • etcd 的 TCP 2379/2380 端口正式成为 IANA(The Internet Assigned Numbers Authority, 互联网数字分配机构)官方分配的端口; 变得更有名了, 比如提到3306你会想到MySQL、提到6379你会想到Redis

etcd 3.0

该版本在 etcd 2.0 的基础上引入了多处优化,可以说是万众瞩目,千呼万唤始出来,并且一经发布即引起了巨大的轰动。优化内容具体如下:

  • 提升了整体吞吐率、降低了延迟, 通过 gRPC API 降低了 Raft 协议调用的开销, 提高了 WAL 的磁盘利用率
  • 全新的存储后端带来了每个 key 平均内存开销的减少
  • 自动的 TLS 配置(可能需要用户提供 ca 证书)
  • 扁平的二进制键空间, 摒弃了 v2 的 key-value 层级和目录
  • 全新的 v3 API, 支持基于 key 为前缀和范围的 get/watch
  • 多版本的键空间, 允许访问历史版本的 key
  • 事务, 将对 etcd 服务的多个请求合并成一个操作
  • 租约, 允许一组 key 共享一个 TTL
  • 监控/告警, 通过存储配额保护 etcd 免受偶然发生的超额使用

以上就是 etcd 的几个著名的版本,如果想要更加详细地了解 etcd 的变迁,可以查看 etcd 发布的各个版本的 CHANGELOG。对于我们现在来说,使用 3.x 的版本就行。

posted @ 2023-05-26 15:37  古明地盆  阅读(450)  评论(0编辑  收藏  举报