文档版本 v3.7-DRAFT 处于 草稿 状态。如需获取最新的稳定版文档,请参阅 v3.6。
常见问题
etcd,概述
什么是 etcd?
etcd 是一个一致性分布式键值存储,主要用作分布式系统中的独立协调服务,设计用于保存可完全放入内存的小量数据。
etcd 怎么读?
etcd 的发音为 /ˈɛtsiːdiː/,意思是“分布式的 etc 目录”。
客户端是否必须向 etcd 领导者发送请求?
Raft 是基于领导者的协议;领导者负责处理所有需要集群共识的客户端请求。但客户端无需知道哪个节点是领导者。发送给跟随者的任何需要共识的请求都会自动转发给领导者。不需要共识的请求(例如序列化读取)可以由任意集群成员处理。
配置
listen-<client,peer>-urls、advertise-client-urls 和 initial-advertise-peer-urls 有什么区别?
listen-client-urls 和 listen-peer-urls 指定 etcd 服务器用于接收传入连接的本地地址。若要在所有接口上监听某个端口,可将监听 IP 设为 0.0.0.0。
advertise-client-urls 和 initial-advertise-peer-urls 指定 etcd 客户端或其他 etcd 成员应使用的地址来与该 etcd 服务器通信。这些广播地址必须能从远程机器访问。生产环境中不要使用 localhost 或 0.0.0.0 这类地址,因为它们在远程机器上无法访问。
为什么更改 --listen-peer-urls 或 --initial-advertise-peer-urls 不会更新 etcdctl member list 中显示的对等节点 URL?
成员公布的对等节点 URL 来自集群首次启动时的 --initial-advertise-peer-urls 参数。在成员启动后更改监听的对等节点 URL 或初始公布的对等节点地址不会影响已导出的公布 URL,因为此类更改必须经过法定人数(quorum)确认,以避免成员配置出现脑裂问题。请使用 etcdctl member update 命令来更新成员的对等节点 URL。
部署
系统要求
由于 etcd 会将数据写入磁盘,其性能高度依赖于磁盘性能。因此强烈建议使用 SSD。要评估磁盘是否足够快,可以使用磁盘基准测试工具(例如 fio)。有关具体操作示例,请参阅此处。为防止性能下降或意外超载键值存储,etcd 设置了可配置的存储配额,默认为 2GB。为避免交换分区或内存耗尽,机器应至少配备与该配额相当的内存容量。对于普通环境,建议最大大小为 8GB,若配置值超过此限制,etcd 在启动时会发出警告。在 CoreOS 中,etcd 集群通常部署在专用的 CoreOS Container Linux 机器上,最低配置为双核处理器、2GB 内存和 80GB 的 SSD。请注意:性能本质上取决于工作负载,请在生产部署前进行测试。更多硬件建议请参见 硬件。
最稳定的生产环境是基于 amd64 架构的 Linux 操作系统;更多信息请参见 支持的平台。
为什么集群成员数量应为奇数?
etcd 集群需要大多数节点(即法定人数,quorum)达成一致才能更新集群状态。对于包含 n 个成员的集群,法定人数为 (n/2)+1。对于任何奇数大小的集群,增加一个节点总会提高形成法定人数所需的节点数量。尽管向奇数大小的集群添加节点看似更优(因为机器数量更多),但容错能力反而更差,因为允许发生故障而不失法定人数的节点数量相同,而潜在可能故障的节点却更多了。如果集群已处于无法再容忍任何节点故障的状态,则在移除节点之前先添加新节点是危险的:一旦新节点未能成功注册到集群(例如地址配置错误),法定人数将永久丢失。
最大集群规模是多少?
理论上没有硬性限制。然而,etcd 集群的节点数通常不应超过七个。Google Chubby 锁服务 与 etcd 类似,并已在 Google 内部广泛部署多年,其建议运行五个节点。一个由五个成员组成的 etcd 集群可以容忍两个成员故障,在大多数情况下已经足够。虽然更大的集群能提供更好的容错能力,但写入性能会下降,因为数据必须在更多机器之间复制。
容错能力是什么?
只要能够建立成员的法定人数,etcd 集群就能正常运行。如果因临时网络故障(例如网络分区)导致失去法定人数,当网络恢复并重新建立法定人数后,etcd 会自动且安全地恢复运行;Raft 协议会确保集群的一致性。对于断电情况,etcd 会将 Raft 日志持久化到磁盘;重启后,etcd 将重放日志至故障点并重新加入集群。若发生永久性硬件故障,可通过运行时重新配置将故障节点从集群中移除。
建议集群中的成员数量为奇数。奇数大小的集群与偶数大小的集群具有相同的容错能力,但所需节点更少。通过比较奇偶大小的集群可以明显看出差异:
| 集群大小 | 多数节点数 | 容错能力 |
|---|---|---|
| 1 | 1 | 0 |
| 2 | 2 | 0 |
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 3 | 2 |
| 6 | 4 | 2 |
| 7 | 4 | 3 |
| 8 | 5 | 3 |
| 9 | 5 | 4 |
向集群中添加成员以使集群规模达到偶数,并不能带来额外的容错能力。同样,在网络分区期间,奇数个成员可以确保始终存在一个多数派分区,该分区能够继续运行,并在网络分区结束时作为真实数据的来源。
etcd 是否支持跨区域或跨数据中心部署?
跨区域部署 etcd 可以提高其容错能力,因为成员位于不同的故障域中。代价是由于跨越数据中心边界导致共识请求的延迟更高。由于 etcd 依赖于成员的多数同意来达成共识,因此跨数据中心的延迟会更加明显,因为必须有至少大多数集群成员响应共识请求。此外,集群数据必须在所有对等节点之间复制,因此还会产生带宽开销。
在高延迟环境下,默认的 etcd 配置可能导致频繁选举或心跳超时。请参阅 调优 了解如何调整高延迟部署的超时设置。
运维
如何备份 etcd 集群?
etcdctl 提供了 snapshot 命令用于创建备份。更多详情请参见 备份。
我应该先添加成员再移除不健康的成员吗?
替换 etcd 节点时,应先移除原成员,再添加新成员。
etcd 采用基于法定数量(quorum)模型的分布式共识机制;即 (n/2)+1 个成员(多数)必须就某项提案达成一致后,该提案才能提交至集群。这些提案包括键值更新和成员变更。这种模型完全避免了脑裂不一致的可能性。缺点是如果发生永久性的法定数量丢失,则会造成灾难性后果。
这对成员管理的影响是:如果一个由 3 个成员组成的集群中有 1 个成员宕机,它仍可继续运行,因为法定数量为 2,而仍有 2 个成员正常运行。然而,向一个 3 成员集群中添加新成员会使法定数量增加到 3,因为 4 个成员中的多数需要 3 票支持。由于法定数量增加,这个额外成员在容错能力方面没有任何增益;集群仍然距离不可恢复的状态仅差一次节点故障。
此外,新增成员还存在风险,因为它可能配置错误或无法加入集群。在这种情况下,将无法恢复法定数量,因为集群有两个成员宕机、两个成员在线,但需要三票才能更改成员配置以撤销失败的成员添加操作。默认情况下,etcd 会拒绝可能导致法定数量丢失的成员添加请求。
相反,如果先从集群成员列表中移除已宕机的成员,则成员总数变为 2,法定数量仍为 2。在此之后添加新成员也不会改变法定数量,仍保持为 2。因此,即使新节点无法启动,仍然可以通过剩余活跃成员的法定数量来移除该新成员。
为什么 etcd 不接受我的成员变更请求?
etcd 设置了 strict-reconfig-check 选项,以拒绝可能导致法定数量丢失的重配置请求。放弃法定数量是非常危险的行为(尤其是在集群已经处于不健康状态时)。尽管在失去法定数量的情况下禁用法定数量检查以添加新成员可能看似诱人,但这可能导致严重的集群不一致问题。对于许多应用而言,这会使问题变得更糟(例如出现“磁盘几何结构损坏”这样令人恐惧的情况)。
为什么磁盘延迟激增会导致 etcd 丢失领导者?
这是有意为之的;磁盘延迟是领导者活跃性的一部分。假设集群领导节点需要一分钟才能将 raft 日志更新 fsync 到磁盘,但 etcd 集群的选举超时时间为一秒。尽管领导节点可以在选举间隔内处理网络消息(例如发送心跳),但由于它无法提交任何新提案,因此实际上是不可用的;它正在等待缓慢的磁盘。如果集群由于磁盘延迟而频繁失去领导节点,请尝试调整磁盘设置或 etcd 时间参数。
etcd 警告信息“request ignored (cluster ID mismatch)”是什么意思?
每个新的 etcd 集群都会根据初始集群配置和用户提供的唯一 initial-cluster-token 值生成一个新的集群 ID。通过拥有唯一的集群 ID,etcd 可以防止跨集群交互,这可能会破坏集群。
通常在拆除旧集群后,然后为新集群重用一些对等地址时会出现此警告。如果旧集群中的任何 etcd 进程仍在运行,它将尝试联系新集群。新集群会识别出集群 ID 不匹配,然后忽略请求并发出此警告。通常可以通过确保不同集群之间的对等地址不重叠来清除此警告。
“mvcc: database space exceeded”是什么意思?如何解决?
etcd 中的多版本并发控制数据模型保留了键空间的确切历史记录。如果不定期压缩此历史记录(例如,通过设置 --auto-compaction),etcd 最终会耗尽其存储空间。如果 etcd 存储空间不足,它会引发空间配额警报以保护集群免受进一步写入。只要警报被触发,etcd 就会以错误 mvcc: database space exceeded 响应写入请求。
要从低空间配额警报中恢复:
etcd 警告信息“etcdserver/api/v3rpc: transport: http2Server.HandleStreams failed to read frame: read tcp 127.0.0.1:2379->127.0.0.1:43020: read: connection reset by peer”是什么意思?
当服务器接收到带有客户端流过早关闭的 TCP RST 标志时,gRPC 侧会发出此警告。例如,客户端关闭连接时,gRPC 服务器尚未处理 TCP 队列中的所有 HTTP/2 帧。服务器端可能丢失了一些数据,但只要客户端连接已经关闭,这是可以接受的。
只有旧版本的 gRPC会记录此信息。默认情况下,etcd >=v3.2.13 会以 DEBUG 级别记录此信息,因此只有启用 --log-level=debug 标志时才可见。
性能
应该如何对 etcd 进行性能测试?
etcd 警告信息“apply entries took too long”是什么意思?
当大多数 etcd 成员同意提交一个请求后,每个 etcd 服务器会将其应用到其数据存储中,并将结果持久化到磁盘。即使使用慢速机械磁盘或虚拟化网络磁盘(如 Amazon 的 EBS 或 Google 的 PD),应用请求通常也应在少于 50 毫秒的时间内完成。如果平均应用持续时间超过 100 毫秒,etcd 会警告条目应用时间过长。
通常这个问题是由慢速磁盘引起的。磁盘可能在 etcd 和其他应用程序之间存在争用,或者磁盘本身太慢(例如共享虚拟化磁盘)。要排除慢速磁盘导致此警告的可能性,请监控backend_commit_duration_seconds(p99 持续时间应小于 25 毫秒)以确认磁盘速度合理。如果磁盘太慢,为 etcd 分配专用磁盘或使用更快的磁盘通常可以解决问题。
第二个最常见的原因是 CPU 资源不足。如果监控显示机器的 CPU 使用率很高,那么可能没有足够的计算能力来运行 etcd。将 etcd 移动到专用机器上、增加进程资源隔离(使用 cgroups)或将 etcd 服务器进程优先级提高通常可以解决这个问题。
访问过多键值(例如,获取整个键空间)的昂贵用户请求也可能导致较长的应用延迟。然而,每次请求访问少于几百个键值应该总是高效的。
如果上述建议都无法清除警告,请提交一个问题,并附上详细的日志、监控指标和可选的工作负载信息。
etcd 警告信息“failed to send out heartbeat on time”是什么意思?
etcd 使用基于领导者的共识协议来进行一致的数据复制和日志执行。集群成员选举出一个领导者,其他所有成员成为跟随者。被选举出的领导者必须定期向其跟随者发送心跳以维持其领导地位。如果在选举间隔内没有收到心跳,跟随者会推断领导者失败并触发新的选举。如果领导者未能及时发送心跳但仍在运行,则选举是虚假的,很可能是由于资源不足造成的。为了捕获这些软故障,如果领导者跳过了两个心跳间隔,etcd 将警告它未能按时发送心跳。
通常这个问题是由慢速磁盘引起的。在领导者发送带有元数据的心跳之前,可能需要将元数据持久化到磁盘上。磁盘可能在 etcd 和其他应用程序之间存在争用,或者磁盘本身太慢(例如,共享虚拟磁盘)。要排除慢速磁盘导致此警告的可能性,可以监控wal_fsync_duration_seconds(p99 持续时间应小于 10 毫秒)以确认磁盘速度合理。如果磁盘太慢,为 etcd 分配专用磁盘或使用更快的磁盘通常可以解决问题。要判断磁盘是否足够快以供 etcd 使用,可以使用像fio这样的基准测试工具。请参阅这里的示例。
第二个最常见的原因是 CPU 资源不足。如果监控显示机器的 CPU 使用率很高,那么可能没有足够的计算能力来运行 etcd。将 etcd 移动到专用机器上、增加进程资源隔离(使用 cgroups)或将 etcd 服务器进程优先级提高通常可以解决这个问题。
慢速网络也可能导致此问题。如果 etcd 机器之间的网络指标显示长延迟或高丢包率,那么可能没有足够的网络容量来运行 etcd。将 etcd 成员移动到不太拥挤的网络通常可以解决问题。但是,如果 etcd 集群部署在多个数据中心中,成员之间的长延迟是预期的。对于这种部署,调整heartbeat-interval配置以大致匹配机器之间的往返时间,并将election-timeout配置设置为至少 5 * heartbeat-interval。有关详细信息,请参阅调优文档。
如果上述建议都无法清除警告,请提交一个问题,并附上详细的日志、监控指标和可选的工作负载信息。
etcd 警告信息“snapshotting is taking more than x seconds to finish …”是什么意思?
etcd 发送其完整键值存储的快照以刷新缓慢的跟随者并进行备份。慢速快照传输时间会增加 MTTR;如果集群正在以高吞吐量摄取数据,缓慢的跟随者可能会因在完成接收快照之前需要新的快照而陷入活锁。为了捕获慢速快照性能,当发送快照的时间超过三十秒并且超过了 1Gbps 连接的预期传输时间时,etcd 会发出警告。