why does paxos proposalId need to be unique

Viewed 1268

could anyone tell me why the proposal Id needs to be unique in Paxos? I think the reason why this the proposalId needs to be unique is that we need to use it to reject the old proposal and sort the max vote. So if we make the phase one: acceptor only accepts the proposal greater than the promisedId and it is incremental, it still can guarantee the consistency.

We assume proposer A makes a proposal (proposalId x, value y) to acceptors, then he got the majority reply with approval, another proposer B with the same proposal id(x) issue a proposal request, this proposer B will be rejected, right? And eventually, we still can reach consistency, right?

3 Answers

There is an additional detail that may be worth pointing out and is touched upon by @ideawu in the comment thread on @simbo1905's answer. My answer given below may have been more appropriate as a comment on that thread but I don't have the required Stack Overflow reputation to post comments.

In the classic description of Paxos (e.g. Paxos Made Simple), it is indeed required that ballot numbers/ids are unique to each proposer i.e. no two proposers can propose a value in the same ballot and each proposer cannot reuse ballot numbers for different proposals. My understanding is that this is simply to guarantee that at most one value is ever proposed for a given ballot.

As @simbo1905 points out, one way to ensure unique ballot numbers across proposals is by pre-allocating a disjoint set of ballot ids to each proposer. That is not the only way to achieve ballot uniqueness, though. If acceptors require that the ballot numbers of prepare (Phase 1a) messages they respond to are strictly greater than the ballot number of their latest promise, then this ensures that proposers will never conflict on a given ballot number, even if different proposers try to use the same ballot number for different proposals. The quorum overlap property ensures this, and it is a fact pointed out in Heidi Howard's technical report Distributed Consensus Revised, where, in Section 3.9, she notes (using the term "epoch" instead of "ballot"):

It has long been known that Classic Paxos does not require that epochs are unique if acceptors require that a proposer’s epochs be strictly greater than the last promised proposal. This means that at most one proposer will reach phase two for a given epoch, since reaching phase two requires a proposer to have already reached majority agreement for phase one, thus guaranteeing uniqueness.

This supports the idea proposed in the comment above by @ideawu. So, if we ensure this "strictly greater than" behavior for acceptors, ballot number uniqueness shouldn't be externally required i.e. the protocol will enforce it automatically.

Alternatively, if we allow acceptors to respond to prepare messages that have ballot numbers greater than or equal to their latest promised ballot, then uniqueness of ballot numbers for proposals is, indeed, not automatically guaranteed. This fact is, presumably, the original motivation for Paxos requiring global ballot number uniqueness. We can fix this, however, by modifying the protocol slightly. We can add an extra piece of state on each acceptor that stores the identity of the proposer it responded to for its latest promised ballot. If it receives a prepare request from a different proposer for the same ballot, it can reject it. Howard gives a precise example of this in the referenced paper section. This is also the approach taken, for example, in the Raft consensus protocol, where it is implemented using the votedFor variable maintained on each server.

You can see a more formal demonstration of the concepts outlined above in this TLA+ specification, which extends one of Lamport's Paxos specifications to add an explicit notion of proposers. Note that nothing in the specification ensures that different proposers choose ballot numbers from disjoint sets. Here is an error trace (counterexample) that is produced when using the "greater than or equal to" condition and model checking the safety property that only a single value is chosen. When using the "strictly greater than" condition, the model checker terminated without error on a model where the Proposer set is defined as {p1,p2} (two proposers) and Nat (which determines the set of possible ballots) is overridden to be {1,2,3}. That is by no means a proof of safety, but it gives a bit of extra confidence that the reasoning is correct.

The accepted answer is actually incorrect - there is no requirement for a round number to be unique across nodes. The only requirement is "Each proposal is uniquely numbered for a given Proposer" and "The number n must be greater than any number used in any of the previous Prepare messages by this Proposer." - these are quotes from wikipedia - in spirit, this is the same requirement.

Let me explain why there is no global uniqueness requirement by an example (and address this argument from the originally accepted answer "It[Leader] will then get back responses that are different values for the same number.").

Let's say we have a system with two proposers and three accepters(and few learners):

  1. Both proposers sent PREPARE(1) - same number - to all acceptors.
  2. Based on paxos rules, only one of proposers will get the majority of PROMISE messages - this is based on the rule that acceptor promises if PREPARE has number strongly greater than any other previously seen by the acceptor.
  3. Now we are in a state where one proposer has two (or three) PROMISES for N=1 and the other proposer has one (or zero) PROMISE with N = 1.
  4. Only first proposer may issue ACCEPT(1, V) as it got majority. The other proposer does not have the majority of PROMISES and has to retry with a larger N.
  5. After the other proposer retries, it will use N larger than any other it saw before - hence it will try with N=2
  6. From now on, it's all works the same way - proposer PREPARES and if get majority of PROMISE for its N, then the proposer issues ACCEPT(N, VALUE_ACCORDING_TO_PROTOCOL)

The key understanding for paxos is there is no way to have two ACCEPT(N, V) messages being sent where same N will have different V, hence there is no issue that two proposer use the same N.

As for initiating every node with some unique ID - that's ok; will it improve the performance - it's a big question and I haven't see a formal proof for that yet.

Related