Skip to content

Commit c1722ec

Browse files
committed
Add: paxos-same-ballot
1 parent 452b066 commit c1722ec

18 files changed

+255
-1
lines changed

_data/refs.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ universal:
4545
- "post-mmp3": https://blog.openacid.com/algo/mmp3/ "Multi-Master-Paxos 3"
4646
- "post-apaxos": https://blog.openacid.com/algo/abstract-paxos/ "Abstract-Paxos 统一 Paxos 和 Raft"
4747

48+
- "discuss-paxos": https://github.com/openacid/openacid.github.io/discussions/31 paxos的读者答疑
49+
4850

4951
zhihu:
5052
# my articles
@@ -55,4 +57,5 @@ zhihu:
5557
- "post-raft-bug": https://zhuanlan.zhihu.com/p/342319702 "TiDB 在 Raft 成员变更上踩的坑"
5658

5759
wechat:
60+
- "post-paxos": https://mp.weixin.qq.com/s/3OZgqEWQcEf6V9v6eoSUUA "可靠分布式系统-paxos的直观解释"
5861
- "post-paxoskv": https://mp.weixin.qq.com/s/_Iu6ITtXx4MVnKam3Q2ZTA "200行代码实现基于paxos的kv存储"
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
title: "Paxos 中 Ballot number 的重用机制"
3+
authors:
4+
- xp
5+
categories:
6+
- algo
7+
tags:
8+
- distributed
9+
- 分布式
10+
- paxos
11+
12+
refs:
13+
- x: y
14+
15+
disabled_article:
16+
image: /post-res/linearizable/linearizable-banner-big.png
17+
18+
mathjax: false
19+
toc: true
20+
toc_label: 本文目录
21+
toc_sticky: true
22+
excerpt: "本文探讨 Paxos 协议中 Ballot number 的重用机制,分析何时可重复使用,以及为何只能使用系统中已存在的值而非提议新值"
23+
---
24+
25+
![](/post-res/paxos-same-ballot/f3c38ebb6fbef4c9-paxos-same-ballot-banner.webp)
26+
27+
欢迎各位读者探讨 Paxos 的深层机制。在我此前发表的 [Paxos 的直观解释](https://zhuanlan.zhihu.com/p/145044486) 文章后,它作为一个完整的介绍 Paxos 文章, 收到了不少读者提出的深入问题,这些问题我已在 [Paxos 的读者答疑](https://github.com/openacid/openacid.github.io/discussions/31) 中详细回应。考虑到分布式共识算法的复杂性,我决定通过一系列 回答 Paxos 的特定问题 形式的文章来作为补充,本文是该系列的第一篇。希望这些分析能帮助你解决疑惑,从不同角度理解 Paxos,帮助自己在分布式系统领域构建更加完整的思维框架。
28+
29+
## 问:是否可以用同样的 Ballot number(rnd)运行 Paxos?
30+
31+
简短回答是:可以,但**不能**在这种情况下提议任何新的值;也就是说,若要用相同的 Ballot number 来重新运行 Paxos,则只能使用系统中**已经存在的值**,继续进行 phase-2(Accept 阶段)以完成提交。原因在于,若此时选择新的值,很可能会导致与现有已被接受的值产生冲突,进而导致不一致(脑裂)的情况。
32+
33+
Paxos 算法要求当我们用相同的 Ballot number 发起提案时,其流程不能从头开始选新值,否则会破坏 Paxos 的一致性。相反,我们只能“沿用”系统已存在、且在之前某一轮中被 Accept 过的值来继续完成提交。
34+
35+
---
36+
37+
## 示例
38+
39+
让我们通过一个时间线示意图来说明不同的时间点和 Paxos 状态。下面的图表展示了一个分布式系统中三个 Acceptor 节点在不同时间点的状态变化:
40+
41+
我们假设系统中已经发生了以下事件:
42+
43+
1. 第一个 Proposer 使用 Ballot number = 1:
44+
45+
- 在 Acceptor-1 和 Acceptor-2 上完成了 phase-1(Prepare 阶段)
46+
- 然后在 Acceptor-1 上完成了 phase-2(Accept 阶段),写入了值 X
47+
48+
1. 第二个 Proposer 使用 Ballot number = 2:
49+
50+
- 在 Acceptor-2 和 Acceptor-3 上完成了 phase-1(Prepare 阶段)
51+
- 然后在 Acceptor-1 和 Acceptor-2 上完成了 phase-2(Accept 阶段),提交了值 Y
52+
53+
![](/post-res/paxos-same-ballot/5abd75633aa50198-paxos-same-ballot-0.x.svg)
54+
55+
> 图中的事件以这种格式表示: `<phase><ballot_number>(<value>)`:
56+
>
57+
> - `phase` 可以是 P 或 A:
58+
> - **P** 表示 Prepare 阶段(phase-1),
59+
> - **A** 表示 Accept 阶段(phase-2),
60+
>
61+
> - `ballot_number` 表示投票轮次(也有些文章中使用 round number),
62+
> - `value` 表示在 Accept 阶段要提交的值(例如 `X``Y`)。但是他只对 A 表示的 accept 的 phase 有效
63+
>
64+
> 例如 `P1` 指的是使用 **Ballot=1** 进行 Prepare,`A1(X)` 则指的是使用 **Ballot=1** 接受值 **X**
65+
66+
67+
### 不同时间下使用同一个 Ballot number 重新运行 Paxos 的效果示例
68+
69+
在上面的例子中, 我们将分析在几个不同的时刻(t1, t2, t3, t4, t5)分别使用相同的 Ballot number = 1 重新运行 Paxos 时会发生什么情况, 并详细描述每种场景下的具体行为和结果.
70+
71+
#### 场景 1:t1 时刻 - 无历史值场景
72+
73+
在时间点 t1,如果我们再次用同样的 Ballot number = 1 发起 Paxos,它可以完成 phase-1, 因为 Acceptor 总是接受同样的 Ballot number 的请求(Prepare 或 Accept). 但这次完成(Prepare)之后,并不会看到任何已存在的值。而前面我们说过, 用相同的 Ballot number 重复运行时也不能 propose 任何值. “无值”情况下也就无法运行 phase-2(Accept 阶段),所以协议会结束,等同于没有做任何更改。
74+
75+
![](/post-res/paxos-same-ballot/9c06b2c3e814b3ae-paxos-same-ballot-1.x.svg)
76+
77+
#### 场景 2:t2 时刻 - 部分节点存在历史值
78+
79+
与 t1 情况相似。如果此时系统只观测到部分 Acceptor(Acceptor-1 和 2)(它并不知道已有 `A1(X)` 的存在),那么结果与 t1 一样,无法提交新的值。
80+
81+
![](/post-res/paxos-same-ballot/a17787ad9c3273b8-paxos-same-ballot-2.x.svg)
82+
83+
#### 场景 3:t3 时刻 - 多数派存在历史值(关键场景)
84+
85+
在 t3 时,如果发起同样的 Ballot number = 1 的 Paxos,但访问到包含 `A1(X)` 的多数派(例如 Acceptor-1、Acceptor-2),phase-1 结束后会“得知”之前已经有值 `X` 被 Accept 过。Paxos 允许**继续使用已存在的值**,所以这时可以在 phase-2 中,使用 `X` 来完成提交。也就是说,用**同一个** Ballot number = 1 依然可以帮助把 `X` 提交到 Acceptor 的一个 majority 上,从而达成共识完成提交。
86+
87+
示意图如下所示,`P1'` 表示重复使用同一个 Ballot=1 进行再次 Prepare 且成功完成;在 Acceptor-1 上看到了值 `X`,然后在 `t3'` 时刻完成 phase-2 Accept 阶段,成功将值 `X` 提交到多数派。这次 Paxos 的运行可以视为修复了之前 `A1(X)` 未完成的提交(该值仅写入了 Acceptor-1 但未达到多数派共识)。
88+
89+
![](/post-res/paxos-same-ballot/56f61d3f1f71e0fd-paxos-same-ballot-3.x.svg)
90+
91+
#### 场景 4:t4 时刻 - 更高 Ballot 存在(被拒绝场景)
92+
93+
如果在时间点 t4 用 Ballot number = 1 去 Prepare,因为这时系统中已经出现了更新的提案(使用 Ballot=2 的提案),那么 Acceptor-2 会拒绝较小的 Ballot number 1 的 Prepare。这意味着 Paxos 提议会在第一阶段就被否定,不能往下进行 phase-2 的 Accept 阶段。
94+
95+
![](/post-res/paxos-same-ballot/321be959bc05288a-paxos-same-ballot-4.x.svg)
96+
97+
#### 场景 5:t5 时刻及之后 - 完全被新 Ballot 覆盖
98+
99+
在 t5 或之后的任何时刻,系统上已经有一个 Quorum 接受了 Ballot=2(甚至更高的 ballot)的 phase-1 Prepare,这会导致 **Ballot=1** 的 Prepare 请求无处不被拒绝。无法完成任何提交。
100+
101+
---
102+
103+
## 总结
104+
105+
- **可以** 用重复的 Ballot number 来重新运行 Paxos 一次或多次,但前提是 **只能使用系统中已经存在、曾被 Accept 的值** ,不能引入任何新的值。
106+
- 用同一个 Ballot number 重复运行 Paxos 可以看做是一个 **修复** 动作,它能够将未完成的提交(未达到多数派)推进至完成状态,但绝对不会破坏已有的提交或引入不一致。
107+
- 一个直观理解:可以将 Paxos 中的 ballot number 视为"逻辑时间戳"。用同一个 Ballot number 重复运行 Paxos,相当于在同一个逻辑时间点上重放事件,但遵循"不能改变历史"的原则 — 如果在这个时间点上已经有了被接受的值,就必须沿用该值;如果没有,也不能随意引入新值。这种机制确保了即使在分布式环境中重复执行,系统状态也会收敛到一致。
108+
- 且一个推论是: 如果不 propose 新的值, 那么用任意 Ballot number 去运行一次 Paxos, 都不会破坏系统的共识!
109+
110+
如果你对 Paxos 或一致性协议还有其他问题,欢迎进一步探讨!
111+
112+
113+
114+
Reference:
115+
116+
- paxos的读者答疑 : [https://github.com/openacid/openacid.github.io/discussions/31](https://github.com/openacid/openacid.github.io/discussions/31)
117+
118+
- 可靠分布式系统-paxos的直观解释 : [https://zhuanlan.zhihu.com/p/145044486](https://zhuanlan.zhihu.com/p/145044486)
119+
120+
121+
[discuss-paxos]: https://github.com/openacid/openacid.github.io/discussions/31 paxos的读者答疑
122+
[post-paxos]: https://zhuanlan.zhihu.com/p/145044486 "可靠分布式系统-paxos的直观解释"
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
title: "Paxos 中 Ballot number 的重用机制"
3+
authors:
4+
- xp
5+
categories:
6+
- algo
7+
tags:
8+
- distributed
9+
- 分布式
10+
- paxos
11+
12+
refs:
13+
- x: y
14+
15+
disabled_article:
16+
image: /post-res/linearizable/linearizable-banner-big.png
17+
18+
mathjax: false
19+
toc: true
20+
toc_label: 本文目录
21+
toc_sticky: true
22+
excerpt: "本文探讨 Paxos 协议中 Ballot number 的重用机制,分析何时可重复使用,以及为何只能使用系统中已存在的值而非提议新值"
23+
---
24+
25+
![](./paxos-same-ballot-banner.webp)
26+
27+
欢迎各位读者探讨 Paxos 的深层机制。在我此前发表的 [Paxos 的直观解释][post-paxos] 文章后,它作为一个完整的介绍 Paxos 文章, 收到了不少读者提出的深入问题,这些问题我已在 [Paxos 的读者答疑][discuss-paxos] 中详细回应。考虑到分布式共识算法的复杂性,我决定通过一系列 回答 Paxos 的特定问题 形式的文章来作为补充,本文是该系列的第一篇。希望这些分析能帮助你解决疑惑,从不同角度理解 Paxos,帮助自己在分布式系统领域构建更加完整的思维框架。
28+
29+
## 问:是否可以用同样的 Ballot number(rnd)运行 Paxos?
30+
31+
简短回答是:可以,但**不能**在这种情况下提议任何新的值;也就是说,若要用相同的 Ballot number 来重新运行 Paxos,则只能使用系统中**已经存在的值**,继续进行 phase-2(Accept 阶段)以完成提交。原因在于,若此时选择新的值,很可能会导致与现有已被接受的值产生冲突,进而导致不一致(脑裂)的情况。
32+
33+
Paxos 算法要求当我们用相同的 Ballot number 发起提案时,其流程不能从头开始选新值,否则会破坏 Paxos 的一致性。相反,我们只能“沿用”系统已存在、且在之前某一轮中被 Accept 过的值来继续完成提交。
34+
35+
---
36+
37+
## 示例
38+
39+
让我们通过一个时间线示意图来说明不同的时间点和 Paxos 状态。下面的图表展示了一个分布式系统中三个 Acceptor 节点在不同时间点的状态变化:
40+
41+
我们假设系统中已经发生了以下事件:
42+
43+
1. 第一个 Proposer 使用 Ballot number = 1:
44+
45+
- 在 Acceptor-1 和 Acceptor-2 上完成了 phase-1(Prepare 阶段)
46+
- 然后在 Acceptor-1 上完成了 phase-2(Accept 阶段),写入了值 X
47+
48+
2. 第二个 Proposer 使用 Ballot number = 2:
49+
- 在 Acceptor-2 和 Acceptor-3 上完成了 phase-1(Prepare 阶段)
50+
- 然后在 Acceptor-1 和 Acceptor-2 上完成了 phase-2(Accept 阶段),提交了值 Y
51+
52+
![](paxos-same-ballot-0.x.svg)
53+
54+
> 图中的事件以这种格式表示: `<phase><ballot_number>(<value>)`:
55+
>
56+
> - `phase` 可以是 P 或 A:
57+
> - **P** 表示 Prepare 阶段(phase-1),
58+
> - **A** 表示 Accept 阶段(phase-2),
59+
> - `ballot_number` 表示投票轮次(也有些文章中使用 round number),
60+
> - `value` 表示在 Accept 阶段要提交的值(例如 `X``Y`)。但是他只对 A 表示的 accept 的 phase 有效
61+
>
62+
> 例如 `P1` 指的是使用 **Ballot=1** 进行 Prepare,`A1(X)` 则指的是使用 **Ballot=1** 接受值 **X**
63+
64+
### 不同时间下使用同一个 Ballot number 重新运行 Paxos 的效果示例
65+
66+
在上面的例子中, 我们将分析在几个不同的时刻(t1, t2, t3, t4, t5)分别使用相同的 Ballot number = 1 重新运行 Paxos 时会发生什么情况, 并详细描述每种场景下的具体行为和结果.
67+
68+
#### 场景 1:t1 时刻 - 无历史值场景
69+
70+
在时间点 t1,如果我们再次用同样的 Ballot number = 1 发起 Paxos,它可以完成 phase-1, 因为 Acceptor 总是接受同样的 Ballot number 的请求(Prepare 或 Accept). 但这次完成(Prepare)之后,并不会看到任何已存在的值。而前面我们说过, 用相同的 Ballot number 重复运行时也不能 propose 任何值. “无值”情况下也就无法运行 phase-2(Accept 阶段),所以协议会结束,等同于没有做任何更改。
71+
72+
![](paxos-same-ballot-1.x.svg)
73+
74+
#### 场景 2:t2 时刻 - 部分节点存在历史值
75+
76+
与 t1 情况相似。如果此时系统只观测到部分 Acceptor(Acceptor-1 和 2)(它并不知道已有 `A1(X)` 的存在),那么结果与 t1 一样,无法提交新的值。
77+
78+
![](paxos-same-ballot-2.x.svg)
79+
80+
#### 场景 3:t3 时刻 - 多数派存在历史值(关键场景)
81+
82+
在 t3 时,如果发起同样的 Ballot number = 1 的 Paxos,但访问到包含 `A1(X)` 的多数派(例如 Acceptor-1、Acceptor-2),phase-1 结束后会“得知”之前已经有值 `X` 被 Accept 过。Paxos 允许**继续使用已存在的值**,所以这时可以在 phase-2 中,使用 `X` 来完成提交。也就是说,用**同一个** Ballot number = 1 依然可以帮助把 `X` 提交到 Acceptor 的一个 majority 上,从而达成共识完成提交。
83+
84+
示意图如下所示,`P1'` 表示重复使用同一个 Ballot=1 进行再次 Prepare 且成功完成;在 Acceptor-1 上看到了值 `X`,然后在 `t3'` 时刻完成 phase-2 Accept 阶段,成功将值 `X` 提交到多数派。这次 Paxos 的运行可以视为修复了之前 `A1(X)` 未完成的提交(该值仅写入了 Acceptor-1 但未达到多数派共识)。
85+
86+
![](paxos-same-ballot-3.x.svg)
87+
88+
#### 场景 4:t4 时刻 - 更高 Ballot 存在(被拒绝场景)
89+
90+
如果在时间点 t4 用 Ballot number = 1 去 Prepare,因为这时系统中已经出现了更新的提案(使用 Ballot=2 的提案),那么 Acceptor-2 会拒绝较小的 Ballot number 1 的 Prepare。这意味着 Paxos 提议会在第一阶段就被否定,不能往下进行 phase-2 的 Accept 阶段。
91+
92+
![](paxos-same-ballot-4.x.svg)
93+
94+
#### 场景 5:t5 时刻及之后 - 完全被新 Ballot 覆盖
95+
96+
在 t5 或之后的任何时刻,系统上已经有一个 Quorum 接受了 Ballot=2(甚至更高的 ballot)的 phase-1 Prepare,这会导致 **Ballot=1** 的 Prepare 请求无处不被拒绝。无法完成任何提交。
97+
98+
---
99+
100+
## 总结
101+
102+
- **可以** 用重复的 Ballot number 来重新运行 Paxos 一次或多次,但前提是 **只能使用系统中已经存在、曾被 Accept 的值** ,不能引入任何新的值。
103+
- 用同一个 Ballot number 重复运行 Paxos 可以看做是一个 **修复** 动作,它能够将未完成的提交(未达到多数派)推进至完成状态,但绝对不会破坏已有的提交或引入不一致。
104+
- 一个直观理解:可以将 Paxos 中的 ballot number 视为"逻辑时间戳"。用同一个 Ballot number 重复运行 Paxos,相当于在同一个逻辑时间点上重放事件,但遵循"不能改变历史"的原则 — 如果在这个时间点上已经有了被接受的值,就必须沿用该值;如果没有,也不能随意引入新值。这种机制确保了即使在分布式环境中重复执行,系统状态也会收敛到一致。
105+
- 且一个推论是: 如果不 propose 新的值, 那么用任意 Ballot number 去运行一次 Paxos, 都不会破坏系统的共识!
106+
107+
如果你对 Paxos 或一致性协议还有其他问题,欢迎进一步探讨!
116 KB
Loading
308 KB
Loading

0 commit comments

Comments
 (0)