[
https://issues.apache.org/jira/browse/CASSANDRA-5062?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13623839#comment-13623839
]
Sylvain Lebresne commented on CASSANDRA-5062:
---------------------------------------------
I haven't finished reviewing yet, but since I'll have to stop for today, here's
a bunch of early remarks.
In SP.preparePaxos, if we throw if {{!mostRecentCommitHasQuorum}} and since
PrepareCallback only waits for quorum response, I'm not sure later
replicasMissingMostRecentCommit can ever return anything other than empty, and
so I don't think we'll make progress. Furthermore, this means that that we'll
throw as soon as one node of the quorum first responder is not up to date,
which feels overly pessimistic.
So I think we should remove the mostRecentCommitHasQuorum check in
preparePaxos. But then, once we're received the prepare responses, we must
still ensure that a quorum of node do are on the MRC before moving on. So if
we do have missingMRC > 0, we would do the commit as is now, but then we would
re-start the prepare phase, re-asking for promisses. I think it is necessary to
re-prepare after the commits anyway because those commit will erase the paxos
state on the replica, so some of the promise we got are not valid anymore.
Another observation is that for the "repair commit" of the missingMRC, we can
(and should in fact) use the MRC as ballot. So we can optimize this
commit-and-re-prepare by sending just one special message (and only to the
missingMRC nodes).
bq. I agree, but on the other hand "just retry automatically" is something that
we avoid elsewhere for good reason (arbitrarily high latency with no visibility
to the client what is going on). I also considered introducing a new exception
type explaining the state, but throwing an exception when everything is working
fine is also not intuitive. So I think all the options kind of suck, but this
one sucks least IMO.
I disagree, I think that is the worst option tbh. That fact is, in almost all
cases, when a user want to CAS something, he will need a "real" true or false,
i.e. weither his CAS applies or not. Until then, an answer that says "sorry but
due to implementation details we haven't tested you CAS yet" is useless and the
user will retry 100% of the time. So retrying server side seems to me like the
right and the most efficient one. Throwing a specific exception could work I
suppose, but in the end it's just pushing the retry to client and since there
is nothing better to do than retry, this will increase latency and expose more
implementation details with no benefits that I can see. But returning false in
those case, mean that user can't do anything with the false value. That's
problematic because it means users will have to read to know if a false is a
real false, or just "the algorithm haven't win on the first round" (in which
case it still has to retry).
I do want to note that "the algorithm haven't win on the first round" can
happen for reasons completely orthogonal to the user CAS, if only because the
CAS is at the row level, and thus a CAS on a column c1 will "conflict" with one
on column c2 (and in fact, due to the implementation of PaxosState, there is
even some random cross-keys conflicts). I.e. a false currently does not even
guarantee that there was a real conflict between the user CAS and some other
CAS.
Also, I don't think this is at all comparable to other places when we don't
retry automatically so I don't buy that argument. Besides, CASSANDRA-4705 does
implement some form of automatic retry so there is prior art. But to be clear,
I do not suggest that we should retry indefinitely, we should absolutely take
the rpc timeout into account. I also think that "you CAS will take longer if
there is contention" is something pretty intuitive to understand (even if, as
said above, the contention can be slightly artificial in practice, due to
implementation details).
Also:
* Nit: In CFMetaData PaxosCF definition: "propsal" -> "proposal"
* When getting the prepare response, I think that as soon as we get a response
that is not promised, we can stop waiting for the other responses. I don't
think we win anything by waiting.
> Support CAS
> -----------
>
> Key: CASSANDRA-5062
> URL: https://issues.apache.org/jira/browse/CASSANDRA-5062
> Project: Cassandra
> Issue Type: New Feature
> Components: API, Core
> Reporter: Jonathan Ellis
> Fix For: 2.0
>
> Attachments: half-baked commit 1.jpg, half-baked commit 2.jpg,
> half-baked commit 3.jpg
>
>
> "Strong" consistency is not enough to prevent race conditions. The classic
> example is user account creation: we want to ensure usernames are unique, so
> we only want to signal account creation success if nobody else has created
> the account yet. But naive read-then-write allows clients to race and both
> think they have a green light to create.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira