分布式系统 Etcd 解析( 二 )


通常情况下,一个完整的工作流主要涉及以下活动:一个用户的请求发送过来,会经由 HTTP Server 转发给 Store 进行具体的事务处理,如果涉及到节点数据的修改,则交给 Raft 模块进行状态的变更、日志的记录,然后再同步给别的 Etcd 节点以确认数据提交,最后进行数据的提交,再次同步 。
那么,Etcd 主要应用于哪些场景呢?
通过官网定义,Etcd 是一个高可用强一致性的键值数据库在很多分布式系统架构中得到了广泛的应用,其最经典的使用场景就是服务发现 。那么有人问了,Zookeeper不香吗?基于 Zookeeper 当前的业务使用场景,结合微服务体系及 云原生K8S 生态支持层面,综合对比分析,Zookeeper 仍存在以下相关缺陷,具体如下:
1、复杂性,Zookeeper 基于Paxos 强一致性算法也以复杂难懂而闻名于世,除此之外,ZooKeeper 的使用也比较复杂,需要安装客户端,而且官方只提供了 Java 和 C 两种语言的接口,其移植性及可扩展性有限 。
2、生态发展滞后,无论是基于项目版本的更新还是所拥抱的生态,都表现的差强人意,尤其是在容器化生态中 。
3、笨重,Zookeeper 基于Java 语言开发,面向企业级应用,故基于Java 生态体系时不时会引入大量的依赖,从而使得维护交往笨重 。
相比较而言,Etcd 虽作为后起之秀,但其已经融入云原生生态领域,并且基于 Go 语言开发,高性能,基于 HTTP 作为接口使用简单、方便,使用 Raft 算法保证强一致性让用户易于理解 。除此,基于 Etcd 所默认的持久化机制与安全机制使得其在云原生生态领域能够得到进一步的发展 。
为什么 Etcd 在服务发现领域能够独占鳌头呢?具体主要涉及以下:
1、强一致性、高可用 。基于 Raft 算法的 Etcd 就是一个强一致性高可用的服务存储目录 。
2、注册服务和监控服务健康状态的机制 。用户可以在 Eetcd 中注册服务,并且对注册的服务设置 key TTL,定时保持服务的心跳以达到监控健康状态的效果 。
3、查找和连接服务的机制 。通过在 Etcd 指定的主题(由服务名称构成的服务目录)下注册的服务也能在对应的主题下查找到 。
那么,Etcd 如何保证数据一致性呢?
首先,Etcd 使用 Raft 协议来维护 Cluster 内各个 Nodes 状态的一致性 。也就是说,Etcd Cluster 是一个分布式系统,由多个 Nodes 相互通信构成整体对外服务,每个 Node 都存储了完整的数据,并且通过 Raft 协议保证每个 Node 维护的数据是一致的 。
其次,Etcd Cluster 中的每个 Node 都维护了一个状态机,并且任意时刻,Cluster 中至多存在一个有效的主节点,即:Leader Node 。由 Leader 处理所有来自客户端写操作,通过 Raft 协议保证写操作对状态机的改动会可靠的同步到其他 Follower Nodes 。具体可参考下 Etcd 算法机制,如下所示:

分布式系统 Etcd 解析

文章插图
 
基于数据一致性问题,分布式系统中常见的三种一致性模型:
1、强一致性:当更新操作在某个副本上执行成功后,之后所有的读操作都要能够获得最新的数据 。
2、弱一致性:当更新某数据时,用户读到最新的数据需要一段时间的延迟 。
3、最终一致性:它是一种特殊的弱一致性,当某个数据更新后,在经过一个时间片段,所有后续的操作能够获得新数据,在这个时间片段内,数据可能是不一致的 。
Raft 是分布式领域中的强一致性算法,当其中某个节点收到客户端的一组指令时,它必须与其它节点沟通,以保证所有的节点以相同的顺序收到相同的指令,最终所有的节点会产生一致的结果 。
如何选举 Leader 节点?
针对 Etcd,Raft 通过『领导选举机制』选举出一个 Leader,由它全权管理日志复制来实现一致性 。一个 Raft 集群包含若干个服务器节点,每一个节点都有一个唯一标识 ID,并且在任何时刻,每一个服务器节点都处于下面三个状态之一:
1、Leader(领导人):Leader 处理所有的客户端请求,在通常情况下,系统中只有一个Leader 并且其他节点都是 Follower 。
2、Follower(跟随者):Follower 不会发送任何请求,只是简单地响应来自 Leader
Candidate 的请求,如果一个客户端与 Follower 联系,那么 Follower 会把请求重定向至 Leader 。
3、Candidate(候选人):如果 Follower 接收不到来自 Leader 的消息,那么它就会变成 Candidate 并发起一次选举,获得集群中大多数选票(超过 n/2+1)的候选人将成为新的Leader 。
假设 Etcd Cluster 中有 3 个 Node,Cluster 启动之初并没有被选举出的 Leader 。此时,Raft 算法使用随机 Timer 来初始化 Leader 选举流程 。比如说上面 3 个 Node 上都运行了 Timer(每个 Timer 的持续时间是随机的),而 Node1 率先完成了 Timer,随后它就会向其他两个 Node 发送成为 Leader 的请求,其他 Node 接收到请求后会以投票回应然后第一个节点被选举为 Leader 。成为 Leader 后,该 Node 会以固定时间间隔向其他 Node 发送通知,确保自己仍是 Leader 。有些情况下当 Follower 们收不到 Leader 的通知后,比如说 Leader 节点宕机或者失去了连接,其他 Node 就会重复之前的选举流程,重新选举出新的 Leader 。具体可参考如下所示:


推荐阅读