cassandra eu 2012 - cql: then, now and when by eric evans
DESCRIPTION
Eric Evans' talk about the latest on CQL given at Cassandra Europe on March 28 2012.TRANSCRIPT
CQL: Then, Now, and When
Eric [email protected]
Cassandra EuropeMarch 28, 2012
Wednesday, March 28, 12
• Query language for Apache Cassandra
• SQL for the most part
• An alternative query interface
• Available since Cassandra 0.8.0
Cassandra Query Language(aka CQL)
Wednesday, March 28, 12
Wednesday, March 28, 12
Wednesday, March 28, 12
Best Troll Ever?
Wednesday, March 28, 12
Not a troll at all, actually.
Wednesday, March 28, 12
• RPC-based query interface
• Low level; very little abstraction
• Implemented in Thrift
• Compact binary serialization
• Loads of supported languages
• Generated language code
Status Quo
Wednesday, March 28, 12
Unstable$@#*!
NOT AGAIN!
Relax
It’ll take you 5 minutes toupdate your code.
Wednesday, March 28, 12
Not User Friendly
Wednesday, March 28, 12
This cannot be unseen!// Your columnColumn col = new Column(ByteBuffer.wrap(“name”.getBytes()));col.setValue(ByteBuffer.wrap(“value”.getBytes()));col.setTimestamp(System.currentTimeMillis());
// Don’t askColumnOrSuperColumn cosc = new ColumnOrSuperColumn();cosc.setColumn(cosc);
// Hang on, here we go...Mutation mutation = new Mutation();mutation.setColumnOrSuperColumn(cosc);
List<Mutation> mutations = new ArrayList<Mutation>();mutations.add(mutation);
Map mutations_map = new HashMap<ByteBuffer, Map<String, List<Mutation>>>();Map cf_map = new Map<String, List<Mutation>>();cf_map.set(“Standard1”, mutations);mutations_map.put(ByteBuffer.wrap(“key”.getBytes()), cf_map);
cassandra.batch_mutate(mutations_map, consistency_level);
Wednesday, March 28, 12
This cannot be unseen!// Your columnColumn col = new Column(ByteBuffer.wrap(“name”.getBytes()));col.setValue(ByteBuffer.wrap(“value”.getBytes()));col.setTimestamp(System.currentTimeMillis());
// Don’t askColumnOrSuperColumn cosc = new ColumnOrSuperColumn();cosc.setColumn(cosc);
// Hang on, here we go...Mutation mutation = new Mutation();mutation.setColumnOrSuperColumn(cosc);
List<Mutation> mutations = new ArrayList<Mutation>();mutations.add(mutation);
Map mutations_map = new HashMap<ByteBuffer, Map<String, List<Mutation>>>();Map cf_map = new Map<String, List<Mutation>>();cf_map.set(“Standard1”, mutations);mutations_map.put(ByteBuffer.wrap(“key”.getBytes()), cf_map);
cassandra.batch_mutate(mutations_map, consistency_level);
Wednesday, March 28, 12
A query interface should be...
Simple
Intuitive
Invisible
Performant(?)
Wednesday, March 28, 12
Alternatives
• REST
• RPC (Thrift, Avro, Protobuf, etc)
• SQL (bahahaha)
• etc, etc
Wednesday, March 28, 12
REST
Pros Cons
• Ubiquitous
• Frequently requested
• Client uniformity
• Fails expectations
• Slow
Wednesday, March 28, 12
RPC
Pros Cons
• Easy to implement
• Performant
• Poor mental fit
• Heavy dependency
Wednesday, March 28, 12
SQL
Pros Cons
• Ubiquitous
• Widely known
• Excellent mental fit
• Client uniformity
• People whinging
• Security(?)
Wednesday, March 28, 12
SQL
Pros Cons
• Ubiquitous
• Widely known
• Excellent mental fit
• Client uniformity
• People whinging
• Security(?)
Wednesday, March 28, 12
Wednesday, March 28, 12
Hello...-- Create or updateINSERT INTO users (id, given, surname) VALUES (jericevans, Eric, Evans);
-- Create or updateUPDATE users SET given = Eric, surname = Evans WHERE id = jericevans;
SELECT surname, given FROM users WHERE id = jericevans;
Wednesday, March 28, 12
-- Adding an indexCREATE INDEX surnameidx ON users (surname);
SELECT id, given FROM users WHERE surname = Evans;
-- Limiting the number of rowsSELECT id, given FROM users WHERE surname = Evans LIMIT 1000;
...is it me you’re looking for?
Wednesday, March 28, 12
-- From column, to columnSELECT ‘2012-01-01’..’2012-03-28’ FROM NewsWHERE topic = cassandra
-- Last N columnsSELECT FIRST 10 REVERSED * FROM NewsWHERE topic = cassandra
Querying column ranges
Wednesday, March 28, 12
-- Get your count onUPDATE inventory SET apples = apples + 1 WHERE id = fruit;
UPDATE inventory SET carrots = carrots - 1 WHERE id = vegetable;
Counting
Wednesday, March 28, 12
BEGIN BATCH INSERT INTO msgs (owner, subject, body) VALUES(jericevans, ‘Hi’, ‘Howdy’); UPDATE subjects SET subject = now WHERE owner = jericevansAPPLY BATCH
Batching writes
Wednesday, March 28, 12
A query interface should be...
Simple
Intuitive
Invisible
Performant(?)
Wednesday, March 28, 12
Drivers• Not a replacement for high-level, idiomatic
libraries
• Avoids duplicating efforts, (error handling, pooling, etc)
• Consistently scoped, JDBC, etc
• Consistently hosted, licensed
• Discoverable
• More work needed...
Wednesday, March 28, 12
Current lineup
• JDBC (Java)
• DB-API 2 (Python)
• PDO (PHP)
• Ruby
• Node.JS
Wednesday, March 28, 12
And what about interfacestability?
Wednesday, March 28, 12
CQL 1.0
0.8.0
Wednesday, March 28, 12
CQL 2.0
0.8.01.0.0
• types made more consistent w/ SQL• count() returns rows, not columns
Wednesday, March 28, 12
Wednesday, March 28, 12
CQL 3.0
0.8.01.0.0
1.1.0
Wednesday, March 28, 12
CQL 3.0-- A materialized timeline of tweetsCREATE COLUMNFAMILY timeline ( username text, posted_at timestamp, body text, posted_by text, PRIMARY KEY (username, posted_at));
Wednesday, March 28, 12
CQL 3.0INSERT INTO timeline (username, posted_at, body, posted_by)VALUES (scotty, ‘2012-03-23 14:36’ ‘stupid klingons...’, jtkirk);
INSERT INTO timeline (username, posted_at, body, posted_by)VALUES (scotty, ‘2012-03-23 16:12’ ‘@jtkirk green?’, spock);
INSERT INTO timeline (username, posted_at, body, posted_by)VALUES (scotty, ‘2012-03-23 17:42’ ‘@spock yes, green’, jtkirk);
INSERT INTO timeline (username, posted_at, body, posted_by)VALUES (scotty, ‘2012-03-25 08:14’ ‘get off my lawn!’, bones);
Wednesday, March 28, 12
In Cassandra’s eyes eye
scotty(23/03 14:36, body):
stupid klingons...(23/03 14:36, posted_by):
jtkirk(23/03 16:12, body):
@jtkirk green?...
Wednesday, March 28, 12
-- Tweets in Scotty’s timeline, by dateSELECT * FROM timeline WHERE username = scotty AND posted_at > ‘2012-03-22’;
Wednesday, March 28, 12
Is it a row, or a table?Yes.
username posted_at body posted_by
scotty 23/03 14:36 stupid klingons... jtkirk
scotty 23/03 16:12 @jtkirk green? spock
scotty 23/03 17:42 @spock yes, green jtkirk
scotty 25/03 08:14 get off my lawn! bones
Wednesday, March 28, 12
Also...
• Column names are strictly UTF-8
• Column names are case-insensitive (unless quoted)
• Old slice notation is gone (<start>..<end>)
• Static column families are actually static (schema-enforced)
Wednesday, March 28, 12
$@#*!
NOT AGAIN!
Wednesday, March 28, 12
CQL 2.0 + 3.0 “beta”
0.8.01.0.0
1.1.0
You arehere
Wednesday, March 28, 12
Wednesday, March 28, 12
CQL 3.0
0.8.01.0.0
1.1.0
You will be here
1.2.0
Wednesday, March 28, 12
A query interface should be...
Simple
Intuitive
Invisible
Performant(?)
Wednesday, March 28, 12
Performanceinserts
Wednesday, March 28, 12
Performanceinserts w/ index
Wednesday, March 28, 12
Performancecounter increments
Wednesday, March 28, 12
Performancereads
Wednesday, March 28, 12
Wednesday, March 28, 12
A query interface should be...
Simple
Intuitive
Invisible
Performant
Wednesday, March 28, 12
Help Wanted
• Writing tests
• Documentation
• Feedback
• Drivers
Wednesday, March 28, 12
Wednesday, March 28, 12