What?● Cassandra Query Language ● aka CQL ● aka /ˈsēkwəl/● Exactly like SQL (except where its not)● Introduced in Cassandra 0.8.0● Ready for production use
SQL? Almost.–- Inserts or updatesINSERT INTO Standard1 (KEY, col0, col1)VALUES (key, value0, value1) vs.–- Inserts or updatesUPDATE Standard1SET col0=value0, col1=value1 WHERE KEY=key
SQL? Almost.–- Get columns for a rowSELECT col0,col1 FROM Standard1 WHERE KEY=key–- Range of columns for a rowSELECT col0..colN FROM Standard1 WHERE KEY=key–- First 10 results from a range of columnsSELECT FIRST 10 col0..colN FROM Standard1 WHERE KEY=key–- Invert the sorting of resultsSELECT REVERSED col0..colN FROM Standard1 WHERE KEY=key
Why?
Interface Instability
(Un)ease of useColumn col = new Column(ByteBuffer.wrap(“name”.getBytes()));col.setValue(ByteBuffer.wrap(“value”.getBytes()));col.setTimestamp(System.currentTimeMillis());ColumnOrSuperColumn cosc = new ColumnOrSuperColumn();cosc.setColumn(col);Mutation mutation = new Mutation();Mutation.setColumnOrSuperColumn(cosc);List mutations = new ArrayList<Mutation>();mutations.add(mutation);Map mutations_map = new HashMap<ByteBuffer, Map<String, List<Mutation>>>();Map cf_map = new HashMap<String, List<Mutation>>();cf_map.set(“Standard1”, mutations);mutations.put(ByteBuffer.wrap(“key”.getBytes()), cf_map)
CQLINSERT INTO Standard1 (KEY, col0) VALUES (key, value0)
Why? How about...● Better stability guarantees● Easier to use (you already know it)● Better code readability / maintainability
Why? How about...● Better stability guarantees● Easier to use (you already know it)● Better code readability / maintainability● Irritates the NoSQL purists
Why? How about...● Better stability guarantees● Easier to use (you already know it)● Better code readability / maintainability● Irritates the NoSQL purists● (Still )irritates the SQL purists
Performance
Thrift RPCColumn col = new Column(ByteBuffer.wrap(“name”.getBytes()));col.setValue(ByteBuffer.wrap(“value”.getBytes()));col.setTimestamp(System.currentTimeMillis());ColumnOrSuperColumn cosc = new ColumnOrSuperColumn();cosc.setColumn(col);Mutation mutation = new Mutation();Mutation.setColumnOrSuperColumn(cosc);List mutations = new ArrayList<Mutation>();mutations.add(mutation);Map mutations_map = new HashMap<ByteBuffer, Map<String, List<Mutation>>>();Map cf_map = new HashMap<String, List<Mutation>>();cf_map.set(“Standard1”, mutations);mutations.put(ByteBuffer.wrap(“key”.getBytes()), cf_map)
Your query, its a graph
CQLINSERT INTO Standard1 (KEY, col0) VALUES (key, value0)
Hotspot Quoted string literalsUPDATE table SET name = value WHERE KEY = somekey
Hotspot Quoted string literalsUPDATE table SET name = value WHERE KEY = somekey
Hotspot Quoted string literalsUPDATE table SET name = value WHERE KEY = somekey● Anything that appears between quotes● Inlined Java constructs a StringBuilder to store the contents (slow not fast)● Incurred multiple times per statement
Hotspot MarshallingUPDATE table SET clear = abffaadd10 WHERE KEY = acfe12ff
Hotspot MarshallingUPDATE table SET clear = abffaadd10 WHERE KEY = acfe12ff ascii blob
Hotspot MarshallingUPDATE table SET clear = abffaadd10 WHERE KEY = acfe12ff ascii blob● Terms are marshalled to bytes by type● String.getBytes is slow (AsciiType)● Hex conversion is fast faster (BytesType)● Incurred multiple times per statement
Hotspot Copying / Conversionexecute_cql_query( ByteBuffer query, enum compression)● Query is binary to support compression (is it worth it?)● And dont forget the String → ByteBuffer conversion on the client-side● Incurred only once per statement!
Achtung! (These tests werent perfect)● Uneeded String → ByteBuffer → String● No query compression implemented● Co-located client and server
Drivers● Hosted on Apache Extras (Google Code)● Tagged cassandra and cql● Licensed using Apache License 2.0● Conforming to a standard for database connectivity (if applicable)● Coming soon, automated testing and acceptance criteria