当前位置: 首页 > news >正文

【Etcd 】Etcd 详解以及安装教程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

一、Etcd 是什么?分布式系统的 “大脑”

Etcd 是一个分布式、高可用、强一致性的键值存储系统,由 CoreOS 公司开发(后被 CNCF 托管)。它的核心价值在于解决分布式系统中的配置共享、服务发现、分布式锁、选主等场景,堪称分布式系统的 “神经中枢”。

和同类产品(如 ZooKeeper)相比,Etcd 有几个显著优势:

  • 轻量级:部署简单,资源占用少,适合云原生微服务架构。
  • 强一致性:基于 Raft 算法保证分布式数据的强一致性,这在金融、电商等对数据一致性要求高的领域至关重要。
  • 实时感知:客户端通过 “长连接 + Watch 机制”,能实时感知数据变化,让服务发现、配置更新更及时。
  • 生态完善:与 Kubernetes、Docker Swarm 等云原生项目深度集成,是云原生技术栈的核心组件。

二、Etcd 核心概念:理解分布式存储的 “语言”

在动手用 Etcd 之前,先理清几个核心概念,能让你用起来更得心应手。

1. 键值对(Key-Value)

Etcd 最基础的存储单元是键值对,键(Key)是唯一的,值(Value)可以是任意二进制数据(通常存 JSON、字符串等)。比如可以用/config/db/host作为键,存储数据库主机地址。

2. Raft 算法

Etcd 基于Raft 一致性算法实现分布式数据同步。简单来说,Raft 通过 “领导者(Leader)选举、日志复制、安全约束” 三个阶段,保证集群中所有节点的数据最终一致。这也是 Etcd 能在分布式场景下保证数据可靠的核心。

3. Watch 机制

Etcd 支持客户端长连接监听键的变化(Watch)。当某个键的值被修改时,所有 Watch 该键的客户端会立即收到通知,这让 “服务发现自动更新”“配置实时推送” 成为可能。

4. 租约(Lease)

租约是 Etcd 实现 ** 临时节点(如服务注册实例)** 的关键。客户端可以为某个键申请租约,若租约过期(客户端心跳中断),对应的键会被自动删除,这在服务发现中用于 “自动剔除故障节点” 非常有用。

三、Etcd 安装:从单节点到集群

Etcd 的安装方式很灵活,我们先从单节点安装入手,再扩展到集群部署。

方式 1:系统包管理器安装(以 Ubuntu 为例)

这种方式最适合快速体验 Etcd:

 

# 安装Etcd
sudo apt-get update
sudo apt-get install etcd -y# 启动Etcd服务
sudo systemctl start etcd# 设置开机自启
sudo systemctl enable etcd

安装完成后,Etcd 默认会在localhost:2379提供 HTTP API 服务,localhost:2380用于集群内部通信。

方式 2:二进制包安装(适合生产环境定制)

如果需要指定版本或更灵活的配置,二进制包安装是更好的选择:

步骤 1:下载二进制包

从Etcd 官方 Release 页面下载对应系统的二进制包,比如:

 

# 下载并解压(以v3.5.9为例)
wget https://github.com/etcd-io/etcd/releases/download/v3.5.9/etcd-v3.5.9-linux-amd64.tar.gz
tar -zxvf etcd-v3.5.9-linux-amd64.tar.gz
cd etcd-v3.5.9-linux-amd64/
步骤 2:启动单节点 Etcd

 

# 前台启动(方便查看日志)
./etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://localhost:2379
步骤 3:配置为系统服务(可选)

为了让 Etcd 能后台运行并开机自启,我们可以创建 systemd 服务文件:

 

sudo vim /etc/systemd/system/etcd.service

在文件中写入以下内容:

 

[Unit]
Description=Etcd Distributed Key-Value Store
After=network.target[Service]
Type=simple
ExecStart=/path/to/etcd/etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://localhost:2379
Restart=on-failure
RestartSec=5[Install]
WantedBy=multi-user.target

然后启动并设置开机自启:

 

sudo systemctl daemon-reload
sudo systemctl start etcd
sudo systemctl enable etcd

方式 3:Docker 安装(容器化部署)

在容器化环境中,用 Docker 运行 Etcd 也很方便:

 

docker run -d \--name etcd \-p 2379:2379 \-p 2380:2380 \--env ETCD_ADVERTISE_CLIENT_URLS=http://localhost:2379 \--env ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 \quay.io/coreos/etcd:v3.5.9

验证安装是否成功

安装完成后,我们可以用 Etcd 的命令行工具etcdctl验证:

 

# 查看Etcd版本
etcdctl version# 写入一个键值对
etcdctl put /hello "world"# 读取键值对
etcdctl get /hello# 监听键的变化(另开一个终端执行put操作,这里会实时收到通知)
etcdctl watch /hello

如果能正常写入、读取和监听,说明 Etcd 安装成功。

四、Etcd 实战:从基础操作到场景化应用

光装好了还不够,我们通过几个场景,看看 Etcd 在实际开发中怎么用。

示例 1:基础键值操作(命令行 + API)

Etcd 的命令行工具etcdctl提供了丰富的操作命令:

 

# 写入键值
etcdctl put /config/app/name "my-service"
etcdctl put /config/app/port "8080"# 读取键值(单个键)
etcdctl get /config/app/name# 读取键值(前缀查询)
etcdctl get /config/app --prefix# 删除键值
etcdctl del /config/app/port# 批量删除(前缀删除)
etcdctl del /config/app --prefix

如果是编程场景,我们可以用 Etcd 的客户端 SDK(如 Go、Python、Java 等)操作。以 Go 语言为例:

 

package mainimport ("context""fmt""go.etcd.io/etcd/client/v3"
)func main() {// 创建Etcd客户端cli, err := clientv3.New(clientv3.Config{Endpoints:   []string{"localhost:2379"},DialTimeout: 5 * time.Second,})if err != nil {panic(err)}defer cli.Close()// 写入键值_, err = cli.Put(context.TODO(), "/config/db/host", "127.0.0.1")if err != nil {panic(err)}// 读取键值resp, err := cli.Get(context.TODO(), "/config/db/host")if err != nil {panic(err)}for _, kv := range resp.Kvs {fmt.Printf("键:%s,值:%s\n", kv.Key, kv.Value)}// 监听键变化rch := cli.Watch(context.TODO(), "/config/db/host")for wresp := range rch {for _, ev := range wresp.Events {fmt.Printf("事件类型:%s,键:%s,值:%s\n", ev.Type, ev.Kv.Key, ev.Kv.Value)}}
}

示例 2:服务发现场景(临时节点 + Watch)

在微服务架构中,服务实例需要 “自动注册” 和 “自动发现”,Etcd 的租约和 Watch 机制可以完美实现:

 

package mainimport ("context""flag""go.etcd.io/etcd/client/v3""go.etcd.io/etcd/client/v3/concurrency""log""time"
)var (etcdEndpoints = flag.String("etcd-endpoints", "localhost:2379", "Etcd endpoints")svcName       = flag.String("service-name", "user-service", "服务名称")svcAddr       = flag.String("service-addr", "192.168.1.100:8080", "服务地址")
)func main() {flag.Parse()// 创建Etcd客户端cli, err := clientv3.New(clientv3.Config{Endpoints:   []string{*etcdEndpoints},DialTimeout: 5 * time.Second,})if err != nil {log.Fatal(err)}defer cli.Close()// 创建租约(TTL为10秒,客户端需每10秒内发心跳续约)lease, err := concurrency.NewLease(cli, 10)if err != nil {log.Fatal(err)}defer lease.Revoke(context.TODO())// 基于租约创建临时节点(服务注册)kv := clientv3.NewKV(cli)key := fmt.Sprintf("/services/%s/%s", *svcName, *svcAddr)_, err = kv.Put(context.TODO(), key, "online", clientv3.WithLease(lease.ID()))if err != nil {log.Fatal(err)}log.Printf("服务 %s 注册成功,地址:%s\n", *svcName, *svcAddr)// 模拟服务运行,定期续约go func() {for {time.Sleep(5 * time.Second) // 每5秒续约一次if _, err := lease.KeepAliveOnce(context.TODO()); err != nil {log.Printf("续约失败:%v\n", err)}}}()// 另一个goroutine:监听服务列表变化(服务发现)go func() {rch := cli.Watch(context.TODO(), fmt.Sprintf("/services/%s", *svcName), clientv3.WithPrefix())for wresp := range rch {for _, ev := range wresp.Events {svcAddr := string(ev.Kv.Key[len(fmt.Sprintf("/services/%s/", *svcName)):])if ev.Type == clientv3.EventTypePut {log.Printf("服务上线:%s\n", svcAddr)} else {log.Printf("服务下线:%s\n", svcAddr)}}}}()// 保持程序运行select {}
}

这个例子中,服务实例启动时会在 Etcd 中注册一个 “临时节点”(基于租约),并通过 Watch 机制实时感知同服务的其他实例上线 / 下线,完美实现了服务发现。

示例 3:分布式锁场景(保证操作原子性)

在分布式任务调度、资源竞争等场景中,分布式锁是必备工具,Etcd 的etcdctl和 SDK 都支持分布式锁:

 

package mainimport ("context""log""time""go.etcd.io/etcd/client/v3""go.etcd.io/etcd/client/v3/concurrency"
)func main() {cli, err := clientv3.New(clientv3.Config{Endpoints:   []string{"localhost:2379"},DialTimeout: 5 * time.Second,})if err != nil {log.Fatal(err)}defer cli.Close()// 创建分布式锁s, err := concurrency.NewSession(cli)if err != nil {log.Fatal(err)}defer s.Close()mu := concurrency.NewMutex(s, "/locks/task-distribute")// 加锁if err := mu.Lock(context.TODO()); err != nil {log.Fatal(err)}log.Println("获取到分布式锁,开始执行临界区逻辑...")// 模拟临界区操作time.Sleep(10 * time.Second)// 解锁if err := mu.Unlock(context.TODO()); err != nil {log.Fatal(err)}log.Println("释放分布式锁,临界区逻辑执行完毕")
}

通过分布式锁,我们可以保证 “同一时间只有一个节点执行临界区逻辑”,避免分布式场景下的数据竞争。

五、Etcd 工程化实践:那些你该知道的细节

1. 集群部署(保证高可用)

生产环境中,Etcd 通常以集群形式部署(至少 3 个节点)。以下是一个简单的集群启动示例:

 

# 节点1
./etcd --name node1 --data-dir node1 --listen-client-urls http://192.168.1.101:2379 --advertise-client-urls http://192.168.1.101:2379 --listen-peer-urls http://192.168.1.101:2380 --initial-advertise-peer-urls http://192.168.1.101:2380 --initial-cluster node1=http://192.168.1.101:2380,node2=http://192.168.1.102:2380,node3=http://192.168.1.103:2380 --initial-cluster-token etcd-cluster-1 --initial-cluster-state new# 节点2(类似节点1,修改name、data-dir、IP)
./etcd --name node2 --data-dir node2 --listen-client-urls http://192.168.1.102:2379 --advertise-client-urls http://192.168.1.102:2379 --listen-peer-urls http://192.168.1.102:2380 --initial-advertise-peer-urls http://192.168.1.102:2380 --initial-cluster node1=http://192.168.1.101:2380,node2=http://192.168.1.102:2380,node3=http://192.168.1.103:2380 --initial-cluster-token etcd-cluster-1 --initial-cluster-state new# 节点3(类似节点1,修改name、data-dir、IP)
./etcd --name node3 --data-dir node3 --listen-client-urls http://192.168.1.103:2379 --advertise-client-urls http://192.168.1.103:2379 --listen-peer-urls http://192.168.1.103:2380 --initial-advertise-peer-urls http://192.168.1.103:2380 --initial-cluster node1=http://192.168.1.101:2380,node2=http://192.168.1.102:2380,node3=http://192.168.1.103:2380 --initial-cluster-token etcd-cluster-1 --initial-cluster-state new

2. 性能与监控

  • 性能调优:Etcd 的性能受磁盘 IO、网络延迟影响较大,生产环境建议使用 SSD 磁盘,并合理配置--snapshot-count(快照触发的键数量)、--auto-compaction-retention(自动压缩时间)等参数。
  • 监控集成:Etcd 暴露了丰富的 metrics(通过--metrics-addr配置),可以接入 Prometheus+Grafana 进行监控,及时发现集群异常。

 

http://www.dtcms.com/a/537313.html

相关文章:

  • 文交所网站建设方案饰品企业网站建设
  • 郑州网站建设市场陕西省建设工程信息网官网
  • 中国电商网站排行榜绍兴百度推广优化排名
  • 网站 用php asp源码 比较好建设部执业考试网站
  • 宜家有做自己的网站吗眼镜厂官网
  • JAVA1027抽象类;抽象类继承
  • AD22更新网表时总是显示 net with name XXX In already exists
  • 推荐一个免费的IP地址库:纯真社区版IP库
  • 4.前缀和
  • 网站开发技术 北京国内网站建设排名
  • 南通网站建设兼职中国沈阳app在哪里下载
  • MinIo纯前端使用文件上传预览
  • 学习记录-package.json的scripts添加参数的方式有那些
  • 【前端】avue组件分页勾选
  • 个人网站主页设计模板台州建网站
  • 修改网站主目录的位置云闪付当前页面设计隐私
  • 计算机图形学:【Games101】学习笔记02——变换(二维与三维、模型、视图、投影)
  • 解码固相萃取仪:如何实现复杂样品前处理的高效与重现性
  • Easyx图形库应用(直接显存操作)
  • 网站翻书效果网站建设费用 会计分录
  • Langchain从零开始到应用落地案例[AI智能助手]【4】---优化ocr识别编写,实现按文件类型进行调用识别
  • 如何添加网站logo天津网站定制公司
  • 做网站需要规划哪些内容南宁网站seo大概多少钱
  • 第15天:网络基础与故障排除
  • confluence or 语雀 or sward,知识管理工具一文全方位对比
  • 易语言中函数参数“参考”的基本概念
  • 阿里巴巴国际站的前台网址是西安美食网页设计
  • 制作网站需要怎么做苏州注册公司流程和步骤
  • 云栖实录 | 驰骋在数据洪流上:Flink+Hologres驱动零跑科技实时计算的应用与实践
  • 基层建设是哪个网站的工作总结及工作计划