菜单

概述

相关源文件

etcd 是一个分布式可靠键值存储,专为分布式系统中最重要的关键数据而设计。本文档介绍了 etcd 的核心概念、架构和关键特性,以帮助开发人员理解该系统。

什么是 etcd?

etcd 是一个高度一致的分布式键值存储,为跨集群机器存储数据提供了一种可靠的方式。它使用 Go 语言编写,并利用 Raft 共识算法 来管理一个高可用的复制日志,为访问具有强一致性保证的分布式数据提供了标准接口。

主要功能

  • 简单:定义清晰、面向用户的 API(gRPC)
  • 安全:自动 TLS,可选客户端证书认证
  • 快速:基准测试显示每秒可处理 10,000 次写入
  • 可靠:通过 Raft 共识算法实现分布式可靠性
  • 一致性:强一致性的读写
  • 高可用:容忍机器故障,包括领导者故障

etcd 被广泛应用于生产环境中,尤其作为 Kubernetes 和其他需要可靠协调服务的分布式系统的主要数据存储。

来源:README.md21-30 README.md28-36

系统架构

etcd 遵循客户端-服务器架构,其中多个 etcd 服务器实例组成一个集群。客户端使用 etcd 客户端库或 etcdctl 命令行工具与集群通信。

高层架构

etcd 架构包含几个关键组件

  1. 客户端接口:提供 gRPC API 和客户端库供应用程序与 etcd 交互
  2. 服务器核心(EtcdServer):处理客户端请求,协调集群操作
  3. 身份验证系统:管理身份验证和基于角色的访问控制
  4. MVCC 存储:多版本并发控制存储,维护版本化的键值数据
  5. 租约系统:管理键的 TTL 和过期
  6. Raft 共识:实现 Raft 算法以实现分布式共识
  7. 存储:包括预写日志(WAL)和 bbolt 数据库后端

来源:server/etcdserver/server.go209-301 server/etcdserver/raft.go80-148 server/etcdserver/v3_server.go59-102

请求处理流程

此图说明了不同类型的请求是如何在 etcd 系统中处理的

  • 读操作可以是串行化的(可能过时)或可线性化的(保证最新)
  • 写操作始终通过 Raft 共识过程,以确保集群之间的一致性

来源:server/etcdserver/v3_server.go104-159 server/etcdserver/server.go1017-1077

核心组件

EtcdServer

EtcdServer 是核心协调组件,负责处理客户端请求、管理 Raft 共识协议以及集成所有其他 etcd 子系统。它在 server/etcdserver/server.go 中定义,并实现了包括 ServerRaftStatusGetterAuthenticator 在内的多个接口。

主要职责

  • 将客户端请求应用于状态机
  • 协调集群成员变更
  • 管理租约和监听
  • 编排快照和压缩

来源:server/etcdserver/server.go209-301 server/etcdserver/server.go538-608

Raft 共识

etcd 使用 Raft 共识算法在集群中保持一致性。raftNode 结构封装了 Raft 协议实现,位于 server/etcdserver/raft.go 中。

Raft 实现的关键方面

  • 领导者选举,用于协调写入
  • 日志复制,以保持一致性
  • 安全特性,以防止脑裂场景
  • 成员变更(添加/删除节点)

来源:server/etcdserver/raft.go80-155 server/etcdserver/server.go1017-1077

存储系统

etcd 的存储系统包含多个层

  1. MVCC(多版本并发控制):

    • 维护版本化的键值对
    • 支持在不阻塞写入的情况下进行并发读取
    • 支持通过修订号进行历史查询
  2. bbolt 后端:

    • 持久化的 B+ 树键值数据库
    • 提供事务和持久性
    • 存储实际的键值数据
  3. 预写日志 (WAL):

    • 在应用所有修改之前记录所有变更
    • 用于崩溃恢复
    • 提供持久性保证
  4. 快照生成器:

    • 创建数据库状态的即时快照
    • 用于恢复和成员添加
    • 允许压缩 WAL 以节省空间

来源:server/etcdserver/server.go209-301 server/etcdserver/bootstrap.go168-178

认证与授权

etcd 提供全面的安全模型,包括身份验证和基于角色的访问控制(RBAC)

主要安全特性

  • 用户名/密码的用户身份验证
  • 基于 JWT 的令牌身份验证
  • 基于角色的访问控制,具有细粒度的权限
  • TLS 用于加密的客户端-服务器和点对点通信

来源:server/etcdserver/server.go381-384 server/etcdserver/v3_server.go84-102

客户端交互

客户端通过 etcdctl 命令行工具或客户端库与 etcd 交互。主要通信协议是 gRPC,并有一个用于 RESTful 访问的 HTTP/JSON 网关。

客户端库

主要的客户端库是 clientv3,它提供了一个与 etcd 交互的 Go API。它包括

  • KV 操作(Get、Put、Delete)
  • Watch 功能,用于监控变更
  • 租约管理,用于键的 TTL
  • 分布式并发原语(锁、选举)
  • 集群管理操作

来源:server/etcdserver/v3_server.go59-102 README.md115-119

etcdctl 命令行接口

etcdctl CLI 提供了一种用户友好的方式,可以通过命令行与 etcd 进行交互。它支持客户端库提供的所有核心操作。

示例操作

  • 键值操作:putgetdel
  • Watch 操作:watch
  • 租约操作:lease grantlease revoke
  • 身份验证:user addrole grant
  • 集群管理:member addendpoint health

来源:README.md32-34 README.md79-83

集群和复制

etcd 使用 Raft 共识在集群节点之间保持一致性。这使其能够容忍机器故障(包括领导者故障),同时维护数据完整性。

集群形成

集群可以通过以下方式形成:

  • 静态配置,包含显式的对等 URL
  • 使用发现服务进行动态发现
  • 基于 DNS 的发现

可以在集群运行时动态添加、删除或更新成员。新节点在被提升为完全投票成员之前,可以作为“学习者”添加。

来源: server/etcdserver/server.go161-196 server/etcdserver/bootstrap.go272-287 server/etcdserver/api/membership/cluster.go42-62

领导者选举与日志复制

在一个基于 Raft 的系统中,例如 etcd

  • 一个节点被选举为领导者
  • 所有写操作都通过领导者进行
  • 领导者将日志条目复制给追随者
  • 多数节点必须确认每个条目
  • 一旦提交,条目就会应用到状态机

领导者选举过程确保任何时候只有一个领导者,从而防止了脑裂的情况。

来源: server/etcdserver/raft.go80-155 server/etcdserver/server.go475-497

监控和维护

etcd 通过 Prometheus 指标和内置的健康检查提供全面的监控功能。

健康监控

  • 用于健康检查的 HTTP 端点: /health, /livez, /readyz
  • 用于监控性能和资源使用的指标
  • 用于检测和报告问题的警报机制

维护操作

etcd 需要定期维护以确保最佳性能

  • 压缩:删除旧版本以释放空间
  • 碎片整理:回收已删除数据的磁盘空间
  • 快照:创建备份以进行灾难恢复
  • 升级:升级到新版本的程序

来源: server/etcdserver/api/v3rpc/maintenance.go72-102 server/etcdserver/corrupt.go39-85

结论

etcd 提供了一个具有强一致性保证的可靠分布式键值存储,使其非常适合存储关键配置数据和构建分布式系统。它结合了简洁性、安全性、性能和可靠性,已成为许多现代云原生架构(尤其是 Kubernetes)的基石。

有关 etcd 特定方面的更详细信息,请参阅这些相关的 wiki 页面