Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixing lightweight transactions and normal writes in Cassandra

The Datastax documentation for lightweight transaction states:

"Lightweight transactions use a timestamping mechanism different than for normal operations and mixing LWTs and normal operations can result in errors. If lightweight transactions are used to write to a row within a partition, only lightweight transactions for both read and write operations should be used."

This is very vague (BTW what do they even mean by LWTs for read operations?).

Can someone with deeper knowledge of Cassandra internals elaborate on possible problems when mixing LWTs and normal writes?

My best guess is that there might be problems with concurrency (obviously). But I thought that if I (for example) insert a row using IF NOT EXISTS and if that was successful I later do UPDATE of the same partition, I will be fine. Am I wrong?

like image 259
st_patriick Avatar asked Apr 01 '16 14:04

st_patriick


People also ask

How does the syntax of Cassandra Query Language CQL support lightweight transactions?

Cassandra implements lightweight transactions by extending the Paxos consensus protocol, which is based on a quorum-based algorithm. Using this protocol, a distributed system can agree on proposed data additions/modifications without the need for a master database or two-phase commit.

Which is a Linearizable consistency level?

Linearizable consistency ensures transaction isolation at a level similar to the serializable level offered by RDBMSs. This type of transaction is known as compare and set (CAS); replica data is compared and any data found to be out of date is set to the most consistent value.


1 Answers

I agree that the documentation is not quite accurate on LWT constraints so let me clarify them:

  • If you use INSERT ... IF NOT EXISTS, all deletes should also use DELETE ... IF EXISTS
  • If you use UPDATE table SET column1=val1 WHERE <filters> IF column2=val2 then all updates/inserts on column1 & column2 should use LWT too. A common usage is when column1 and column2 are the same column.

Indeed LWT has 4 rounds:

  1. Propose a Paxos ballot (a timeuuid value) to all replicas of the given partition

  2. Check the condition (IF NOT EXISTS, IF EXISTS or IF col=val). If the condition is not met, fail here

  3. Else, wait for a QUORUM/LOCAL_QUORUM to accept the Paxos ballot

  4. Commit and apply the mutation (INSERT, UPDATE or DELETE)

Step b and c can be seen as a Compare And Swap.

The guarantees are that all writes using LWT are linearizable with respect to each others, so they are atomic and isolated on the partition.

Now if you use INSERT ... IF NOT EXISTS and then simple DELETE without LWT, you defeat the purpose of LWT and the LWT guarantees no longer apply.

Since the Compare phase (step 2) and the Commit phase (step 4) are in different steps, the only way to provide atomicity is to force others mutations to go throught LWT otherwise the logic is broken.

Same remark for the conditional updates with LWT.

like image 72
doanduyhai Avatar answered Sep 28 '22 01:09

doanduyhai