4. CAS: When
SELECT * FROM users
WHERE username = ’jbellis’
[empty resultset]
INSERT INTO users (...)
VALUES (’jbellis’, ...)
Session 1
SELECT * FROM users
WHERE username = ’jbellis’
[empty resultset]
INSERT INTO users (...)
VALUES (’jbellis’, ...)
Session 2
When you absolutely require linearizable consistency
(think - safely creating a user with a unique username)
5. CAS: How
• Based on the Paxos consensus protocol
• Paxos state is durable
• All operations are quorum-based
• Immediate consistency with no leader election or failover
• Relatively expensive - requires 4 round trips vs. 1 for regular
updates. Use only in the parts of your application where it’s really
needed
• ConsistencyLevel.SERIAL
6. CAS: CQL3
// Insert a user with a unique username
INSERT INTO USERS (username, email, name)
VALUES ('jbellis', 'jbellis@datastax.com', 'Jonathan Ellis')
IF NOT EXISTS
// Reset user’s password transactionally
UPDATE users
SET reset_token = null AND password = ‘newpassword’
IF reset_token = ‘some-generated-reset-token’
7. CAS: Further Reading
• http://www.datastax.com/dev/blog/lightweight-transactions-in-
cassandra-2-0
• Paxos Made Simple: http://www.cs.utexas.edu/users/lorenzo/
corsi/cs380d/past/03F/notes/paxos-simple.pdf
• http://the-paper-trail.org/blog/consensus-protocols-paxos/
9. Eager Retries
• New per-table setting: speculative_retry (NONE|Xpercentile|Xms|
ALWAYS)
• Will issue extra read commands to other replicas behind the scenes
if the current one(s) isn’t (aren’t) responding within the configured
milliseconds/percentile
• Minimizes read latencies, reduces the occurrence of read timeouts
if one or several of the replicas crash or become overloaded
• https://issues.apache.org/jira/browse/CASSANDRA-4705
11. Native Proto V2
• Paging (cursors)
• Batching prepared statements
• Parametrized statements without the explicit prepare phase
12. Native Proto V2: Paging
Statement stmt = new SimpleStatement("SELECT * FROM images");
stmt.setFetchSize(100);
ResultSet result = session.execute(stmt);
// Iterate over the ResultSet here (will transparently fetch new pages)
for (Row row : result) {
handleRow(row);
}
14. Native Proto V2: Paging
• Paging state = last seen partition key + last seen cell name +
remaining, opaque
• https://issues.apache.org/jira/browse/CASSANDRA-4415
16. Native Proto V2: Batching Prepared
• Variable statements count
• Can mix prepared and non-prepared statements in a single batch
• Fast
• https://issues.apache.org/jira/browse/CASSANDRA-4693
18. Native Proto V2: Parametrized Queries
• One-off prepare+execute w/out the explicit prepare phase
• No need to escape the values
• No need to serialize non-string data as strings
• Esp. handy for blobs
• https://issues.apache.org/jira/browse/CASSANDRA-5349
19. (Some) Notable Internal Improvements
• Rewritten Streaming (CASSANDRA-5286)
• Tracking max/min values on clustering columns for optimized
reads (CASSANDRA-5514)
• Single pass compaction roughly doubling compaction speed for
large partitions (CASSANDRA-4180)
• Size-tiered compaction for LCS L0 when it gets behind
(CASSANDRA-5371)
• Default LCS sstable size increased to 160MB (from 5MB)
(CASSANDRA-5727)
• http://www.datastax.com/dev/blog/whats-under-the-hood-in-
cassandra-2-0
21. New CQL3 Features
• ALTER TABLE DROP
• 2i on PRIMARY KEY columns
• Preparing TIMESTAMP, TTL and LIMIT
• Listing partition keys
22. CQL3: ALTER TABLE DROP
ALTER TABLE <table> DROP <column>;
// Immediately removes the column from table’s metadata
// Lazily gets rid of the data during compaction
23. CQL3: 2i on PRIMARY KEY columns
CREATE TABLE timeline (
event_id uuid,
week_in_year int,
created_at timeuuid,
content blob,
PRIMARY KEY ((event_id, week_in_year), created_at)
);
-- Invalid in C* 1.2, valid now in C* 2.0:
CREATE INDEX ON demo (event_id);
CREATE INDEX ON demo (week_in_year);
CREATE INDEX ON demo (created_at);
24. CQL3: Preparing Query Options
// Preparing LIMIT
session.prepare("SELECT * FROM foo LIMIT ?");
// Preparing TIMESTAMP and TTL
session.prepare("UPDATE foo USING TIMESTAMP ? AND TTL ? SET bar = ? WHERE baz = ?");
27. Triggers Interface
public interface ITrigger
{
/**
* Called exactly once per CF update, returned mutations are atomically
updated.
*
* @param key - Row Key for the update.
* @param update - Update received for the CF
* @return modifications to be applied, null if no action to be performed.
*/
public Collection<RowMutation> augment(ByteBuffer key, ColumnFamily update);
}