Etcd简介

2018/05/01 etcd

Etcd简介

ETCD是一个分布式、开源的、可靠的key-value存储的分布式系统,用于存储分布式系统中的关键数据;提供共享配置、服务的注册和发现;基于Go语言实现 。

etcd介绍

ectd是CoreOS公司发起的一个开源项目,是用于共享配置和服务发现的分布式,一致性的KV存储系统,它的目标是提供了一种可靠的方法来存储分布式系统或机器集群需要访问的数据。 类似项目有zookeeper和consul。

具有以下特点:

  • 简单:安装配置简单,且提供HTTP API进行交互,使用也简单;
  • 存储:将数据存储在分层组织的目录中,如同在标准文件系统中;
  • Watch机制:Watch 指定的键、前缀目录的更改,监测特定的键或目录的更改时机,并能对值的更改做出相应的反应;
  • 安全:支持 SSL 证书验证;
  • 快速:按照官网给出的数据, 在2CPU,1.8G内存,SSD磁盘这样的配置下,单节点的写性能可以达到16K QPS, 而先写后读也能达到12K QPS;
  • 一致可靠:基于 Raft 共识算法,实现分布式系统内部数据存储、服务调用的一致性和高可用性;
  • Revision 机制:每个 Key 带有一个 Revision 号,每进行一次事务便加一,因此它是全局唯一的,如初始值为 0,进行一次 Put 操作,Key 的 Revision 变为 1,同样的操作,再进行一次,Revision 变为 2;换成 Key1 进行 Put 操作,Revision 将变为 3。这种机制有一个作用,即通过 Revision 的大小就可知道写操作的顺序,这对于实现公平锁,队列十分有益;
  • Lease 机制:即租约机制(TTL,Time To Live),Etcd 可以为存储的 Key-Value 对设置租约,当租约到期,Key-Value 将失效删除;同时也支持续约,通过客户端可以在租约到期之前续约,以避免 Key-Value 对过期失效;此外,还支持解约,一旦解约,与该租约绑定的 Key-Value 将失效删除;

应用场景

etcd 在稳定性、可靠性和可伸缩性上表现极佳,同时也为云原生应用系统提供了协调机制。etcd 经常用于服务注册与发现的场景,此外还有键值对存储、消息发布与订阅、分布式锁等场景。

服务发现

服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听 udp 或 tcp 端口,并且通过名字就可以查找和连接。要解决服务发现的问题,需要有下面三大支柱,缺一不可。

(1) 一个强一致性、高可用的服务存储目录。基于 Raft 算法的etcd天生就是这样一个强一致性高可用的服务存储目录;

(2) 一种注册服务和监控服务健康状态的机制。用户可以在etcd中注册服务,并且对注册的服务设置key TTL,定时保持服务的心跳以达到监控健康状态的效果。

(3) 一种查找和连接服务的机制。通过在etcd指定的主题下注册的服务也能在对应的主题下查找到。为了确保连接,我们可以在每个服务机器上都部署一个 Proxy 模式的 etcd,这样就可以确保能访问etcd集群的服务都能互相连接。

消息发布与订阅

在分布式系统中,最适用的一种组件间通信方式就是消息发布与订阅。即构建一个配置共享中心,数据提供者在这个配置中心发布消息,而消息使用者则订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者。通过这种方式可以做到分布式系统配置的集中式管理与动态更新。

(1) 应用中用到的一些配置信息放到etcd上进行集中管理。应用在启动的时候主动从etcd获取一次配置信息,同时,在etcd节点上注册一个 Watcher 并等待,以后每次配置有更新的时候,etcd 都会实时通知订阅者,以此达到获取最新配置信息的目的;

(2) 分布式搜索服务中,索引的元信息和服务器集群机器的节点状态存放在etcd中,供各个客户端订阅使用。etcd租约机制可以确保机器状态是实时更新的;

(3) 分布式日志收集系统。这个系统的核心工作是收集分布在不同机器的日志。收集器通常是按照应用(或主题)来分配收集任务单元,因此可以在etcd上创建一个以应用(主题)命名的目录 P,并将这个应用(主题相关)的所有机器 ip,以子目录的形式存储到目录 P 上,然后设置一个etcd递归的 Watcher,递归式的监控应用(主题)目录下所有信息的变动,即这样就实现了机器 IP(消息)变动的时候,能够实时通知到收集器调整任务分配;

(4) 系统中信息需要动态自动获取与人工干预修改信息请求内容的情况。通常是暴露出接口,例如 JMX 接口,来获取一些运行时的信息。引入etcd之后,就不用自己实现一套方案了,只要将这些信息存放到指定的etcd目录中即可,etcd 的这些目录就可以通过 HTTP 的接口在外部访问。

服务均衡

分布式系统中,为了保证服务的高可用以及数据的一致性,通常都会把数据和服务部署多份,以此达到对等服务,即使其中的某一个服务失效了,也不影响使用。由此带来的坏处是数据写入性能下降,而好处则是数据访问时的负载均衡。因为每个对等服务节点上都存有完整的数据,所以用户的访问流量就可以分流到不同的机器上。

(1) etcd本身分布式架构存储的信息访问支持负载均衡。etcd 集群化以后,每个etcd的核心节点都可以处理用户的请求。

(2) 利用etcd维护一个负载均衡节点表。etcd 可以监控一个集群中多个节点的状态,当有一个请求发过来后,可以轮询式的把请求转发给存活着的多个状态。

分布式通知与协调

分布式通知与协调与前面提到的消息发布和订阅有些相似,都用到了etcd中的 Watcher 机制,通过注册与异步通知机制,实现分布式环境下不同系统之间的通知与协调,从而对数据变更做到实时处理。

实现方式通常是这样:不同系统都在etcd上对同一个目录进行注册,同时设置 Watcher 观测该目录的变化,当某个系统更新了etcd的目录,那么设置了 Watcher 的系统就会收到通知,并作出相应处理。

(1) 通过etcd进行低耦合的心跳检测。检测系统和被检测系统通过etcd上某个目录关联而非直接关联起来,这样可以大大减少系统的耦合性。

(2) 通过etcd完成系统调度。某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作,实际上是修改了etcd上某些目录节点的状态,而etcd就把这些变化通知给注册了 Watcher 的推送系统客户端,推送系统再作出相应的推送任务。

(3) 通过etcd完成工作汇报。大部分类似的任务分发系统,子任务启动后,到etcd来注册一个临时工作目录,并且定时将自己的进度进行汇报,这样任务管理者就能够实时知道任务进度。

分布式锁

因为 etcd 使用 Raft 算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。

(1) 保持独占即所有获取锁的用户最终只有一个可以得到。etcd 为此提供了一套实现分布式锁原子操作 CAS(CompareAndSwap)的 API。通过设置prevExist值,可以保证在多个节点同时去创建某个目录时,只有一个成功。而创建成功的用户就可以认为是获得了锁。

(2) 控制时序,即所有想要获得锁的用户都会被安排执行,但是获得锁的顺序也是全局唯一的,同时决定了执行顺序。etcd 为此也提供了一套 API(自动创建有序键),对一个目录建值时指定为POST动作,这样 etcd 会自动在目录下生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可以使用 API 按顺序列出所有当前目录下的键值。此时这些键的值就是客户端的时序,而这些键中存储的值可以是代表客户端的编号。

分布式队列

分布式队列的常规用法与分布式锁的控制时序用法类似,即创建一个先进先出的队列,保证顺序。另一种比较有意思的实现是在保证队列达到某个条件时再统一按顺序执行。这种方法的实现可以在 /queue 这个目录中另外建立一个 /queue/condition 节点。

(1) condition 可以表示队列大小。比如一个大的任务需要很多小任务就绪的情况下才能执行,每次有一个小任务就绪,就给这个 condition 数字加 1,直到达到大任务规定的数字,再开始执行队列里的一系列小任务,最终执行大任务。

(2) condition 可以表示某个任务在不在队列。这个任务可以是所有排序任务的首个执行程序,也可以是拓扑结构中没有依赖的点。通常,必须执行这些任务后才能执行队列中的其他任务。

(3) condition 还可以表示其它的一类开始执行任务的通知。可以由控制程序指定,当 condition 出现变化时,开始执行队列任务。

集群监控与Leader竞选

通过 etcd 来进行监控实现起来非常简单并且实时性强。例如,前面几个场景已经提到 Watcher 机制,当某个节点消失或有变动时,Watcher 会第一时间发现并告知用户。此外,节点可以设置TTL key,比如每隔 30s 发送一次心跳使代表该机器存活的节点继续存在,否则节点消失。这样就可以第一时间检测到各节点的健康状态,以完成集群的监控要求。

另外,使用分布式锁,可以完成 Leader 竞选。这种场景通常是一些长时间 CPU 计算或者使用 IO 操作的机器,只需要竞选出的 Leader 计算或处理一次,就可以把结果复制给其他的 Follower。从而避免重复劳动,节省计算资源。

这个的经典场景是搜索系统中建立全量索引。如果每个机器都进行一遍索引的建立,不但耗时而且建立索引的一致性不能保证。通过在 etcd 的 CAS 机制同时创建一个节点,创建成功的机器作为 Leader,进行索引计算,然后把计算结果分发到其它节点。

常用术语 为了有效提高读者阅读的效率,本小节将总结后续常出现的专用术语,先混个眼熟,后续具体实现过程会继续深入。

术语 描述 备注 Raft Raft算法,etcd实现一致性的核心 ectd-raft 模型 Follower Raft中的从属节点 竞争Leader失败 Leader Raft中的领导节点,处理数据提交 Leader协调集群 Candidate 候选节点 当Follower接收Leader节点的消息超时会转变为Candidate Node Raft状态机的实例 Raft中涉及多个节点 Member etcd实例,管理对应Node节点 可处理客户端请求 Peer 同一个集群中的另一个Member 其他成员 Cluster etcd集群 拥有多个ectd Member Lease 租期 关键设置的租期,过期删除 Watch 监测机制 监控键值对的变化 Term 任期 某个节点成为Leader, 到下一次竞选的时间 WAL 预写式日志 持久化存储的日志格式 MVCC 多版本并发控制 事务隔离的手段 revision MVCC中的版本 每一次key-value操作都会有revision keyIndex Key的生命周期 记录一个key的生命周期中所涉及过的版本 Client 客户端 向etcd发起请求的客户端

参考 【一文入门ETCD】https://juejin.cn/post/6844904031186321416 【etcd:从应用场景到实现原理的全方位解读】https://www.infoq.cn/article/etcd-interpretation-application-scenario-implement-principle 【Etcd 架构与实现解析】http://jolestar.com/etcd-architecture/ 【linux单节点和集群的etcd】https://www.jianshu.com/p/07ca88b6ff67 【软负载均衡与硬负载均衡、4层与7层负载均衡】https://cloud.tencent.com/developer/article/1446391 【Etcd Lock详解】https://tangxusc.github.io/blog/2019/05/etcd-lock详解/ 【etcd基础与使用】https://zhuyasen.com/post/etcd.html 【ETCD核心机制解析】https://www.cnblogs.com/FG123/p/13632095.html 【etcd watch机制】http://liangjf.top/2019/12/31/110.etcd-watch机制分析/ 【ETCD 源码学习–Watch(server)】https://www.codeleading.com/article/15455457381/ 【etcdV3—watcher服务端源码解析】https://blog.csdn.net/stayfoolish_yj/article/details/104497233

Search

    微信好友

    博士的沙漏

    Table of Contents