返回归档
🀄工程与设计

etcd

文章目录

热身

etcd简介

是什么

  • 分布式的kv存储系统
  • 用于存储和管理分布式系统中的共享配置和服务发现信息

使用场景

  1. k8s的存储后端 & 配置管理 & 存储原数据和状态
    • 存储API对象的原数据,如Pod、ConfigMap、Secret等
    • 记录k8s集群中所有的资源的实时状态变化,提供回滚能力
  2. 服务发现
    • 每个微服务启动时,将自己的地址注册到 ETCD。
    • 客户端应用通过查询 ETCD,找到当前有效的服务实例。
    • 支持动态扩展和负载均衡,服务实例发生变化时自动更新。
  3. 分布式锁 & election 选举
    • ETCD 提供强一致性的分布式锁机制,适合用于多实例应用中的协调问题,比如领导者选举(Leader Election)等
  4. 分布式系统协调
    • ETCD 可以用作多个组件之间的协调服务。它通过强一致性保证,能够让分布式系统中的组件保持同步
    • 分布式任务调度系统中,各个任务节点通过 ETCD 来协调谁负责执行哪些任务
    • 在大规模分布式系统中使用 ETCD 作为调度控制中心,确保任务不被重复执行

etcd用于服务发现和服务注册的优缺点

  • 优点
    • 强一致性
    • 简单的API
    • 支持分布式锁和election机制
  • 缺点
    • 强调CP中的C,一致性强,高并发下性能一般
    • 缺失健康检查机制,用户需要通过外部工具或逻辑实现健康检查,管理服务的生命周期
    • etcd强调一致性,在网络分区(partition Tolerance)和服务注册发现高频率变动时,可用性一般

安装

brew update
brew install etcd
etcd --version

quick-demo

#开启etcd
etcd 

#设置一个k
etcdctl put k "v"

#获取一个k
etcdctl get k
 
#用前缀搜索
etcdctl get k --prefix 

#删除
etcdctl del k1  

#watch key
etcdctl watch k 

#创建续约
~ etcdctl lease grant 300 
lease 694d9212b3941e20 granted with TTL(300s)
~ etcdctl put name yst --lease=694d9212b3941e20    
OK

# revoke 
~ etcdctl lease revoke 694d9212b3941e20        
lease 694d9212b3941e20 revoked

#lock
~ etcdctl lock mutex1                  
mutex1/694d9212b3941e25

#创建snapshot
➜  etcd etcdctl snapshot save backup.db
{"level":"info","ts":"2024-09-23T09:46:09.367125+0800","caller":"snapshot/v3_snapshot.go:65","msg":"created temporary db file","path":"backup.db.part"}
{"level":"info","ts":"2024-09-23T09:46:09.368469+0800","logger":"client","caller":"v3@v3.5.16/maintenance.go:212","msg":"opened snapshot stream; downloading"}
{"level":"info","ts":"2024-09-23T09:46:09.368498+0800","caller":"snapshot/v3_snapshot.go:73","msg":"fetching snapshot","endpoint":"127.0.0.1:2379"}
{"level":"info","ts":"2024-09-23T09:46:09.381468+0800","logger":"client","caller":"v3@v3.5.16/maintenance.go:220","msg":"completed snapshot read; closing"}
{"level":"info","ts":"2024-09-23T09:46:09.386211+0800","caller":"snapshot/v3_snapshot.go:88","msg":"fetched snapshot","endpoint":"127.0.0.1:2379","size":"98 kB","took":"now"}
{"level":"info","ts":"2024-09-23T09:46:09.386426+0800","caller":"snapshot/v3_snapshot.go:97","msg":"saved","path":"backup.db"}
Snapshot saved at backup.db
#利用snapshot恢复数据
#Snapshot 只捕获 etcd 数据库的状态,并不包含 etcd 集群的运行时配置
➜  etcd etcdctl snapshot restore backup.db 
Deprecated: Use `etcdutl snapshot restore` instead.

2024-09-23T09:46:22+08:00       info    snapshot/v3_snapshot.go:265     restoring snapshot      {"path": "backup.db", "wal-dir": "default.etcd/member/wal", "data-dir": "default.etcd", "snap-dir": "default.etcd/member/snap", "initial-memory-map-size": 0}
2024-09-23T09:46:22+08:00       info    membership/store.go:141 Trimming membership information from the backend...
2024-09-23T09:46:22+08:00       info    membership/cluster.go:421       added member    {"cluster-id": "cdf818194e3a8c32", "local-member-id": "0", "added-peer-id": "8e9e05c52164694d", "added-peer-peer-urls": ["http://localhost:2380"]}
2024-09-23T09:46:22+08:00       info    snapshot/v3_snapshot.go:293     restored snapshot       {"path": "backup.db", "wal-dir": "default.etcd/member/wal", "data-dir": "default.etcd", "snap-dir": "default.etcd/member/snap", "initial-memory-map-size": 0}
➜  etcd 

#健康检查
~ etcdctl endpoint health
127.0.0.1:2379 is healthy: successfully committed proposal: took = 1.254458ms

etcd数据从写入到落盘,这期间发生了什么

当 etcd 将数据写入到磁盘时,会经历以下主要步骤,涉及到数据存储的关键机制。这些机制旨在保证 etcd 的一致性、高可用性以及性能。


1. 数据写入请求的接收

当 etcd 接收到客户端的写入请求(如 PUT 操作)时:

  • 请求首先会被发送到 etcd 集群中的 Leader 节点。
  • 如果请求被发送到一个 Follower 节点,Follower 会将请求转发给 Leader。

2. Raft 共识算法处理

etcd 使用 Raft 共识算法保证数据一致性。

  1. Leader 提议(Proposal)
    • Leader 节点会将写入请求包装成一个 Raft 日志条目(Entry)。
    • 日志条目包含操作的类型、键、值以及递增的索引(Index)和任期(Term)。
  2. 日志复制(Log Replication)
    • Leader 会将日志条目广播到集群中的其他 Follower 节点。
    • Follower 会将日志条目存储到自己的内存和本地存储(如磁盘)。
  3. 日志条目提交(Commit)
    • Leader 等待大多数(过半)节点确认日志条目已写入。
    • 一旦过半节点成功持久化,Leader 会将日志条目标记为已提交(Committed)。

3. 持久化到磁盘

etcd 的数据最终会被写入磁盘,这涉及以下几个关键步骤:

  1. 内存写入
    • 日志条目首先写入到 Leader 和 Follower 的内存缓存中。
    • etcd 会将日志条目追加到内存中的 Raft 日志。
  2. WAL 写入
    • etcd 会将日志条目同步写入到 Write-Ahead Log (WAL) 中,WAL 是 etcd 的操作日志,存储在磁盘中。
    • fsync:etcd 使用 fsync 系统调用确保数据被可靠写入磁盘,避免因系统崩溃导致数据丢失。
  3. Snapshot 生成(快照)
    • 为了控制日志大小并优化磁盘空间使用,etcd 会定期生成快照(Snapshot),将整个数据状态(Key-Value 数据)写入到磁盘快照文件中。
    • 快照生成后,早期的 WAL 日志可以被清理。
  4. B+树存储
    • etcd 的实际数据存储基于 BoltDB(一个嵌入式的键值存储)。
    • 写入的键值数据会被组织成 B+ 树结构,并最终保存到磁盘的数据库文件中。

4. 数据返回客户端

  • 一旦 Leader 确认数据提交(即大多数节点持久化成功),它会将操作结果返回给客户端。
  • 如果 Follower 节点接收到请求,会从 Leader 同步状态。

etcd 写入过程的特点

  1. 高可靠性
    • 即使部分节点宕机,只要超过半数的节点存活,写入仍能保证成功。
  2. 强一致性
    • 通过 Raft 算法确保所有节点的状态一致性。
  3. 低延迟
    • etcd 使用内存缓存和日志追加来加速写入,但最终会通过 fsync 确保数据安全。
  4. 数据恢复
    • 如果节点宕机,etcd 可以通过 WAL 和快照恢复最新数据状态。

写入期间可能发生的问题

  1. 磁盘 I/O 问题
    • 如果磁盘写入速度慢,会导致写入延迟增加。
    • etcd 提供指标监控(如 wal_fsync_duration_seconds)来检测写入性能。
  2. 网络问题
    • 日志复制依赖网络通信,网络延迟或中断可能影响提交速度。
  3. 节点故障
    • 如果 Leader 宕机,集群会重新选举新 Leader,这期间写入请求会暂时挂起。
  4. 磁盘故障
    • 如果节点磁盘故障,数据可能无法写入。但 etcd 的多副本机制保证了数据不丢失。

总结

etcd 数据从写入到磁盘涉及了请求接收、Raft 共识算法、WAL 和快照存储等多个步骤。通过这种机制,etcd 提供了一种既强一致又高可用的分布式键值存储服务。

库函数调用

add: etcd api调用案例 · Forrest-Tao/codeCollection@86deb81 (github.com)

源码阅读

  1. 客户端调用grpc写方法
  2. etcd leader向member提议这个写命令后,并得到多数人的统一管理
  3. etcd leader将写命令写入log中
  4. etcd根据log,将相应的写操作固化到磁盘中
  5. etcd将结果返回给客户

ref