[ 
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

Reply via email to