cloudinyachao 2016-12-11
一、概述
etcd是一个高可用的键值存储系统,主要用于共享配置和服务发现。etcd是由CoreOS开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致性算法处理日志复制以保证强一致性。Raft是一个新的一致性算法,适用于分布式系统的日志复制,Raft通过选举的方式来实现一致性,在Raft中,任何一个节点都可能成为Leader。Google的容器集群管理系统Kubernetes、开源PaaS平台Cloud Foundry和CoreOS的Fleet都广泛使用了etcd。在分布式系统中,如何管理节点间的状态一直是一个难题,etcd像是专门为集群环境的服务发现和注册而设计,它提供了数据TTL失效、数据改变监视、多值、目录监听、分布式锁原子操作等功能,可以方便的跟踪并管理集群节点的状态。
etcd的特性如下:
二、安装和使用
etcd的安装非常简单,可以直接下载编译后的可执行文件,下载地址:https://github.com/coreos/etcd/releases
三、应用场景
服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听udp或tcp端口,并且通过名字就可以查找和连接。要解决服务发现的问题,需要有下面三大支柱,缺一不可。
图1 服务发现示意图
下面我们来看服务发现对应的具体场景。
图2 微服务协同工作
图3 云平台多实例透明化
在分布式系统中,最适用的一种组件间通信方式就是消息发布与订阅。即构建一个配置共享中心,数据提供者在这个配置中心发布消息,而消息使用者则订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者。通过这种方式可以做到分布式系统配置的集中式管理与动态更新。
图4 消息发布与订阅
在场景一中也提到了负载均衡,本文所指的负载均衡均为软负载均衡。分布式系统中,为了保证服务的高可用以及数据的一致性,通常都会把数据和服务部署多份,以此达到对等服务,即使其中的某一个服务失效了,也不影响使用。由此带来的坏处是数据写入性能下降,而好处则是数据访问时的负载均衡。因为每个对等服务节点上都存有完整的数据,所以用户的访问流量就可以分流到不同的机器上。
图5 负载均衡
这里说到的分布式通知与协调,与消息发布和订阅有些相似。都用到了etcd中的Watcher机制,通过注册与异步通知机制,实现分布式环境下不同系统之间的通知与协调,从而对数据变更做到实时处理。实现方式通常是这样:不同系统都在etcd上对同一个目录进行注册,同时设置Watcher观测该目录的变化(如果对子目录的变化也有需要,可以设置递归模式),当某个系统更新了etcd的目录,那么设置了Watcher的系统就会收到通知,并作出相应处理。
图6 分布式协同工作
因为etcd使用Raft算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。
图7 分布式锁
分布式队列的常规用法与场景五中所描述的分布式锁的控制时序用法类似,即创建一个先进先出的队列,保证顺序。
另一种比较有意思的实现是在保证队列达到某个条件时再统一按顺序执行。这种方法的实现可以在/queue这个目录中另外建立一个/queue/condition节点。
图8 分布式队列
通过etcd来进行监控实现起来非常简单并且实时性强。
这样就可以第一时间检测到各节点的健康状态,以完成集群的监控要求。
另外,使用分布式锁,可以完成Leader竞选。这种场景通常是一些长时间CPU计算或者使用IO操作的机器,只需要竞选出的Leader计算或处理一次,就可以把结果复制给其他的Follower。从而避免重复劳动,节省计算资源。
这个的经典场景是搜索系统中建立全量索引。如果每个机器都进行一遍索引的建立,不但耗时而且建立索引的一致性不能保证。通过在etcd的CAS机制同时创建一个节点,创建成功的机器作为Leader,进行索引计算,然后把计算结果分发到其它节点。
图9 Leader竞选
etcd是一个分布式可靠的键值存储系统。它提供了与ZooKeeper相似的功能,但是使用Go语言编写而不是Java语言。Etcd使用Raft协调算法而不是ZooKeeper采用的Paxos算法。在云计算方面,Go是一个大有前景的语言,被誉为云时代的C语言。
对比与ZooKeeper,etcd更轻量级,etc更加关注一下几点:
l简单:curl命令可以调用的API接口(http+JSON)
l保密:可选的SSL客户端认证
l快速:标准检测每个实例每秒1000读写能力
l可靠:恰到地实现分布式协调,采用Raft一致性算法
etcd虽然是一个很年轻的项目,但是,已经在CoreOS、Kubernetes和CloudFoundry等知名厂商的生产环境中广泛使用。足见etcd具有一定得发展前景。如果你偏向使用成熟的Java客户端去调用etcd,有几个Java客户端库提供选择。
1. [boonproject/etcd](https://github.com/boonproject/boon/blob/master/etcd/README.md) 支持etcd v2,Async/Sync和waits
2. [justinsb/jetcd](https://github.com/justinsb/jetcd
或者[diwakergupta/jetcd](https://github.com/diwakergupta/jetcd)支持etcd v2
3. [jurmous/etcd4j](https://github.com/jurmous/etcd4j) 支持etcd v2, Async/Sync, waits 和 SSL。
如果你关注高性能,比较喜欢Go语言技术栈。有两个Go语言的客户端库提供选择:
A. [etcd/client](https://github.com/coreos/etcd/blob/master/client) 官方维护的Go语言客户端
B. [go-etcd](https://github.com/coreos/go-etcd) 官方客户端,可能更适合etcd早期版本(< 2.0.0)
https://my.oschina.net/abcijkxyz/blog/721759
http://www.mamicode.com/info-detail-1490139.html
###host字段指定授权使用该证书的etcd节点IP或子网列表,需要将etcd集群的3个节点都添加其中。cp etcd-v3.3.13-linux-amd64/etcd* /opt/k8s/bin/