etcd:从应用场景到实现原理的全方位解读html
ETCD:A highly-available key value store for shared configuration and service discovery.算法
- 简单:基于HTTP+JSON的API让你用curl就能够轻松使用。
- 安全:可选SSL客户认证机制。
- 快速:每一个实例每秒支持一千次写操做。
- 可信:使用Raft算法充分实现了分布式。
基于Raft强一致性算法的分布式存储仓库apache
分布式系统中的数据分为控制数据和应用数据。使用etcd的场景默认处理的数据都是控制数据,对于应用数据,只推荐数据量很小,可是更新访问频繁的状况。安全
场景一:服务发现(Service Discovery)
同一个分布式集群中的进程或服务,要如何才能找到对方并创建链接。服务器
本质上来讲,服务发现就是想要了解集群中是否有进程在监听udp或tcp端口,而且经过名字就能够查找和链接。 架构
- 一个强一致性、高可用的服务存储目录。基于Raft算法的etcd天生就是这样一个强一致性高可用的服务存储目录。
- 一种注册服务和监控服务健康状态的机制。用户能够在etcd中注册服务,而且对注册的服务设置
key TTL
,定时保持服务的心跳以达到监控健康状态的效果。
- 一种查找和链接服务的机制。经过在etcd指定的主题下注册的服务也能在对应的主题下查找到。为了确保链接,咱们能够在每一个服务机器上都部署一个Proxy模式的etcd,这样就能够确保能访问etcd集群的服务都能互相链接。

服务发现对应的具体场景app
- 微服务协同工做架构中,服务动态添加。随着Docker容器的流行,多种微服务共同协做,构成一个相对功能强大的架构的案例愈来愈多。透明化的动态添加这些服务的需求也日益强烈。经过服务发现机制,在etcd中注册某个服务名字的目录,在该目录下存储可用的服务节点的IP。在使用服务的过程当中,只要从服务目录下查找可用的服务节点去使用便可。

- PaaS平台中应用多实例与实例故障重启透明化。PaaS平台中的应用通常都有多个实例,经过域名,不只能够透明的对这多个实例进行访问,并且还能够作到负载均衡。可是应用的某个实例随时都有可能故障重启,这时就须要动态的配置域名解析(路由)中的信息。经过etcd的服务发现功能就能够轻松解决这个动态配置的问题。

场景二:消息发布与订阅
在分布式系统中,最适用的一种组件间通讯方式就是消息发布与订阅。负载均衡
即构建一个配置共享中心,数据提供者在这个配置中心发布消息,而消息使用者则订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者。运维
经过这种方式能够作到分布式系统配置的集中式管理与动态更新。curl
- 应用中用到的一些配置信息放到etcd上进行集中管理。这类场景的使用方式一般是这样:应用在启动的时候主动从etcd获取一次配置信息,同时,在etcd节点上注册一个Watcher并等待,之后每次配置有更新的时候,etcd都会实时通知订阅者,以此达到获取最新配置信息的目的。
- 分布式搜索服务中,索引的元信息和服务器集群机器的节点状态存放在etcd中,供各个客户端订阅使用。使用etcd的
key TTL
功能能够确保机器状态是实时更新的。
- 分布式日志收集系统。这个系统的核心工做是收集分布在不一样机器的日志。收集器一般是按照应用(或主题)来分配收集任务单元,所以能够在etcd上建立一个以应用(主题)命名的目录P,并将这个应用(主题相关)的全部机器ip,以子目录的形式存储到目录P上,而后设置一个etcd递归的Watcher,递归式的监控应用(主题)目录下全部信息的变更。这样就实现了机器IP(消息)变更的时候,可以实时通知到收集器调整任务分配。
- 系统中信息须要动态自动获取与人工干预修改信息请求内容的状况。一般是暴露出接口,例如JMX接口,来获取一些运行时的信息。引入etcd以后,就不用本身实现一套方案了,只要将这些信息存放到指定的etcd目录中便可,etcd的这些目录就能够经过HTTP的接口在外部访问。

场景三:负载均衡
本文所指的负载均衡均为软负载均衡。
分布式系统中,为了保证服务的高可用以及数据的一致性,一般都会把数据和服务部署多份,以此达到对等服务,即便其中的某一个服务失效了,也不影响使用。
由此带来的坏处是数据写入性能降低,而好处则是数据访问时的负载均衡。
由于每一个对等服务节点上都存有完整的数据,因此用户的访问流量就能够分流到不一样的机器上。
- etcd自己分布式架构存储的信息访问支持负载均衡。etcd集群化之后,每一个etcd的核心节点均可以处理用户的请求。因此,把数据量小可是访问频繁的消息数据直接存储到etcd中也是个不错的选择,如业务系统中经常使用的二级代码表(在表中存储代码,在etcd中存储代码所表明的具体含义,业务系统调用查表的过程,就须要查找表中代码的含义)。
- 利用etcd维护一个负载均衡节点表。etcd能够监控一个集群中多个节点的状态,当有一个请求发过来后,能够轮询式的把请求转发给存活着的多个状态。相似KafkaMQ,经过ZooKeeper来维护生产者和消费者的负载均衡。一样也能够用etcd来作ZooKeeper的工做。

场景四:分布式通知与协调
与消息发布和订阅有些类似。都用到了etcd中的Watcher机制,经过注册与异步通知机制,实现分布式环境下不一样系统之间的通知与协调,从而对数据变动作到实时处理。
实现方式一般是这样:不一样系统都在etcd上对同一个目录进行注册,同时设置Watcher观测该目录的变化(若是对子目录的变化也有须要,能够设置递归模式),当某个系统更新了etcd的目录,那么设置了Watcher的系统就会收到通知,并做出相应处理。
- 经过etcd进行低耦合的心跳检测。检测系统和被检测系统经过etcd上某个目录关联而非直接关联起来,这样能够大大减小系统的耦合性。
- 经过etcd完成系统调度。某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工做。管理人员在控制台做的一些操做,其实是修改了etcd上某些目录节点的状态,而etcd就把这些变化通知给注册了Watcher的推送系统客户端,推送系统再做出相应的推送任务。
- 经过etcd完成工做汇报。大部分相似的任务分发系统,子任务启动后,到etcd来注册一个临时工做目录,而且定时将本身的进度进行汇报(将进度写入到这个临时目录),这样任务管理者就可以实时知道任务进度。

场景五:分布式锁
由于etcd使用Raft算法保持了数据的强一致性,某次操做存储到集群中的值必然是全局一致的,因此很容易实现分布式锁。
锁服务有两种使用方式,一是保持独占,二是控制时序。
- 保持独占即全部获取锁的用户最终只有一个能够获得。etcd为此提供了一套实现分布式锁原子操做CAS(
CompareAndSwap
)的API。经过设置prevExist
值,能够保证在多个节点同时去建立某个目录时,只有一个成功。而建立成功的用户就能够认为是得到了锁。
- 控制时序,即全部想要得到锁的用户都会被安排执行,可是得到锁的顺序也是全局惟一的,同时决定了执行顺序。etcd为此也提供了一套API(自动建立有序键),对一个目录建值时指定为
POST
动做,这样etcd会自动在目录下生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可使用API按顺序列出全部当前目录下的键值。此时这些键的值就是客户端的时序,而这些键中存储的值能够是表明客户端的编号。

场景六:分布式队列
与分布式锁的控制时序用法相似,即建立一个先进先出的队列,保证顺序。
另外一种比较有意思的实现是在保证队列达到某个条件时再统一按顺序执行。这种方法的实现能够在/queue这个目录中另外创建一个/queue/condition节点。
- condition能够表示队列大小。好比一个大的任务须要不少小任务就绪的状况下才能执行,每次有一个小任务就绪,就给这个condition数字加1,直到达到大任务规定的数字,再开始执行队列里的一系列小任务,最终执行大任务。
- condition能够表示某个任务在不在队列。这个任务能够是全部排序任务的首个执行程序,也能够是拓扑结构中没有依赖的点。一般,必须执行这些任务后才能执行队列中的其余任务。
- condition还能够表示其它的一类开始执行任务的通知。能够由控制程序指定,当condition出现变化时,开始执行队列任务。

场景七:集群监控与Leader竞选
经过etcd来进行监控实现起来很是简单而且实时性强。
- Watcher机制,当某个节点消失或有变更时,Watcher会第一时间发现并告知用户。
- 节点能够设置
TTL key
,好比每隔30s发送一次心跳使表明该机器存活的节点继续存在,不然节点消失。
这样就能够第一时间检测到各节点的健康状态,以完成集群的监控要求。
使用分布式锁,能够完成Leader竞选。
这种场景一般是一些长时间CPU计算或者使用IO操做的机器,只须要竞选出的Leader计算或处理一次,就能够把结果复制给其余的Follower。从而避免重复劳动,节省计算资源。
这个的经典场景是搜索系统中创建全量索引。若是每一个机器都进行一遍索引的创建,不但耗时并且创建索引的一致性不能保证。经过在etcd的CAS机制同时建立一个节点,建立成功的机器做为Leader,进行索引计算,而后把计算结果分发到其它节点。

场景八:为何用etcd而不用ZooKeeper?
阅读了“ZooKeeper典型应用场景一览”一文的读者可能会发现,etcd实现的这些功能,ZooKeeper都能实现。那么为何要用etcd而非直接使用ZooKeeper呢?
相较之下,ZooKeeper有以下缺点:
- 复杂。ZooKeeper的部署维护复杂,管理员须要掌握一系列的知识和技能;而Paxos强一致性算法也是素来以复杂难懂而闻名于世;另外,ZooKeeper的使用也比较复杂,须要安装客户端,官方只提供了Java和C两种语言的接口。
- Java编写。这里不是对Java有偏见,而是Java自己就偏向于重型应用,它会引入大量的依赖。而运维人员则广泛但愿保持强一致、高可用的机器集群尽量简单,维护起来也不易出错。
- 发展缓慢。Apache基金会项目特有的“Apache Way”在开源界饱受争议,其中一大缘由就是因为基金会庞大的结构以及松散的管理致使项目发展缓慢。
etcd做为一个后起之秀,其优势也很明显。
- 简单。使用Go语言编写部署简单;使用HTTP做为接口使用简单;使用Raft算法保证强一致性让用户易于理解。
- 数据持久化。etcd默认数据一更新就进行持久化。
- 安全。etcd支持SSL客户端安全认证。
etcd做为一个年轻的项目,真正告诉迭代和开发中,这既是一个优势,也是一个缺点。
优势是它的将来具备无限的可能性,缺点是没法获得大项目长时间使用的检验。
目前CoreOS、Kubernetes和CloudFoundry等知名项目均在生产环境中使用了etcd,因此总的来讲,etcd值得你去尝试。