为了向用户提供更好的服务体验,现代软件架构越来越注重系统的可用性availability
问题。正是在这种趋势的驱动下,微服务与容器化技术才能在今天大行其道。
而高可用架构的前提就是冗余。一个高可用服务必然由多个进程组成,这些进程互为备份,部分进程失效不会导致整个服务不可用。
如果服务是有状态的,那么每个进程都需要维护自己的一个状态副本。为了保证有状态进程的可替代性,如何维护这些副本的一致性consistency
成为了至关重要的问题。
以提供锁服务的分布式协调服务为例,这类服务必须满足一下两个特性:
根据分布式数据库的CAP
理论,同时实现这个特性是困难的:
在网络通信正常的时候,分布式数据库可以同时保证 C 与 A
在发生网络分区(进程间无法正常通信)的时候,数据库必须在 C 和 A 中做出权衡:
- AP 系统:保证可用性,牺牲一致性,每个节点可以对外服务,但整个数据库会处于不一致的状态
- CP 系统:保证一致性,牺牲可用性,每个节点拒绝对外服务,但整个数据库会始终保持一致的状态
在 CAP 的框架下,我们似乎陷入了一个两难的境地:实现一个 CA 的系统是不可能的吗?在回答这个问题前,首先要指出 CAP 理论存在的一个问题:
CAP 理论在权衡时仅考虑了 3 个因素,而忽略了其他的指标,比如:性能、实现复杂度、机器数量...
举个例子:一种流行的说法是 ZooKeeper 是一个 CP 系统。然而,在 ZooKeeper 集群中,只要有半数以上的节点之间能够正常通信,集群仍然能够正常对外提供服务。这意味着:ZooKeepr 在网络发生分区的情况下,依然是可用且一致。
在发生网络分区时,如果要保证系统的可用且一致,需要付出一些额外的代价。以 ZK 为例子,其付出的的代价就是更多的机器资源(必须部署 3 个以上的节点)与复杂度(使用一致性算法)。
所谓共识Consensus
,就是在某件事情上达成一致意见。分布式系统的共识问题可以表述为:
系统中一个或多个进程提出一个提案
Proposal
,然后通过共识算法从中选择一个提案作为最终结果。
以上图中的场景为例:图中是一个多主的分布式数据库,同时允许多个节点接收写操作请求,并且两者会彼此交换修改指令以保证数据的一致性。
刚好在某个时刻,两个客户端同时发起对同个记录的变更操作,因此可能同时存在两种不同的更新顺序(提案)。为了保证数据副本的一致性,两个数据库必须在更新顺序上达成一致(共识)。
进程间为了达成共识,必须遵循一套相同的机制对提议进行选择,从而保证最终选定Chosen
的提案是一致的,这类协议就是共识算法Consensus algorithm
。
由于运行环境的不确定性,系统故障总是是不可避免的,一个实用的共识算法必须能够在不确定的环境中,保障分布式系统的:
Safety
:所有进程收敛到一致的合法状态Fault-tolerance
:少量进程崩溃,系统可持续运行在分布式系统中,可能出现的故障大致可以分为两类:
Byzantine fault
Non-Byzantine fault
因此共识算法又可以分为拜占庭容错与非拜占庭容错两类。
前者主要是应用于区块链领域,通过高昂的计算开销来杜绝进程作恶的可能性,功能强大但不适合用于提供高性能的一致性保障。
后者主要是为数据管理服务,通过额外的安全性假设,减少容错开销,从而能够提供高性能的一致性保障。
接下来要解析的分布式一致性协议都属于非拜占庭共识算法。
原文:https://www.cnblogs.com/buttercup/p/12873512.html