paxos"忽略"如果它与接受者发送的最高提案号不同步,请求更新值?

时间:2015-01-02 21:34:45

标签: distributed-computing paxos consensus

这里的标题可能会产生误导。我会尽力通过一个例子来解释我的怀疑。

我正在阅读来自wiki和其他来源的paxos算法。

1)想象一下客户要求更新值(下例中为X)的情况。 在一轮Paxos之后,选择值Vb,因为接受者对提议者的回复包含他们先前接受的提案编号和相应的值。在下面的情况中,三个接受者将(8,Va),(9,Vb),(7,Vc)发送给当前具有(10,X)的提议者。它选择(9,Vb),因为它是收到的最高提案号,并将值(10,Vb)广播给所有接受者以供接受。因此,处理整轮Paxos的初始值X从未更新过。那么在这种情况下更新到X的客户端事务是否失败?

此后接受者的最终状态是什么?他们都有(10,Vb)作为他们最高接受的提案编号和价值,因此是同步的吗?

Client   Proposer      Acceptor     Learner
   |         |          |  |  |       |  | --- First Request ---
   X-------->|          |  |  |       |  |  Request
   |         X--------->|->|->|       |  |  Prepare(10)
   |         |<---------X--X--X       |  |  Promise(10,{(8,Va),(9,Vb),(7,Vc)}
   |         X--------->|->|->|       |  |  Accept!(10,9,Vb)
   |         |<---------X--X--X------>|->|  Accepted(10,9,Vb)
   |<---------------------------------X--X  Response
   |         |          |  |  |       |  |

2)现在是一个更复杂的案例,其中提出了两个提案,但在尝试达成共识时的不同时间点。这是一种情况,其中区域A中的客户端C1正在修改某些数据X并且尚未达到共识,而区域B中的客户端C2正在修改相同的数据X。客户的请求之一被拒绝了吗?请注意C2发生的时间晚于C1,但尚未达成共识。如果遵循排序,则必须完成C1请求,接受共识,然后处理C2请求。根据我对this blog的理解,在这种情况下,选择了C1请求值。

那么C2请求被放弃了吗?这可能不是一个好的选择。

示例(来自this博客的版权):

enter image description here

在这种情况下,最终选择v=8,但V=5的请求是客户端请求的最新更新。为什么会这样?这可能会产生严重影响

感谢您的帮助和新年快乐!

1 个答案:

答案 0 :(得分:2)

为了解释这一点,我将给出一些上下文 - 对OSI协议栈的解释:

+------------------------+
|100. Your Application   |
#========================#
|8. Some state machine   |
|   or key/value store   |
+------------------------+
|7. Transaction log      |
+------------------------+
|6. Paxos                |
+------------------------+
|5. Some framing protocol|
+------------------------+
|4. TCP                  |
+------------------------+
|...                     |
+------------------------+

我见过的每一个paxos的严肃实现都使用了类似的模型(我见过许多严肃的实现)。也就是说,Paxos习惯于为状态机选择事务日志中的下一个条目(因为没有事务日志,数据库只是一个昂贵,缓慢,错误的缓存)。事务日志中的每个条目都有一个不同的Paxos实例;他们是完全独立的;如果系统的设计者非常聪明,Paxos实例甚至可以并行运行。

现在回答你的问题。

是的,你的第一个例子中的X失败了; 没有选择。失败应该返回到上层。这可能不一定意味着客户端失败(上述模型中的“您的应用程序”)。上层可以决定在事务日志中的后续条目中重试该值;或者他们可能只是将失败告诉客户。

在你的第二个例子中,其中一个请求最终必须被拒绝 - Paxos最多选择一个值。一旦选择了这个价值,就会保持选择。好像查克诺里斯选择了它。

但在第二个例子中看起来有点误解。首先启动哪个请求无关紧要。由于网络延迟和行星的对齐,第二个请求可能会在第一个请求中消失。

试试吧!用X,Y作为值; P1,P2为提名者;和A1,A2,A3作为受体:

  1. P1有X并发送Prepare(1)
  2. A1承诺为1并返回Accepted(0,_)
  3. A2承诺为1并返回Accepted(0,_)
  4. A3承诺为1并返回Accepted(0,_)
  5. P1仍有X并发送Accept(X,1)
  6. A1接受(X,1)
  7. P2有Y并发送Prepare(2)
  8. A2承诺2并返回Accepted(1,_)
    • 如您所见,A2已切换为不接受任何小于2的回合
  9. A2拒绝接受(X,1)
  10. A3承诺为2并返回Accepted(1,_)
  11. P2仍然有Y并发送Accept(Y,2)
  12. A2接受(Y,2)
  13. A3接受(Y,2)
    • 在被简单多数接受后,Y被选中了。无论任何提议者从现在开始做什么,总是会选择Y的值。
  14. 这实际上有点像你在第二个例子中的图片,但在这个例子中,网络偏爱第二个提议者。