Skip to content

Commit f1ee9c6

Browse files
author
wangyazhou
committed
te
1 parent 2c3d3b0 commit f1ee9c6

16 files changed

+809
-25
lines changed
Loading
1000 KB
Loading
Loading
Loading
27.3 KB
Loading
Loading
Loading
Loading
Loading
Loading
69.6 KB
Loading
Loading
56.5 KB
Loading
Loading

k8s/kubernetes.md

Lines changed: 795 additions & 11 deletions
Large diffs are not rendered by default.

network/分布式.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -394,18 +394,20 @@ Paxos 算法的第二个阶段称“批准阶段”(Accept)。提议者向
394394

395395
现在,我们来分析 S1 、S5 同时发起提案,会出现什么情况。
396396

397-
**情况一:提案已批准**如图 6-7 所示,S1 收到客户端的请求,于是 S1 作为提议者,向 S1...S3 广播 Prepare(3.1) 消息,决策者 S1...S3 没有接受过任何提案,所以接受该提案。接着,S1 广播 Accept(3.1, X) 消息,提案 X 成功被批准。
397+
**情况一:提案已批准**如图所示,S1 收到客户端的请求,于是 S1 作为提议者,向 S1...S3 广播 Prepare(3.1) 消息,决策者 S1...S3 没有接受过任何提案,所以接受该提案。接着,S1 广播 Accept(3.1, X) 消息,提案 X 成功被批准。
398398

399399
在提案 X 被批准后,S5 收到客户端的提案 Y,S5 作为提议者向 S3...S5 广播 Prepare(4.5) 消息。对 S3 来说,4.5 比 3.1 大,且已经接受了 X,它回复提案 (3.1, X)。S5 收到 S3...S5 的回复后,使用 X 替换自己的 Y,接着进入批准阶段,广播 Accept(4.5, X) 消息。S3...S5 批准提案,所有决策者就 X 达成一致。
400-
![[Pasted image 20250606160134.png]]**情况二:事实上,对于情况一,也就是“取值为 X”并不是一定需要多数派批准,S5 发起提案时,准备阶段的应答中是否包含了批准过 X 的决策者也影响决策**。如图 6-8 所示,S3 接受了提案 (3.1, X),但 S1、S2 还没有收到 Accept(3.1, X) 消息。此时 S3、S4、S5 收到 Prepare(4.5) 消息,S3 回复已经接受的提案 (3.1, X),S5 将提案值 Y 替换成 X,广播 Accept(4.5, X) 消息给 S3、S4、S5,对 S3 来说,编号 4.5 大于 3.1,所以批准提案 X,最终共识的结果仍然是 X。
400+
![[Pasted image 20250606160134.png]]
401+
402+
**情况二:事实上,对于情况一,也就是“取值为 X”并不是一定需要多数派批准,S5 发起提案时,准备阶段的应答中是否包含了批准过 X 的决策者也影响决策**。如图所示,S3 接受了提案 (3.1, X),但 S1、S2 还没有收到 Accept(3.1, X) 消息。此时 S3、S4、S5 收到 Prepare(4.5) 消息,S3 回复已经接受的提案 (3.1, X),S5 将提案值 Y 替换成 X,广播 Accept(4.5, X) 消息给 S3、S4、S5,对 S3 来说,编号 4.5 大于 3.1,所以批准提案 X,最终共识的结果仍然是 X。
401403
![[Pasted image 20250606160150.png]]
402404

403405
**情况三:另外一种可能的情况是 S5 发起提案时,准备阶段的应答中未包含批准过 X 的决策节点**。S1 接受了提案 (3.1, X),S3 先收到 Prepare(4.5) 消息,后收到 Accept(3.1, X) 消息,由于 3.1 小于 4.5,会直接拒绝这个提案。提案 X 没有收到多数的回复,X 提案就被阻止了。提案 Y 顺利通过,整个系统最终对“取值为 Y”达成一致。
404406
![[Pasted image 20250606160159.png]]
405407

406408
**情况四:从情况三可以推导出另一种极端的情况**,多个提议者同时发起提案,在准备阶段互相抢占,反复刷新决策者上的提案编号,导致任何一方都无法达到多数派决议,这个过程理论上可以无限持续下去,形成“活锁”(livelock)。
407409

408-
解决这个问题并不复杂,将重试时间随机化,就能减少这种巧合发生
410+
解决这个问题并不复杂,**将重试时间随机化**,就能减少这种巧合发生
409411

410412
![[Pasted image 20250606160219.png]]
411413
以上,就是整个 Paxos 算法的工作原理。
@@ -428,13 +430,11 @@ Raft 算法出现之前,绝大多数共识系统都是基于 Paxos 算法或
428430

429431
那段时期,虽然所有的共识系统都是从 Paxos 算法开始的,但工程师们实现过程中有很多难以逾越的难题,往往不得已开发出与 Paxos 完全不一样的算法,这导致 Lamport 的证明并没有太大价值。所以,很长的一段时间内,实际上并没有一个被大众广泛认同的 Paxos 算法。
430432

431-
> Paxos 算法的理论描述与实际工程实现之间存在巨大鸿沟,最终实现的系统往往建立在一个尚未完全证明的算法基础之上。
432-
433-
—— Chubby 作者评论 Paxos
433+
> Paxos 算法的理论描述与实际工程实现之间存在巨大鸿沟,最终实现的系统往往建立在一个尚未完全证明的算法基础之上。-- Chubby 作者评论 Paxos
434434
435435
考虑到共识问题在分布式系统的重要性,同时为了提供一种更易于理解的教学方法,斯坦福大学的学者们决定重新设计一个替代 Paxos 的共识算法。
436436

437-
2013 年,斯坦福大学的学者 Diego Ongaro 和 John Ousterhout 发表了论文 《In Search of an Understandable Consensus Algorithm》[[1]](https://www.thebyte.com.cn/consensus/raft.html#footnote1),提出了 Raft 算法。Raft 论文开篇描述了 Raft 的证明和 Paxos 等价,详细阐述了算法如何实现。也就是说,Raft 天生就是 Paxos 算法的工程化。
437+
2013 年,斯坦福大学的学者 Diego Ongaro 和 John Ousterhout 发表了论文 《In Search of an Understandable Consensus Algorithm》,提出了 Raft 算法。Raft 论文开篇描述了 Raft 的证明和 Paxos 等价,详细阐述了算法如何实现。也就是说,Raft 天生就是 Paxos 算法的工程化。
438438

439439
> 《In Search of an Understandable Consensus Algorithm》节选
440440
> Raft is a consensus algorithm for managing a replicated log. It produces a result **equivalent to (multi-)Paxos, and it is as efficient as Paxos,** but its structure is different from Paxos;
@@ -466,7 +466,7 @@ raft的选举过程
466466

467467
RequestVote RPC 消息示例如下:
468468

469-
```
469+
```bash
470470
{
471471
"term": 5, // 候选者的当前任期号,用于通知接收方当前选举属于哪个任期。
472472
"candidateId": 3, // 候选者的节点 ID,标识请求投票的节点。
@@ -482,7 +482,7 @@ RequestVote RPC 消息示例如下:
482482

483483
RequestVote 响应的示例如下:
484484

485-
```
485+
```bash
486486
{
487487
"term": 5, //接收方的当前任期号,用于告知候选者最新的任期号。如果候选者发现该值比自己大,会转为跟随者。
488488
"voteGranted": true//是否投票给候选者,true 表示同意,false 表示拒绝。
@@ -497,14 +497,14 @@ RequestVote 响应的示例如下:
497497

498498
一旦选出一个公认的领导者,那领导者顺理成章地承担起“**处理系统发生的所有变更,并将变更复制到所有跟随者节点**”的职责。
499499

500-
在 Raft 算法中,日志承载着系统所有变更。图 6-13 展示了 Raft 集群的日志模型,每个“日志条目”(log entry)包含索引、任期、指令等关键信息:
500+
在 Raft 算法中,日志承载着系统所有变更。如图展示了 Raft 集群的日志模型,每个“日志条目”(log entry)包含索引、任期、指令等关键信息:
501501

502502
- **指令**: 表示客户端请求的具体操作内容,也就是待“状态机”(State Machine)执行的操作。
503503
- **索引值**:日志条目在仓库中的索引值,是单调递增的数字。
504504
- **任期编号**:日志条目是在哪个任期中创建的,用于解决“脑裂”或日志不一致问题。
505505
![[raft-log-C8Qk2Ad7.svg]]Raft 算法中,领导者通过广播消息(AppendEntries RPC)将日志条目复制到所有跟随者。AppendEntries RPC 的示例如下:
506506

507-
```
507+
```bash
508508
{
509509
"term": 5, // 领导者的任期号
510510
"leaderId": "leader-123",
@@ -517,7 +517,7 @@ RequestVote 响应的示例如下:
517517
}
518518
```
519519
520-
根据图 6-14 所示,当 Raft 集群收到客户端请求(例如 set x=4)时,日志复制的过程如下:
520+
当 Raft 集群收到客户端请求(例如 set x=4)时,日志复制的过程如下:
521521
522522
- 若当前节点非领导者,将请求转发至领导者;
523523
- 领导者接收请求后:
@@ -538,7 +538,7 @@ Raft 日志复制过程需要等待多数节点确认。节点越多,等待的
538538
539539
日志不连续的问题是这样解决的:follower-2 收到日志复制请求后,它会通过 prevLogIndex 和 prevLogTerm 检查本地日志的连续性。如果日志缺失或存在冲突,follower-2 返回失败响应,指明与领导者日志不一致的部分。
540540
541-
```
541+
```bash
542542
{
543543
"success": false,
544544
"term": 4,
@@ -573,7 +573,7 @@ Raft 的论文中,对此提出过一种基于两阶段的“联合共识”(
573573
574574
单成员变更方案很容易穷举所有情况,如图 6-16 所示,穷举奇/偶数集群下节点添加/删除情况。如果每次只操作一个节点,Cold 的 Quorum 和 Cnew 的 Quorum 一定存在交集。交集节点只会进行一次投票,要么投票给 Cold,要么投票给 Cnew。因此,不可能出现两个符合条件的 Quorum,也就不会出现两个领导者。
575575
576-
以图 6-16 第二种情况为例,Cold 为 [Server1、Server2、Server3],该配置的 Quorum 为 2,Cnew 为 [Server1、Server2、Server3、Server4],该配置的 Quorum 为 3。假设 Server1、Server2 比较迟钝,还在用 Cold ,其他节点的状态机已经应用 Cnew:
576+
以上图第二种情况为例,Cold 为 [Server1、Server2、Server3],该配置的 Quorum 为 2,Cnew 为 [Server1、Server2、Server3、Server4],该配置的 Quorum 为 3。假设 Server1、Server2 比较迟钝,还在用 Cold ,其他节点的状态机已经应用 Cnew:
577577
578578
- 假设 Server1 触发选举,赢得 Server1,Server2 的投票,满足 Cold Quorum 要求,当选领导者;
579579
- 假设 Server3 也触发选举,赢得 Server3,Server4 的投票,但**不满足 Cnew 的 Quorum 要求,选举失效**

0 commit comments

Comments
 (0)