作者:王雷
etcd是什么
etcd是云原生架构中重要的根底组件,由CNCF孵化托管。ETCD是用于共享配置和服务发现的分布式,一致性的KV存储系统,是CoreOS公司发动的一个开源我的项目,受权协定为Apache。etcd 基于Go语言实现,次要用于共享配置,服务发现,集群监控,leader选举,分布式锁等场景。在微服务和 Kubernates 集群中不仅能够作为服务注册发现,还能够作为 key-value 存储的中间件。
提到键值存储系统,在大数据畛域利用最多的当属ZOOKEEPER,而ETCD能够算得上是后起之秀了。在我的项目实现,一致性协定易了解性,运维,平安等多个维度上,ETCD相比Zookeeper都占据劣势。
ETCD vs ZK
ETCD | ZK | |
---|---|---|
一致性协定 | Raft协定 | ZAB(类Paxos协定) |
运维方面 | 不便运维 | 难以运维 |
我的项目活跃度 | 沉闷 | 没有etcd沉闷 |
API | ETCD提供HTTP+JSON, gRPC接口,跨平台跨语言 | ZK须要应用其客户端 |
拜访平安方面 | ETCD反对HTTPS拜访 | ZK在这方面不反对 |
etcd的架构
etcd 是一个分布式的、牢靠的 key-value 存储系统,它用于存储分布式系统中的要害数据,这个定义十分重要。
通过上面这个指令,理解一下etcd命令的执行流程,其中etcdctl:是一个客户端,用来操作etcd。
etcdctl put key test
通常etcd都是以集群的形式来提供服务的,etcdctl操作命令的时候,会对应到leader当中的gRPC Server
gRPC Server
用来接管客户端具体的申请进行解决,然而不仅仅是解决客户端的连贯,它同时负责解决集群当中节点之间的通信。
wal: Write Ahead Log(预写式日志)
etcd 的数据存储形式。除了在内存中存有所有数据的状态以及节点的索引以外,etcd 就通过 WAL 进行长久化存储。WAL 中,所有的数据提交前都会当时记录日志。实现事务日志的规范办法;执行写操作前先写日志,跟mysql中redo相似,wal实现的是程序写。
当执行put操作时,会批改etcd数据的状态,执行具体的批改的操作,wal是一个日志,在批改数据库状态的时候,会先批改日志。put key test会在wal记录日志,而后会进行播送,播送给集群当中其余的节点设置key的日志。其余节点之后会返回leader是否批准数据的批改,当leader收到一半的申请,就会把值刷到磁盘中。
snapshot
etcd 避免 WAL 文件过多而设置的快照,用于存储某一时刻etcd的所有数据。Snapshot
和 WAL
相结合,etcd
能够无效地进行数据存储和节点故障复原等操作。
boltdb
相当于mysql当中的存储引擎,etcd中的每个key都会创立一个索引,对应一个B+树。
etcd重要的个性
•存储:数据分层存储在文件目录中,相似于咱们日常应用的文件系统;
•Watch 机制:Watch 指定的键、前缀目录的更改,并对更改工夫进行告诉;
•平安通信:反对 SSL 证书验证;
•高性能:etcd 单实例能够反对 2K/s 读操作,官网也有提供基准测试脚本;
•统一牢靠:基于 Raft 共识算法,实现分布式系统外部数据存储、服务调用的一致性和高可用性;
•Revision 机制:每个 Key 带有一个 Revision 号,每进行一次事务便加一,因而它是全局惟一的,如初始值为 0,进行一次 Put 操作,Key 的 Revision 变为 1,同样的操作,再进行一次,Revision 变为 2;换成 Key1 进行 Put 操作,Revision 将变为 3。这种机制有一个作用,即通过 Revision 的大小就可晓得写操作的程序,这对于实现偏心锁,队列非常无益;
•lease机制:lease 是分布式系统中一个常见的概念,用于代表一个分布式租约。典型状况下,在分布式系统中须要去检测一个节点是否存活的时,就须要租约机制。
首先创立了一个 10s 的租约,如果创立租约后不做任何的操作,那么 10s 之后,这个租约就会主动过期。接着将 key1 和 key2 两个 key value 绑定到这个租约之上,这样当租约过期时 etcd 就会主动清理掉 key1 和 key2,使得节点 key1 和 key2 具备了超时主动删除的能力。
如果心愿这个租约永不过期,须要周期性的调用 KeeyAlive 办法刷新租约。比如说须要检测分布式系统中一个过程是否存活,能够在过程中去创立一个租约,并在该过程中周期性的调用 KeepAlive 的办法。如果一切正常,该节点的租约会统一放弃,如果这个过程挂掉了,最终这个租约就会主动过期。
类比redis的expire,redis expore key ttl,如果key过期的话,到了过期工夫,redis会删除这个key。etcd的实现:将过期工夫雷同的key全副绑定一个全局的对象,去治理过期,etcd只须要检测这个对象的过期。通过多个 key 绑定在同一个 lease 的模式,咱们能够将超工夫类似的 key 聚合在一起,从而大幅减小租约刷新的开销,在不失灵活性同时可能大幅提高 etcd 反对的应用规模。
在引擎中的场景
服务注册发现
etcd基于Raft算法,可能无力的保障分布式场景中的一致性。各个服务启动时注册到etcd上,同时为这些服务配置键的TTL工夫。注册到etcd上的各个服务实例通过心跳的形式定期续租,实现服务实例的状态监控。服务提供方在 etcd 指定的目录(前缀机制反对)下注册服务,服务调用方在对应的目录下查问服务。通过 watch 机制,服务调用方还能够监测服务的变动。
引擎服务蕴含两大模块,一个是master服务,一个是调度服务。
master服务
master服务启动胜利后,向etcd注册服务,并且定时向etcd发送心跳
server, err := NewServiceRegister(key, serviceAddress, 5) if err != nil { logging.WebLog.Error(err) }
定时向etcd发送心跳
//设置续租 定期发送需要申请 leaseRespChan, err := s.cli.KeepAlive(context.Background(), resp.ID)
调度服务
调度服务作为服务的消费者,监听服务目录:key=/publictest/pipeline/
// 从etcd中订阅前缀为 "/pipeline/" 的服务go etcdv3client.SubscribeService("/publictest/pipeline/", setting.Conf.EtcdConfig)
监听put和delete操作,同时在本地保护serverslist,如果有put或者delete操作,会更新本地的serverslist
客户端发现指客户端间接连贯注册核心,获取服务信息,本人实现负载平衡,应用一种负载平衡策略发动申请。劣势能够定制化发现策略与负载平衡策略,劣势也很显著,每一个客户端都须要实现对应的服务发现和负载平衡。
watch机制
etcd能够Watch
指定的键、前缀目录的更改,并对更改工夫进行告诉。BASE引擎中,缓存的革除策略借助etcd来实现。
缓存过期策略:在编译减速的实现中,每个须要缓存的我的项目都有对应的缓存key,通过etcd监控key,并且设置过期工夫,例如7天,如果在7天之内再次命中key,则通过lease进行续约;7天之内key都没有被应用,key就会过期删除,通过监听对应的前缀,在过期删除的时候,调用删除缓存的办法。
storage.Watch("cache/", func(id string) { //do nothing }, func(id string) { CleanCache(id) })
除此之外,引擎在流水线勾销和人工确认超时的场景中,也应用到了etcd的watch机制,监听某一个前缀的key,如果key产生了变动,进行相应的逻辑解决。
集群监控与leader选举机制
集群监控:通过 etcd 的 watch 机制,当某个 key 隐没或变动时,watcher 会第一工夫发现并告知用户。节点能够为 key 设置租约(TTL),比方每隔 30 s 向 etcd 发送一次心跳续约,使代表该节点的 key 放弃存活,一旦节点故障,续约进行,对应的 key 将生效删除。如此,通过 watch 机制就能够第一工夫检测到各节点的衰弱状态,以实现集群的监控要求。
Leader 竞选:应用分布式锁,能够很好地实现 Leader 竞选(抢锁胜利的成为 Leader)。Leader 利用的经典场景是在搜寻零碎中建设全量索引。如果每个机器别离进行索引建设,不仅耗时,而且不能保障索引的一致性。通过在 etcd 实现的锁机制竞选 Leader,由 Leader 进行索引计算,再将计算结果散发到其它节点。
相似kafka的controller选举,引擎的调度服务启动,所有的服务都注册到etcd的/leader上面,其中最先注册胜利的节点成为leader节点,其余节点主动变成follow。
leader节点负责从redis中获取工作,依据负载平衡算法,将工作派发给对应的go master服务。
follow节点监听leader节点的状态,如果leader节点服务不可用,对应节点删除,follow节点会从新抢占,成为新的leader节点。
同时leader设置在etcd中的leader标识设置过期工夫为60s,leader每隔30s更新一次。follow每隔30s到etcd中通告本人存活,并查看leader存活。