etcd介绍
etcd是一个Go语言编写的分布式、高可用的一致性键值存储系统,用于提供可靠的分布式键值(key-value)存储、配置共享和服务发现等功能。
etcd可以用于存储关键数据和实现分布式调度。
etcd以一致和容错的方式存储数据。分布式系统可以使用etcd实现一致性键值存储、配置管理、服务发现和分布式系统的协同功能。常见的etcd使用场景包括:服务发现、分布式锁、分布式数据队列、分布式通知协调、主备选举等。
etcd基于raft协议,通过赋值日志文件保证数据的强一致性。
etcd具有一定的容错能力,假设集群中共有n个节点,即使集群中(n-1)/2个节点发生了故障,只要剩下的(n+1)/2个节点达成一致,也能操作成功。
etcd默认数据一更新就持久化,数据持久化存储使用WAL(write ahead log 预写式日志)格式,WAL记录了数据的变化全过程。在etcd中所有数据在提交之前都要先写入WAL中;etcd的Snapshot文件则存储了某一时刻etcd的所有数据,默认设置为每10000条记录做一次快照,经过快照后WAL文件即可删除。
etcd特性:
- 支持RestFul风格的Http+Json的API
- etcd v3增加了对gRPC的支持,同时也提供rest gateway进行转化。
- go语言编写,跨平台
- raft算法保证强一致性
- 支持TLS客户端安全认证
- Lease 优化 TTL 机制
- MVCC
- ...
etcd架构
etcd简要基础架构图:
Client 层:
- Client 层包括 client v2 和 v3 两个大版本 API 客户端库,提供了简洁易用的 API,同时支持负载均衡、节点间故障自动转移,可极大降低业务使用 etcd 复杂度, 提升开发效率、服务可用性。
API 网络层:
- API 网络层主要包括 client 访问 server 和 server 节点之间的通信协议。一方面,client 访问 etcd server 的 API 分为 v2 和 v3 两个大版本。v2 API 使用 HTTP/1.x 协议,v3 API 使用 gRPC 协议。同时 v3 通过 etcd grpc-gateway 组件也支持 HTTP/1.x 协议,便于各种语言的服务调用。另一方面,server 之间通信协议,是指节点间通过 Raft 算法实现数据复制和 Leader 选举等功能时使用的 HTTP 协议。
Raft 算法层:
- Raft 算法层实现了 Leader 选举、日志复制、ReadIndex 等核心算法特性,用于保障 etcd 多个节点间的数据一致性、提升服务可用性等,是 etcd 的基石和亮点。
功能逻辑层:
- etcd 核心特性实现层,如典型的 KVServer 模块、MVCC 模块、Auth 鉴权模块、Lease 租约模块、Compactor 压缩模块等,其中 MVCC 模块主要由 treeIndex 模块和 boltdb 模块组成。
存储层:
- 存储层包含预写日志 (WAL) 模块、快照 (Snapshot) 模块、boltdb 模块。其中 WAL 可保障 etcd crash 后数据不丢失,boltdb 则保存了集群元数据和用户写入的数据。
etcd典型应用场景
服务注册和发现
服务发现机制可用于在etcd中注册某个服务名字的目录。并在该目录下存储可用的服务节点的IP。
在使用服务的过程中,只要从服务目录下查找可用的服务节点进行使用即可,这样就通过etcd做到了各个微服务之间的自动添加与协同。
消息订阅和发布
这类场景的使用的方式通常是应用在启动的时候主动从etcd获取一次配置信息,同时,在etcd节点上注册一个Watcher并等待,以后每当配置有更新的时候,etcd都会实时通知订阅者,以此达到获取最新配置信息的目的。
负载均衡
etcd集群化之后,每个etcd的核心节点都可以处理用的请求。所以把数量小但是访问频繁的消息数据直接存储到etcd是一个不错的选择.
分布式锁
因为etcd使用raft算法保证了数据强一致性,某次操作存储到集群中的值必然是全局一致的,所以etcd很容易实现分布式锁。
锁服务包含两种使用方式:一种是保持独占、一种是控制时序。
保持独占:
- 保持独占即所有试图获取锁的用户最终只有一个可以得到
- etcd为此提供了一套实现分布式锁的原子操作CAS的api,通过设置prevExist值,可以保证在多个节点上同时创建某个目录时,只有一个节点能够成功,而成功的那个即可获得分布式锁。
控制时序:
- 试图获取锁的所有用户都会进入等待队列,获得所得顺序是全局唯一的,同时还能决定队列的执行顺序
- etcd为此也提供了一套API(自动创建有序键),它会将一个目录的键值指定为POST动作,这样etcd就会在目录下生成一个当前最大的值作为键,并存储这个新的值(客户端编号)。
- 同时还可以使用API按顺序列出所有目录下的键值,此时这些键的值就是客户端的时序,而这些键中存储的值则可以是代表客户端的编号。
集群监控
通过etcd来进行监控的功能实现起来非常简单并且实时性较强,主要会用到如下两点特性:
- watcher机制,当某个节点消失或发生变动时,watcher会第一时间发现并告知用户
- 节点可以设置TTL Key,比如每隔30s向etcd发送一次心跳信号,一次代表该节点依然存活着,否则就表示该节点已经消失了
这样就可以第一时间检测到各个节点的健康状态,以完成集群的监控要求。
etcd相关概念
- Raft:etcd所采用的保证分布式系统强一致性的算法。
- Node:一个Raft状态机实例
- Member:一个etcd实例,它管理着一个node,并且可以为客户端请求提供服务。
- Cluster:由多个Member构成的,遵循Raft一致性协议的etcd集群。
- Peer:对同一个etcd集群中另外一个Member的叫法。
- Client:凡是连接etcd服务器请求服务的。
- Proposal:一个需要经过Raft一致性协议的请求
- Quorum:Raft协议需要的、能够修改集群状态的、活跃的etcd集群成员成为Quorum(法定人数)。
- WAL:预写式日志,etcd用于持久化存储的日志格式
- Snapshot:etcd集群状态在某一时间点的快照(备份),etcd为防止WAL文件过多而设置的快照,用于存储etcd的数据状态。
- Proxy:etcd的一种模式,为etcd集群提供反向代理服务。
- Leader:Raft算法中通过竞选而产生的处理所有数据提交的节点。
- Follower:竞选失败的节点作为raft中的从属节点,为算法提供强一致性保证。
- Candidate:当Follower超过一定时间还接收不到Leader的心跳时转变为Candidate参与竞选。
- Term:某个节点从成为Leader到下一次竞选的时间,称为一个Term。
- Index:WAL日志数据项编号。
- Key:用户定义的用于存储和获取用户定义数据的标识符。
- Key Space:键空间,etcd集群内所有键的集合。
- Revision:etcd集群范围内64位的计数器,键空间的每次修改都会导致该计数器的增加。
- Modifation Revision:一个Key最后一次修改的revision。
- Lease:一个短时的,可续约的契约,当它过期时,就会删除与其关联的所有键。
- Watcher:观察者,客户端通过打开一个观察者来获取一个给定键范围的更新。、
- Key Range:键范围,一个键的集合,这个集合既可以是只有一个key或者是在一个字典区间
- Endpoint:指向etcd服务或资源的URL
- Compaction:etcd的压缩操作,丢弃所有etcd的历史数据并且取代一个给定revision之前的所有的key。压缩操作通常用于重新声明etcd后端数据库的存储空间,其与Raft的日志压缩是一个原理。
- Key Version:键版本,即一个键从创建开始的写(修改)次数,从1开始。一个不存在或已删除的键版本是0。其与revision的概念不同。