Distributed System FAQ
CAP 原理是什么?
CAP 原理(CAP Theorem)是分布式系统中一个著名的理论,由 Eric Brewer 在 2000 年提出。它描述了分布式系统在一致性、可用性和分区容错性三者之间的权衡关系。
三个核心概念:
一致性(Consistency) 所有节点在同一时间看到的数据是一致的,即系统对某一操作的所有副本更新成功后才会返回结果。 例子:银行账户余额的操作,任何时候查询都必须反映最新的交易记录。
可用性(Availability) 系统始终能够响应用户的读写请求,即使某些节点失效。换句话说,服务必须是可用的,但返回的结果可能不一定是最新的。 例子:购物网站在促销高峰时,某些延迟的数据更新不会影响其提供基本购物功能。
分区容错性(Partition Tolerance)
系统在面对分区(网络故障、节点故障)时,仍然能够继续工作。 例子:两个数据中心之间的网络断开后,各自的数据副本仍能正常提供服务。
核心理论:
在一个分布式系统中,不可能同时完全满足一致性、可用性和分区容错性,只能三者中满足两个:
CP 系统:放弃可用性,保证一致性和分区容错性。 例子:分布式数据库如 HBase。
AP 系统:放弃一致性,保证可用性和分区容错性。 例子:DNS 系统。
CA 系统:放弃分区容错性,保证一致性和可用性(理论上无法实现,因为分区容错性对分布式系统至关重要)。
CAP 原理强调了分布式系统设计中的权衡,需要根据应用场景选择最合适的折中方案。
分布式事务怎么实现?
分布式事务是指跨多个服务或数据库的事务操作,这些操作需要满足原子性、一致性、隔离性和持久性(ACID)原则。分布式事务在分布式系统中较为复杂,因为它涉及多个节点之间的协调和同步。
常见的分布式事务实现方式:
两阶段提交(2PC, Two-Phase Commit)
阶段 1:准备阶段(Prepare Phase) 所有参与者节点执行事务并将更改写入日志,但不提交。协调者节点等待所有参与者的响应。
阶段 2:提交阶段(Commit Phase) 如果所有参与者都准备成功,则协调者发出提交命令;否则,发出回滚命令。
优点:实现简单,适用于需要强一致性的场景。 缺点:存在性能瓶颈,且在协调者失效时可能导致阻塞问题。
三阶段提交(3PC, Three-Phase Commit)
引入了一个预提交阶段,进一步减少阻塞风险。
分为:CanCommit、PreCommit 和 Commit。
优点:相比 2PC,更容错,但仍不能完全避免脑裂问题。
基于消息队列的事务
思路:通过可靠消息队列协调事务的一致性。
举例:订单创建与支付状态更新通过消息队列进行异步协调。
优点:适用于最终一致性场景,性能较高。
缺点:需要仔细设计补偿逻辑。
TCC 模型(Try-Confirm-Cancel)
将事务分为三个步骤:
Try:预留资源。
Confirm:确认并提交操作。
Cancel:回滚并释放资源。
适用场景:电商、金融等需要资源预留的分布式场景。
优点:高灵活性,可控制粒度。
缺点:业务逻辑复杂,开发成本较高。
Saga 模式
将长事务拆分为一系列短事务,每个短事务都有对应的补偿操作。
两种协调方式:
顺序协调:一个事务失败,立即触发补偿。
事件驱动协调:通过事件总线协调事务。
优点:性能较高,适合最终一致性场景。
缺点:事务复杂性高,依赖补偿操作的正确性。
分布式事务与 CAP 的关系:
分布式事务通常会选择一致性(C)和分区容错性(P),在可用性(A)上进行妥协。
在很多实际场景中,分布式系统更倾向于最终一致性(如 Saga 和消息队列),从而提高系统可用性。
分布式协议 RAFT 是怎么实现一致性的?
RAFT 是一种用于分布式系统中实现一致性的协议,它提供了更易理解的方式来实现分布式日志复制。RAFT 协议特别适用于一致性和分区容错性(CP)系统,主要用于构建分布式存储系统(如 etcd 和 Consul)。以下是 RAFT 的详细工作原理及实现一致性的方式:
RAFT 协议的核心目标
RAFT 的主要目标是确保分布式系统中:
所有节点共享一个一致的日志。
系统能够在部分节点故障时继续工作。
系统能够处理网络分区问题。
RAFT 协议的核心角色
RAFT 集群由多个节点组成,每个节点可以扮演以下三种角色之一:
Leader(领导者):
负责处理所有客户端请求。
负责日志的复制和提交。
每个任期(term)最多只能有一个 Leader。
Follower(追随者):
被动响应来自 Leader 的指令。
如果没有收到 Leader 的心跳消息,会发起选举。
Candidate(候选者):
由 Follower 转变而来,在选举期间竞选成为 Leader。
RAFT 的三个核心子模块
1. Leader 选举
2. 日志复制
3. 日志一致性保障
1. Leader 选举
在分布式系统中,需要选出一个 Leader 来协调各节点操作。RAFT 使用如下步骤实现 Leader 选举:
初始状态:
所有节点默认为 Follower。
如果 Follower 在选举超时时间内没有收到 Leader 的心跳消息,则转为 Candidate 并发起选举。
选举流程:
Candidate 增加自己的任期号(term)并给自己投票。
向其他节点发送 RequestVote 请求。
其他节点对比任期号并决定是否投票:
如果 Candidate 的任期号比自己高,投票给 Candidate。
如果任期号较低,则拒绝投票。
如果 Candidate 获得多数投票(n/2 + 1),成为 Leader。
选举结果:
如果某个节点成功当选为 Leader,则它开始发送心跳消息,告知其他节点自己是新的 Leader。
如果选举失败(没有节点获得多数投票),节点会增加任期号并重新开始选举。
2. 日志复制
Leader 负责接收客户端请求并将其添加到日志中,然后通过以下过程将日志复制到 Follower:
Leader 接收日志条目:
Leader 将客户端的写请求作为新的日志条目添加到其本地日志中,但未立即提交。
发送 AppendEntries:
Leader 将新的日志条目通过 AppendEntries RPC 发送给所有 Follower。
消息中包含:
当前任期号(term)。
新的日志条目。
前一个日志条目的索引和任期号(用于一致性检查)。
Follower 响应:
Follower 检查日志是否连续:
如果连续,则将日志条目追加到其本地日志中并回复成功。
如果不连续,则返回失败,Leader 会回退并重新发送正确的日志。
提交日志(Log Commit):
Leader 在收到多数节点确认日志已复制后,将日志条目标记为已提交,并通知所有 Follower 提交日志。
日志提交后,日志中的操作会生效,响应客户端请求。
3. 日志一致性保障
RAFT 通过以下规则保障日志一致性:
日志连续性检查:
AppendEntries 消息中包含前一个日志条目的索引和任期号。如果 Follower 的日志不匹配,Leader 会回退日志直到找到匹配点。
多数派规则:
只有当日志条目被复制到多数节点时,才能认为该条目是已提交的。
Leader 的日志总是最新的:
在 Leader 选举期间,候选者必须拥有最新的日志,否则无法当选为 Leader。
幂等性:
即使日志条目被重复发送,RAFT 保证每个条目在节点上只应用一次。
RAFT 如何实现一致性
通过 Leader 提供中心化管理:
所有写操作必须经过 Leader,避免写冲突。
Leader 确保日志在复制到多数节点后才提交。
日志的严格顺序:
每个日志条目包含唯一的索引和任期号。
Follower 的日志与 Leader 保持严格一致。
容错机制:
即使部分节点宕机,Leader 仍能协调剩余节点完成日志复制。
强一致性:
当客户端收到确认时,保证该操作已被提交到多数节点并应用。
RAFT 的优点
易于理解:相比于 Paxos,RAFT 的逻辑更清晰,更适合工程实现。
可维护性强:通过划分子问题(选举、日志复制、一致性检查)降低了复杂性。
容错能力高:允许部分节点失败而不影响整体一致性。
RAFT 的缺点
性能开销:由于日志复制需要多数节点确认,性能可能低于弱一致性系统。
网络分区时的延迟:在网络分区严重时,选举和日志同步可能会变慢。
总结
RAFT 通过 Leader 选举、日志复制和一致性检查三大机制,实现了分布式系统中的强一致性。 它的设计目标是简化 Paxos 的复杂性,同时提供工程上易实现的解决方案,是构建一致性系统的基础协议之一。
分布式协议 Paxos 是怎么实现一致性的?
Paxos 协议
Paxos 是 Leslie Lamport 提出的分布式一致性协议,专注于在不可靠的分布式环境中实现一致性。它是分布式系统中强一致性的理论基础。Paxos 的核心目标是确保多个节点(或称副本)在面对网络延迟、节点故障或消息丢失时,能够就某一值达成共识。
Paxos 的基本概念
在 Paxos 中,系统中的节点有三种角色:
Proposer(提议者):
提议某个值给其他节点,希望该值能被采纳。
通常代表客户端的请求。
Acceptor(接受者):
决定是否接受一个提议(proposal)。
多个 Acceptor 组成一个“仲裁组”,用于保证一致性。
Learner(学习者):
学习最终被采纳的值。
通常用于将最终一致的值通知客户端或其他组件。
Paxos 的主要流程
Paxos 协议分为两阶段实现一致性:Prepare 阶段和Accept 阶段。
Prepare 阶段(准备阶段)
Proposer 生成提案编号: * 提议者生成一个唯一的提案编号(Proposal Number),确保编号递增且唯一。
发送 Prepare 请求: * Proposer 将提案编号发送给所有 Acceptor,请求其承诺不再接受编号低于该提案的任何提议。
Acceptor 响应:
* 如果 Acceptor 收到的提案编号比自己之前承诺的编号更高,则承诺(Promise):
* 不再接受编号低于该提案编号的任何提议。
* 返回它已经接受的编号最高的提案(如果有)。
Accept 阶段(接受阶段)
Proposer 决定提议值:
根据 Acceptor 返回的响应,Proposer 决定提议的值:
如果返回的提案中有已接受的值,则选择编号最高的提案值。
如果没有已接受的值,则选择一个新的值。
发送 Accept 请求:
Proposer 将提案编号和提议值发送给所有 Acceptor,要求其接受该提案。
Acceptor 响应:
如果接收到的提案编号仍然是它承诺过的最高编号,则接受该提案。
Acceptor 会将该提案存储,并通知 Learner。
决议完成
当一个提案被大多数 Acceptor 接受时,该提案就被认为达成共识(Chosen)。
Learner 收到被接受的提案值后,将其传播到整个系统,使所有节点达成一致。
Paxos 的一致性保障
Paxos 的一致性由以下原则保障:
提案编号递增性:
每次提案编号递增,确保更高编号的提案可以覆盖之前的提案。
已接受提案的优先级:
如果某个提案已经被接受,则所有新的提案必须选择编号最高的已接受值,避免多个值被同时接受。
多数派原则:
一个提案必须被多数 Acceptor 接受才能被认为达成一致,确保至少有一个 Acceptor 能与下一次提案的仲裁组重叠。
故障容忍性:
Paxos 能在多数 Acceptor 存活时继续运行,即使部分节点发生故障。
Paxos 的优点
强一致性:
Paxos 在任何情况下都能保证只有一个提案值被最终达成共识。
容错能力强:
Paxos 能容忍少量节点故障,只要超过一半的节点可用即可继续运行。
理论完备性:
Paxos 是经过形式化验证的协议,确保其正确性。
Paxos 的缺点
实现复杂:
Paxos 的流程较复杂,特别是多个角色的交互容易让实现者感到困惑。
性能瓶颈:
Paxos 的通信轮次较多,每个提案需要经过两个阶段(Prepare 和 Accept),导致高延迟。
难以扩展:
增加节点数量会显著提高网络通信开销,降低效率。
实际工程中的简化:
如 Raft 就简化了 Paxos 的复杂性,更适合工程实现。
Paxos 的改进版本
为解决 Paxos 的性能问题,出现了许多改进版本:
Multi-Paxos:
避免每次提议都进行选举,Leader 可以直接处理后续提案,减少 Prepare 阶段的开销。
Fast Paxos:
减少通信轮次,允许 Proposer 直接向 Acceptor 提交提案。
EPaxos:
支持并行提案,减少延迟,提高性能。
总结
Paxos 协议通过精巧的两阶段流程和多数派规则,在不可靠的分布式环境中实现了一致性。尽管 Paxos 是分布式一致性协议的理论基础,但由于实现复杂和性能瓶颈,在实际工程中通常使用其改进版(如 Multi-Paxos)或其他协议(如 Raft)。