1. 引言

在分布式系统的复杂世界里,高效的数据管理至关重要。分布式键值存储在维护分布式环境中的数据一致性和可扩展性方面扮演着关键角色。

本教程将深入探讨 etcd——一个开源的分布式键值存储。我们将解析其核心概念、特性和用例,并提供快速上手指南。最后,通过与其他分布式键值存储的对比,揭示 etcd 的独特优势。

2. 什么是分布式键值存储?

分布式键值存储是一种 NoSQL 数据库,将数据以键值对的形式存储在多个物理或虚拟机上

这种分布式架构本质上提升了可扩展性、容错性和性能。每个数据项(值)都关联一个唯一标识符(键)。该模型在缓存、配置管理和快速数据检索等场景中效率极高。

典型实现包括 Apache Zookeeper、Consul 和 Redis。分布式键值存储是众多分布式系统的基石,提供了简单而强大的数据存储和检索机制。

核心特性如下:

  • 简洁性:基于键值对的基本数据结构,易于理解和应用
  • 可扩展性:通过多节点分布负载,高效处理数据增长和访问压力
  • 可靠性:确保数据一致性、容错性和可扩展性
  • 高性能:键值机制提供快速数据访问,多节点分布降低单机负载
  • 分布式特性:数据跨节点分布,显著提升整体性能

典型应用场景包括:配置管理、缓存、会话存储、服务发现、领导者选举等

3. etcd 是什么?

etcd 是专为分布式系统关键数据设计的分布式可靠键值存储。它是一个简单、安全、快速且可靠的键值存储,专为配置管理、服务发现和分布式系统协调而设计

由 CoreOS 团队开发,现为 CNCF(云原生计算基金会)项目,etcd 在动态可扩展环境中提供可靠的数据存储,支持配置协调和服务发现。

etcd 使用 Go 语言开发,内部采用 Raft 共识算法管理高可用复制日志。

百度、华为、Salesforce、Ticketmaster 等公司已在生产环境中使用 etcd。它常与 Kubernetes、Locksmith、Vulcand、Doorman 等应用集成。

etcd 丰富的功能集使其成为分布式系统的理想选择,为云原生环境中的配置管理、服务发现和协调提供基础组件。其对分布式一致性、高可用性和数据完整性的承诺,使其成为现代可扩展弹性应用的核心组件。

4. etcd 的核心特性

etcd 的功能集使其成为分布式系统的可靠选择,提供配置管理、服务发现和协调的基础模块。特定场景下可达 10,000 写入/秒。

关键特性解析:

  • HTTP/gRPC API:提供双协议支持,方便多语言集成
  • 分布式一致性:在集群中维护强一致性,确保所有节点数据视图一致
  • 高可用性:内置领导者选举和故障转移机制,节点故障时集群仍可运行
  • 监听支持:提供强一致性监听机制,实时监控键值变化
  • 原子事务:支持将多个操作组合为原子单元执行,保障数据一致性
  • 租约管理:支持键关联 TTL,到期自动删除
  • **基于角色的访问控制 (RBAC)**:精细化管理用户和应用的访问权限
  • 快照与备份:提供集群状态快照和备份恢复机制,确保灾难恢复
  • 可插拔存储后端:支持 LevelDB、RocksDB 等存储引擎,灵活适配不同场景
  • Kubernetes 集成:作为 Kubernetes 的核心数据存储,支撑容器编排
  • etcdctl:官方命令行工具,简化集群管理操作

5. 安装指南

快速配置并启动 etcd。etcd 兼容 Ubuntu、CentOS 等 Linux 发行版及 Windows。

在 Ubuntu 上更新包列表:

$ sudo apt update

安装 etcd:

$ sudo apt install etcd

CentOS 环境需先启用 EPEL 仓库:

$ sudo yum install epel-release
$ sudo yum install etcd

或从 GitHub 发布页 下载最新版本,也可克隆仓库:

$ git clone -b v3.5.11 https://github.com/etcd-io/etcd.git

解压并进入目录:

$ tar xvf etcd-v3.5.11-linux-amd64.tar.gz
$ cd etcd

执行构建脚本:

$ ./build.sh

二进制文件位于 bin 目录,添加到 PATH:

$ export PATH="$PATH:`pwd`/bin"

验证安装:

$ etcd --version

6. 配置文件详解

etcd 提供多种配置方式,这里通过配置文件实现基础设置。

配置文件采用 YAML 格式,用于定制网络、集群、认证等关键参数。示例配置:

# etcd-config.yml 示例
# 节点唯一标识
name: node-1

# 数据存储目录
data-dir: /var/lib/etcd/default.etcd

# 客户端监听地址
listen-client-urls: http://127.0.0.1:2379,http://<NODE-IP>:2379

# 客户端通告地址
advertise-client-urls: http://<NODE-IP>:2379

# 节点间通信监听地址
listen-peer-urls: http://<NODE-IP>:2380

# 节点间通信通告地址
initial-advertise-peer-urls: http://<NODE-IP>:2380

# 初始集群配置
initial-cluster: node-1=http://<NODE-IP>:2380,node-2=http://<NODE-IP>:2380

# 集群唯一令牌
initial-cluster-token: etcd-cluster-1

# 初始集群状态 (new/existing/standby)
initial-cluster-state: new

# 启用认证令牌
auth-token: "some-secret-token"

# 启用 RBAC 授权
enable-authorization: true

# 启用自动压缩
auto-compaction-mode: periodic
auto-compaction-retention: "1h"

# TLS 安全配置
client-transport-security:
  cert-file: /etc/etcd/server.crt
  key-file: /etc/etcd/server.key
  client-cert-auth: true
  trusted-ca-file: /etc/etcd/ca.crt

peer-transport-security:
  cert-file: /etc/etcd/peer.crt
  key-file: /etc/etcd/peer.key
  client-cert-auth: true
  trusted-ca-file: /etc/etcd/ca.crt

配置要点:

  • TLS 证书:生产环境强烈建议启用加密通信
  • RBAC 集成:通过角色权限控制增强安全性
  • 自动压缩:定期清理历史数据(如每小时),控制存储空间

修改配置后需重启 etcd 服务生效。

7. 启动与交互

通过配置文件启动 etcd:

$ ./etcd --config-file=etcd-config.yml

使用 etcdctl 命令行工具与集群交互,支持直接执行管理操作。

基础操作示例: 设置键值对:

$ etcdctl put mykey "Hello, etcd!"

获取键值:

$ etcdctl get mykey
mykey
Hello, etcd!

监听键变化:

$ etcdctl watch mykey

监听机制可实时接收键变更通知(修改或删除),但需注意:监听不阻止键被删除,仅提供变更观察。

检查集群健康状态:

$ etcdctl endpoint health

对于安全集群,需额外提供 --cacert--cert--key 参数指定证书文件。

8. Java 代码示例

使用 Java 客户端库 jetcd(官方 v3 客户端)与 etcd 交互。

jetcd 基于 Java 11,支持 SSL 安全、多连接配置,提供同步/异步双 API。添加 Maven 依赖:

<dependency>
    <groupId>io.etcd</groupId>
    <artifactId>jetcd-core</artifactId>
    <version>0.7.7</version>
</dependency>

基础操作示例(put/get/delete):

public class JetcdExample {
    public static void main(String[] args) {
        String etcdEndpoint = "http://localhost:2379";
        ByteSequence key = ByteSequence.from("/mykey".getBytes());
        ByteSequence value = ByteSequence.from("Hello, etcd!".getBytes());

        try (Client client = Client.builder().endpoints(etcdEndpoint).build()) {
            KV kvClient = client.getKVClient();
            
            // 存储键值对
            kvClient.put(key, value).get();
            
            // 异步获取值
            CompletableFuture<GetResponse> getFuture = kvClient.get(key);
            GetResponse response = getFuture.get();
            
            // 删除键
            kvClient.delete(key).get();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

9. 与 Zookeeper/Consul 对比

etcd、Apache ZooKeeper 和 Consul 均为分布式系统工具,但在设计理念、架构和适用场景上存在显著差异:

特性/维度 etcd Apache ZooKeeper Consul
共识算法 Raft Zab Raft
数据模型 键值存储 层次化 ZNode 键值存储
典型场景 云原生/Kubernetes 通用分布式系统 服务发现/网络
一致性模型 强一致性 强一致性 最终一致性
安全特性 TLS + AuthN/AuthZ 内置安全有限 ACL + TLS + 令牌
领导者选举 Raft 内置选举 Zab 协议集中选举 Raft 选举
性能表现 良好 大规模部署验证 高性能可扩展
生态集成 CNCF 项目 Apache 生态 HashiCorp 生态
监控能力 Prometheus 支持 内置监控有限 集成 Prometheus
配置管理 配置 API Hadoop/Kafka 等集成 动态配置管理
服务发现 基础支持 作为系统组件 DNS 核心功能
商业支持 有限 可用 企业版/开源版
易用性 简单直接 相对复杂 配置简单
许可证 Apache 2.0 Apache 2.0 MPL 2.0

选型建议

  • etcd:云原生环境(如 Kubernetes),追求简洁和 CNCF 支持
  • ZooKeeper:大规模部署需强一致性,可接受复杂度
  • Consul:服务发现为核心需求,需集成 HashiCorp 生态

安全要求、易用性和集成需求是决策关键,需根据具体场景权衡选择。

10. 总结

本文全面解析了 etcd 的核心概念、关键特性和实践应用。快速上手指南可帮助读者快速部署并编程交互。与其他分布式键值存储的对比凸显了 etcd 在分布式系统场景中的独特优势。

理解分布式键值存储、etcd 的能力及数据在分布式系统中的重要性,有助于我们在设计和实现分布式应用时做出明智决策。作为众多分布式系统的基石,etcd 的简洁性、一致性和高可用性使其成为开发者应对复杂分布式环境的利器。

本文配套源码可在 GitHub 获取。


原始标题:A Guide to etcd | Baeldung