etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不只能够做为服务注册于发现,还能够做为 key-value 存储的中间件。算法
《完全搞懂 etcd 系列文章》将会从 etcd 的基本功能实践、API 接口、实现原理、源码分析,以及实现中的踩坑经验等几方面具体展开介绍 etcd。预计会有 20 篇左右的文章,笔者将会每周持续更新,欢迎关注。数据库
etcd 是 CoreOS 团队于 2013 年 6 月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。具备如下特色:安全
etcd 采用 Go 语言编写,它具备出色的跨平台支持,很小的二进制文件和强大的社区。 etcd 机器之间的通讯经过 Raft 算法处理。服务器
etcd 是一个高度一致的分布式键值存储,它提供了一种可靠的方式来存储须要由分布式系统或机器集群访问的数据。它能够优雅地处理网络分区期间的 leader 选举,以应对机器的故障,即便是在 leader 节点发生故障时。微信
从简单的 Web 应用程序到 Kubernetes 集群,任何复杂的应用程序均可以从 etcd 中读取数据或将数据写入 etcd。markdown
etcd 于 2018 年 12 月正式加入云原生计算基金会(CNCF,全称 Cloud Native Computing Foundation),并由 CNCF 支持。CNCF 是一个厂商中立的基金会、云原生技术推广和普及的领导者。网络
etcd 比较多的应用场景是用于服务注册与发现,除此以外,也能够用于键值对存储,应用程序能够读取和写入 etcd 中的数据。架构
一个简单的用例是将数据库链接详细信息或功能标志存储在 etcd 中做为键值对。 能够观察这些值,使咱们的应用在更改时能够从新配置本身。高级用法是利用 etcd 的一致性保证来实施数据库 leader 选举或在一组 follower 之间执行分布式锁定。异步
A highly-available key value store for shared configuration and service discovery.
一个用于配置共享和服务发现的键值存储系统。分布式
归根结底,etcd 是一个键值存储的组件,其余的应用都是基于其键值存储的功能展开。etcd 的存储有以下特色:
etcd leader 的延迟是要跟踪的最重要的指标,而且内置仪表板具备专用于此的视图。在咱们的测试中,严重的延迟会在群集内形成不稳定,由于 Raft 的速度仅与大多数机器中最慢的机器同样快。咱们能够经过适当地调整群集来缓解此问题。etcd 已在具备高度可变网络的云提供商上进行了预调。
服务注册与发现(Service Discovery)要解决的是分布式系统中最多见的问题之一,即在同一个分布式集群中的进程或服务如何才能找到对方并创建链接。从本质上说,服务发现就是要了解集群中是否有进程在监听 UDP 或者 TCP 端口,而且经过名字就能够进行查找和连接。
要解决服务发现的问题,须要下面三大支柱,缺一不可。
强一致性、高可用的服务存储目录。 基于 Raft 算法的 etcd 天生就是这样一个强一致性、高可用的服务存储目录。
一种注册服务和服务健康情况的机制。 用户能够在 etcd 中注册服务,而且对注册的服务配置 key TTL,定时保持服务的心跳以达到监控健康状态的效果。
一种查找和链接服务的机制。经过在 etcd 指定的主题下注册的服务业能在对应的主题下查找到。为了确保链接,咱们能够在每一个服务机器上都部署一个 Proxy 模式的 etcd,这样就能够确保访问 etcd 集群的服务都可以互相链接。
etcd2 中引入的 etcd/raft 库,是目前最稳定、功能丰富的开源一致性协议之一。做为 etcd、TiKV、CockcorachDB、Dgraph 等知名分布式数据库的核心数据复制引擎,etcd/raft 驱动了超过十万个集群,是被最为普遍采用一致性协议实现之一。etcd3 中引入的多版本控制、事务等功能,大大的简化了分布式应用的开发流程,提升了效率和稳定性。通过 5 年的演进,etcd 也已经成为了各类容器编排系统的默认存储选项。Kubernetes 是流行的容器平台,运行在任何环境的 Kubernetes 集群都依赖 etcd 来提供稳定而可靠的存储服务。
在分布式系统中,最适用的一种组件间通讯方式就是消息发布与订阅。即构建一个配置共享中心,数据提供者在这个配置中心发布消息,而消息使用者则订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者。经过这种方式能够作到分布式系统配置的集中式管理与动态更新。
分布式搜索服务中,索引的元信息和服务器集群机器的节点状态存放在etcd中,供各个客户端订阅使用。使用etcd的key TTL功能能够确保机器状态是实时更新的。
分布式日志收集系统。这个系统的核心工做是收集分布在不一样机器的日志。收集器一般是按照应用(或主题)来分配收集任务单元,所以能够在etcd上建立一个以应用(主题)命名的目录P,并将这个应用(主题相关)的全部机器ip,以子目录的形式存储到目录P上,而后设置一个 etcd 递归的Watcher,递归式的监控应用(主题)目录下全部信息的变更。这样就实现了机器IP(消息)变更的时候,可以实时通知到收集器调整任务分配。
系统中信息须要动态自动获取与人工干预修改信息请求内容的状况。一般是暴露出接口,例如JMX接口,来获取一些运行时的信息。引入etcd以后,就不用本身实现一套方案了,只要将这些信息存放到指定的etcd目录中便可,etcd的这些目录就能够经过HTTP的接口在外部访问。
这里说到的分布式通知与协调,与消息发布和订阅有些类似。在分布式系统中,最适用的一种组件间通讯方式就是消息发布与订阅。即构建一个配置共享中心,数据提供者在这个配置中心发布消息,而消息使用者则订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者。经过这种方式能够作到分布式系统配置的集中式管理与动态更新。
这里用到了etcd中的Watcher机制,经过注册与异步通知机制,实现分布式环境下不一样系统之间的通知与协调,从而对数据变动作到实时处理。实现方式一般是这样:不一样系统都在etcd上对同一个目录进行注册,同时设置Watcher观测该目录的变化(若是对子目录的变化也有须要,能够设置递归模式),当某个系统更新了etcd的目录,那么设置了Watcher的系统就会收到通知,并做出相应处理。
经过etcd进行低耦合的心跳检测。检测系统和被检测系统经过etcd上某个目录关联而非直接关联起来,这样能够大大减小系统的耦合性。
经过etcd完成系统调度。某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工做。管理人员在控制台做的一些操做,其实是修改了etcd上某些目录节点的状态,而etcd就把这些变化通知给注册了Watcher的推送系统客户端,推送系统再做出相应的推送任务。
经过etcd完成工做汇报。大部分相似的任务分发系统,子任务启动后,到etcd来注册一个临时工做目录,而且定时将本身的进度进行汇报(将进度写入到这个临时目录),这样任务管理者就可以实时知道任务进度。
当在分布式系统中,数据只有一份(或有限制),此时须要利用锁的技术控制某一时刻修改数据的进程数。与单机模式下的锁不只须要保证进程可见,分布式环境下还须要考虑进程与锁之间的网络问题。
分布式锁能够将标记存在内存,只是该内存不是某个进程分配的内存而是公共内存如 Redis、Memcache。至于利用数据库、文件等作锁与单机的实现是同样的,只要保证标记能互斥就行。
由于etcd使用Raft算法保持了数据的强一致性,某次操做存储到集群中的值必然是全局一致的,因此很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。
保持独占即全部获取锁的用户最终只有一个能够获得。etcd为此提供了一套实现分布式锁原子操做CAS(CompareAndSwap)的API。经过设置prevExist值,能够保证在多个节点同时去建立某个目录时,只有一个成功。而建立成功的用户就能够认为是得到了锁。
控制时序,即全部想要得到锁的用户都会被安排执行,可是得到锁的顺序也是全局惟一的,同时决定了执行顺序。etcd为此也提供了一套API(自动建立有序键),对一个目录建值时指定为POST动做,这样etcd会自动在目录下生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可使用API按顺序列出全部当前目录下的键值。此时这些键的值就是客户端的时序,而这些键中存储的值能够是表明客户端的编号。
本章主要介绍了 etcd 的相关概念,以及 etcd 主要的使用场景。etcd 在分布式环境中是一个利器,在一致性存储方面有普遍的应用。下一篇将会具体介绍 etcd 的安装以及使用的实践。
欢迎购买笔者的图书,现已出版上市:
原创不易,但愿你们多多支持,期待与各位的交流学习。