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);
}