ETCD

 

一、简介

CoreOS团队于2013年6月发起的开源项目。

etcd是一个高可用的 Key/Value 存储系统,主要用于共享配置和服务发现。基于Go语言实现。

类似的常见的有Consul、ZooKeeper等等。

 

二、为什么需要etcd?

 

三、特点&优势

总结下来就是:分布式、高可用、强一致性

在分布式系统中,各个服务的配置信息的管理共享和服务发现是一个很基本、也是很重要的问题。

1、配置共享

etcd可以集中管理配置信息,服务端将配置信息存储于etcd,客户端通过etcd得到服务配置信息,etcd监听配置信息的改变,发现变更通知客户端。

为了防止单点故障,还可以启动多个etcd组成集群。etcd集群使用Raft一致性算法处理日志复制,保证多节点之间数据的强一致性。

2、服务健康检查

在etcd中注册服务,并且对注册的服务配置key的TTL,定时保持服务的心跳以达到监控健康状态的效果。

3、查找和连接服务

通过在etcd指定主题下注册的服务,也能在对应的主题下查找到。

为了确保连接,我们可以在每个服务机器节点上都部署一个proxy模式的etcd,这样就可以确保访问etcd集群的服务都能够互相连接。

 

四、应用场景

参考:https://www.jianshu.com/p/372e76a27cc3

 

五、etcd结构

etcd结构

etcd主要分为四部分:

 

六、Raft协议

为了保证高可用,可以使用多个节点组成集群。通常是3个及以上的单数节点。比如集群有3个节点,那么可以容忍其中一个出现故障(半数以上节点是健康的),系统依旧可以正常运行。

Raft

上图是正常工作状态的三节点Raft集群:

1、一个Raft集群有一个Leader节点,其余都是Follower节点

2、客户端只允许和Leader节点进行交互

3、Follower节点只允许从Leader节点接收日志数据

4、Leader节点将客户端发来的请求同步给所有Follower节点,至少有一半节点同步成功时,才可以将日志commit,并返回给客户端成功

5、Leader节点定期向Follower节点发送心跳信息,告诉Follower自己依然健康

 

Raft关键在于抽屉理论二阶段提交选举约束,一共3个部分

抽屉理论

又称大多数协议,举个例子:假设有5个人,把一个秘密分享给其中3人,那么随机挑选3个人,至少有1个人知道这个秘密!

二阶段提交

假设集群节点数为2N+1,leader处理请求分4步:

  1. 把日志复制给半数以上节点,如果复制失败则无限重试
  2. 只要有N+1个节点复制成功,则本地commit提交(写提交日志,执行业务逻辑)
  3. 返回客户端告知成功
  4. leader异步的把commit事件广播给follower们

上述操作先执行复制,再广播提交,对于follower们就是2阶段。

一句话概括:如果一共有2n+1个节点,有大多数follower(n+1)复制完leader就给调用者返回,之后leader再异步通知follower完成提交

选举约束

如果Leader节点由于异常原因无法提供服务了,这是会从Follower中选举新的Leader。从Follower的角度来看,当它接收不到Leader节点的心跳时,就可以认为Leader节点不在了。

Follower的选举过程如下:

1、节点由Follower变为Candidate,同时设置当前的Term(任期)

2、Candidate节点给自己投一票,同时向其它节点发送拉票请求

3、Follower只能向大于自己term的Candidate进行投票;term相等的情况下,选择记录了最新log的

4、Candidate等待投票结果,可能的结果如下: a)赢得选举,节点状态变为Leader b)其它节点赢得选举,节点状态变为Follower c)本轮选举未产生结果,节点状态保持为Candidate

三种投票结果说明:

自己赢得选举

只有当一个Candidate得到过半的选票时才能赢得选举,每一个节点按照先到先得的方式,最多投票给一位Candidate。

在Candidate赢得选举后,自己变为Leader,同时向所有节点发送心跳信息以使其他节点变为Follower,开始下一任任期。

他人赢得选举

在等待投票结果的过程中,如果Candidate收到其他节点发送的心跳信息,并检查心跳信息中的任期不比自己小,则自己变为Follower,听从新上任的Leader的指挥。

未产生结果

举个例子:当有多个Candidate同时竞选时,由于每个人先为自己投一票,导致没有任何一个人的选票数量过半。

当这种情况出现时,每一位Candidate都开始准备下一任竞选:将Term+1,同时再次发送拉票请求。为了防止出现长时间选不出新Leader的情况,Raft采用了两个方法:

1、Follower认为Leader不可用的超时时间,是一个随机值,这首先防止了所有的Follower都在同一时刻发现Leader不可用的情况,从而让先发现的Follower顺利当选

2、即使出现多个Candidate同时竞选的情况,再发送拉票请求时,也有一段随机的延迟,来保证大家不是同时发送拉票请求

 

七、区别

注册中心的区别

功能特性etcdConsulzookeeper
服务健康检查连接心跳服务状态,内存,硬盘等(弱)长连接,keepalive
多数据中心支持
kv存储服务支持支持支持
一致性raftraftpaxos
capcpcacp
使用接口(多语言能力)http/grpc支持http和dns客户端
watch支持支持 long polling全量/支持long polling支持
自身监控metricsmetrics
安全https支持(弱)acl /httpsacl
spring cloud集成已支持已支持已支持

延伸:CAP原则

CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

CAP

分布式锁的区别

功能特性redisetcdzookeeper
一致性算法raftpaxos
CAPAPCPCP
高可用主从N+1可用N+1可用
接口类型客户端http/grpc客户端
实现setNXrestful APIcreateEphemeral

redis分布式锁

实现简单,市面上也有许多的开源框架。但从根本上来说,它并不适合于分布式锁。因为分布式锁从业务场景上来说,是CP的,但Redis是AP的。

redis依靠主从,一旦主节点宕机,数据没有同步到从节点中,会出现再次上锁的问题。如果业务一定需要数据的一致性,在高并发的场景下是不建议选择redis锁的实现

ZK分布式锁

依靠的是创建临时顺序节点和watch监听机制,它的效率和扩展能力都是比较低的,因此,也较少人使用。

etcd分布式锁

不同于Redis,在一致性和集群方面,借鉴了Zookeeper,使得它的集群能力和一致性能力都是比较强的。

在使用方面,又采用restful API这种比较简单的使用方式,有点像ES。其实etcd是比较适合用来做分布式锁的。

 

八、安装

源码包安装

Docker部署etcd集群

ZoneIP同伴通信Port对外服务Port
etcd-node-110.110.2.923802379
etcd-node-210.110.2.1023802379
etcd-node-310.110.2.1123802379

 

参数说明:

 

九、使用

数据库操作

set

支持的选项有: --ttl value 该键值的超时时间(单位为秒),不配置(默认为0)则永不超时 --swap-with-value value 若该键现在的值是value,则进行设置操作 --swap-with-index value 若该键现在的索引值是指定索引,则进行设置操作

get

支持的选项有: --sort 对结果进行排序 --consistent 将请求发给主节点,保证获取内容的一致性。

注意:key不存在时会报错

update

支持的选项有: --ttl value 超时时间(单位为秒),不配置(默认为 0)则永不超时。

注意:key不存在时会报错

rm

支持的选项有: --dir 如果键是个空目录或者键值对则删除 --recursive 删除目录和所有子键 --with-value value 检查现有的值是否匹配 --with-index value 检查现有的index是否匹配

注意:key不存在时会报错

其它命令

mk、mkdir、setdir、updatedir、rmdir等等,具体用法使用命令 etcdctl help 可以查看。

 

API文档

https://etcd.io/docs/v2.3/api/

 

GO操作etcd

 

GO实现分布式锁

 

十、资源