前言
先简单聊聊分布式算法的重要性问题
在分布式微服务系统的项目中,最重要的是 如何选择或者设计合适的算法,来解决一致性问题以及可用性等相关问题
而分布式系统的最关键之处,在于根据场景的需要选择合适的算法,在一致性和可用性之间权衡(注:因为分区容错性是必须满足的),而权衡妥协的关键在于是否了解各个算法的特点,对于其他技术也适用。找到影响选择的因素,了解各个技术的特点,根据场景需要权衡选择。
下面是一些分布式算法的比较:
当然本章不是介绍所有的分布式算法,我也没法仅仅使用一篇文章就把上面表格中覆盖的分布式算法知识清晰的讲述。
所有我们重点讲解的是现在分布式算法或者说现在分布式数据一致性首选算法:Raft 算法
raft是工程上使用较为广泛的强一致性、去中心化、高可用的分布式协议。在这里强调了是在工程上,因为在学术理论界,最耀眼的还是大名鼎鼎的Paxos。但Paxos是:少数真正理解的人觉得简单,尚未理解的人觉得很难,大多数人都是一知半解。本人也花了很多时间、看了很多材料也没有真正理解。直到看到raft的论文,两位研究者也提到,他们也花了很长的时间来理解Paxos,他们也觉得很难理解,于是研究出了raft算法。
raft是一个共识算法(consensus algorithm),所谓共识,就是多个节点对某个事情达成一致的看法,即使是在部分节点故障、网络延时、网络分割的情况下。这些年最为火热的加密货币(比特币、区块链)就需要共识算法,而在分布式系统中,共识算法更多用于提高系统的容错性。raft协议就是一种leader-based的共识算法,与之相应的是leaderless的共识算法。
本文基于论文In Search of an Understandable Consensus Algorithm对raft协议进行分析,当然,还是建议读者直接看论文。
简单提一下,因为Raft协议也是基于CAP理论,但是现在大部分人对CAP 存在一个误解,认为无论在什么情况下,A和C 只能选择一个,因为P必选,其实,在不存在网络分区的情况下或者网络故障等问题的时候,也就是分布式系统正常,P 不需要的时候,C和P是能同时保证的。只有发生故障分区的时候,在需要的P的时候,才会在C和P 中抉择。
Raft协议
首先来一句话简单说下Raft 是什么:从本质上,Raft协议就是一切以领导者为准的方式,实现一系列值的共识和各节点日志的一致性
现在我们带着一些问题,边思考边分析Raft协议
(1)如何选举leader?
(2)节点间是如何通讯的呢?
(3)数据一致性是如何保证的?
(4)数据不一种的时候如何进行修复?
leader选举
领导者周期性地向所有跟随者发送心跳消息(即不包含日志项的日志复制 RPC 消息),通知大家我是领导者,阻止跟随者发起新的选举。
如果在指定时间内,跟随者没有接收到来自领导者的消息,那么它就认为当前没有领导者,推举自己为候选人,发起领导者选举。
在一次选举中,赢得大多数选票的候选人,将晋升为领导者。在一个任期内,领导者一直都会是领导者,直到它自身出现问题(比如宕机),或者因为网络延迟,其他节点发起一轮新的选举。
在一次选举中,每一个服务器节点最多会对一个任期编号投出一张选票,并且按照“先来先服务”的原则进行投票。比如节点 C 的任期编号为 3,先收到了 1 个包含任期编号为 4 的投票请求(来自节点 A),然后又收到了 1 个包含任期编号为 4 的投票请求(来自节点 B)。
那么节点 C 将会把唯一一张选票投给节点 A,当再收到节点 B 的投票请求 RPC 消息时,对于编号为 4 的任期,已没有选票可投了。