SlideShare a Scribd company logo
1 of 79
Download to read offline
CQL Under the Hood 
Robbie Strickland
whoami? 
Robbie Strickland 
Software Development Manager 
@rs_atl
Target Audience 
• Veterans who don’t use or don’t understand CQL 
• Newcomers who only know CQL, but don’t know what’s happening 
underneath
Definitions 
• Thrift: legacy RPC protocol + code generation tool 
• batch_mutate, get_range_slices, multiget_slice, etc. 
• Deprecated in favor of native protocol 
• Native protocol: replacement for Thrift 
• Only works with CQL
Definitions 
• Storage rows: keys + columns as stored on disk 
• CQL rows: abstraction layer on top of storage rows 
• Not usually a direct mapping to storage rows 
• Make use of predefined schema 
• Data still sparse – no space used for null columns
In the Old Days … 
• Lots of clients with lots of APIs 
• No common language for describing schemas or queries 
• Steep learning curve
In the Old Days … 
• No cursors, so entire result set must fit in memory on client and server 
• Hard to add new features 
• Lag time between release of new features and client library adoption
Solution: CQL? 
SELECT * FROM mytable WHERE mykey = ‘foo’; 
WAT???!!!
Solution: CQL? 
Veterans 
“What happened to 
my NoSQL??!!”
Solution: CQL? 
Newbies 
“Sweet, SQL! I don’t 
have to learn 
anything new!”
Reality 
• Don’t panic 
• Thrift problems solved 
• You didn’t lose anything 
• Underlying storage is 
unchanged 
• Don’t get lazy 
• CQL is not SQL 
• You need to know what 
you’re doing 
• No, you can’t just index 
everything
Simple CQL 
CREATE TABLE Books (! 
title varchar,! 
author varchar,! 
year int,! 
PRIMARY KEY (title)! 
SELECT * FROM Books;! 
);! 
! 
INSERT INTO Books (title, author, year) ! 
VALUES ('Patriot Games', 'Tom Clancy', 1987);! 
INSERT INTO Books (title, author, year) ! 
VALUES ('Without Remorse', 'Tom Clancy', 1993);! 
! 
title | author | year! 
-----------------+------------+------! 
Without Remorse | Tom Clancy | 1993! 
Patriot Games | Tom Clancy | 1987!
Storage Rows 
[default@unknown] create keyspace Library;! 
[default@unknown] use Library;! 
[default@Library] create column family Books! 
...! with key_validation_class=UTF8Type! 
...! and comparator=UTF8Type! 
...! and default_validation_class=UTF8Type;! 
[default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! 
[default@Library] set Books['Patriot Games']['year'] = '1987';! 
[default@Library] list Books;! 
! 
RowKey: Patriot Games! 
=> (name=author, value=Tom Clancy, timestamp=1393102991499000)! 
=> (name=year, value=1987, timestamp=1393103015955000)!
Storage Rows 
[default@unknown] create keyspace Library;! 
[default@unknown] use Library;! 
[default@Library] create column family Books! 
...! with key_validation_class=UTF8Type! 
...! and comparator=UTF8Type! 
...! and default_validation_class=UTF8Type;! 
[default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! 
[default@Library] set Books['Patriot Games']['year'] = '1987';! 
[default@Library] list Books;! 
! 
RowKey: Patriot Games! 
=> (name=author, value=Tom Clancy, timestamp=1393102991499000)! 
=> (name=year, value=1987, timestamp=1393103015955000)! 
Random hash (no ordering)
Storage Rows 
[default@unknown] create keyspace Library;! 
[default@unknown] use Library;! 
[default@Library] create column family Books! 
...! with key_validation_class=UTF8Type! 
...! and comparator=UTF8Type! 
...! and default_validation_class=UTF8Type;! 
[default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! 
[default@Library] set Books['Patriot Games']['year'] = '1987';! 
[default@Library] list Books;! 
! 
Ordered by name 
RowKey: Patriot Games! 
=> (name=author, value=Tom Clancy, timestamp=1393102991499000)! 
=> (name=year, value=1987, timestamp=1393103015955000)!
Compound Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
);! 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Compound Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
);! 
Partition key (row key) 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Compound Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
);! 
Clustering columns 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
== Composite Columns 
[default@Library] list authors;! 
! 
Partition key (row key) 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)!
== Composite Columns 
[default@Library] list authors;! 
! 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
Clustering columns
== Composite Columns 
[default@Library] list authors;! 
! 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
Ordered by name
Reversing Sort Order 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
) WITH CLUSTERING ORDER BY (year DESC);! 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam!
Reversing Sort Order 
[default@Library] list authors;! 
! 
RowKey: Tom Clancy! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Composite Partition Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY ((name, year), title)! 
);! 
Composite partition key 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Composite Partition Key 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY ((name, year), title)! 
);! 
Clustering column 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
== Composite Keys 
[default@Library] list authors;! 
! 
Partition keys (row key) 
RowKey: Tom Clancy:1993! 
=> (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! 
=> (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! 
-------------------! 
RowKey: Tom Clancy:1987! 
=> (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! 
=> (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)!
== Composite Keys 
[default@Library] list authors;! 
! 
RowKey: Tom Clancy:1993! 
=> (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! 
=> (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! 
-------------------! 
RowKey: Tom Clancy:1987! 
=> (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! 
=> (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)! 
Clustering column
Why This Matters 
• Queries must respect underlying storage, else they will either be slow or 
impossible 
• You have to know your partition key at query time 
• If you want fast multi-record queries, select a range, in storage order 
• With clustering columns, order matters
Example 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
) WITH CLUSTERING ORDER BY (year DESC);!
Example 
name | year | title | isbn | publisher! 
------------+------+-----------------------------+---------------+-----------! 
Tom Clancy | 1996 | Executive Orders | 0-399-13825-0 | Putnam! 
Tom Clancy | 1994 | Debt of Honor | 0-399-13826-1 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13927-0 | Putnam! 
Tom Clancy | 1991 | The Sum of All Fears | 0-399-12341-6 | Putnam! 
Tom Clancy | 1989 | Clear and Present Danger | 0-399-13341-1 | Putnam! 
Tom Clancy | 1988 | The Cardinal of the Kremlin | 0-399-13241-4 | Putnam! 
Tom Clancy | 1987 | Patriot Games | 0-399-13231-4 | Putnam! 
Tom Clancy | 1986 | Red Storm Rising | 0-399-13230-2 | Putnam! 
Tom Clancy | 1984 | The Hunt for Red October | 0-399-13251-1 | Putnam! 
!!
Query by Key 
SELECT * FROM authors 
WHERE name = ‘Tom Clancy’ 
(CL = QUORUM) 
RF = 3 
Tom 
Clancy 
Tom 
Clancy 
Tom 
Clancy
Query by Key 
Find partition key 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Query by Key 
Scan all columns in order 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Range Query 
SELECT * FROM authors 
WHERE name = ‘Tom Clancy’ 
AND year >= 1990 
(CL = QUORUM) 
Tom 
Clancy 
Tom 
Clancy 
Tom 
Clancy
Range Query 
Find partition key 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Range Query 
Scan until < 1990 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Querying Tail of Range 
SELECT * FROM authors 
WHERE name = ‘Tom Clancy’ 
AND year <= 1990 
(CL = QUORUM) 
Tom 
Clancy 
Tom 
Clancy 
Tom 
Clancy
Querying Tail of Range 
Find partition key 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Querying Tail of Range 
Scan all, 
then filter <= 1990 
RowKey: Tom Clancy! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! 
...! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
Multiple Keys 
DK 
DK 
MG 
MG 
TC 
MG 
TC 
TC 
DK 
SELECT * FROM authors 
WHERE name IN 
(‘Tom Clancy’, 
‘Dean Koontz’, 
‘Malcolm Gladwell’) 
(CL = QUORUM)
Lessons Learned 
• Sequential == fast 
• Query by key / clustering column (range) == Sequential 
• Multi-key query often == lots of nodes 
• Write in the intended read order
Collections 
• Sets: unordered, unique 
• Lists: ordered, allow duplicates 
• Maps: key/value pairs – can be a good substitute for dynamic columns 
• Max 64k items, 64k per item 
• Always returns entire collection
Sets 
CREATE TABLE authors (! 
!name text,! 
!books set<text>,! 
PRIMARY KEY (name)! 
name | books! 
------------+--------------------------------------! 
Tom Clancy | {'Patriot Games', 'Without Remorse'}! 
);! 
! 
INSERT INTO authors (name, books) ! 
VALUES ('Tom Clancy', {'Without Remorse', 'Patriot Games'});!
Sets 
RowKey: Tom Clancy! 
=> (name=books:50617472696f742047616d6573, value=, ...)! 
=> (name=books:576974686f75742052656d6f727365, value=, ...)! 
Set name 
Set item 
Empty value
Lists 
CREATE TABLE authors (! 
!name text,! 
!books list<text>,! 
PRIMARY KEY (name)! 
name | books! 
------------+--------------------------------------! 
Tom Clancy | ['Without Remorse’, 'Patriot Games']! 
);! 
! 
INSERT INTO authors (name, books) ! 
VALUES ('Tom Clancy', ['Without Remorse', 'Patriot Games']);!
Lists 
RowKey: Tom Clancy! 
=> (name=books:d36de8b0305011e4a0dddbbeade718be, value=576974686f75742052656d6f727365, ...)! 
=> (name=books:d36de8b1305011e4a0dddbbeade718be, value=50617472696f742047616d6573, ...)! 
List name 
Ordering ID 
List item
Maps 
CREATE TABLE authors (! 
!name text,! 
!books map<text, int>,! 
PRIMARY KEY (name)! 
name | books! 
------------+-------------------------------------------------! 
Tom Clancy | {'Patriot Games': 1987, 'Without Remorse': 1993}! 
);! 
! 
INSERT INTO authors (name, books) ! 
VALUES ('Tom Clancy', ! 
{'Without Remorse' : 1993, 'Patriot Games' : 1987});!
Maps 
RowKey: Tom Clancy! 
=> (name=books:50617472696f742047616d6573, value=000007c3, ...)! 
=> (name=books:576974686f75742052656d6f727365, value=000007c9, ...)! 
Map name 
Map key 
Map value
Indices 
CREATE INDEX author_publisher! 
ON author (publisher);!
Indices 
• Allow query by value in certain cases 
• Partitioned based on row key of indexed table 
• Are updated atomically along with the data being inserted 
• Must be low cardinality, or it won’t scale well (to large cluster sizes) 
• But not too low, or it’s sort of pointless
Index Distribution 
Node 1 
Authors 
“Tom Clancy” : “Putnam”! 
“Mark Twain” : “Putnam”! 
! 
Index 
“Putnam” : “Tom Clancy”! 
“Putnam” : “Mark Twain”! 
! 
Node 2 
Authors 
“Mark Twain” : “Putnam”! 
“Dan Brown” : “Putnam”! 
! 
Index 
“Putnam” : “Mark Twain”! 
“Putnam” : “Dan Brown”! 
! 
Node 3 
Authors 
“Dan Brown” : “Putnam” 
“Tom Clancy” : “Putnam”! 
! 
Index 
“Putnam” : “Dan Brown”! 
“Putnam” : “Tom Clancy”! 
! 
Index key == indexed column value
Index Distribution 
Node 1 
Authors 
“Tom Clancy” : “Putnam”! 
“Mark Twain” : “Putnam”! 
! 
Index 
“Putnam” : “Tom Clancy”! 
“Putnam” : “Mark Twain”! 
! 
Node 2 
Authors 
“Mark Twain” : “Putnam”! 
“Dan Brown” : “Putnam”! 
! 
Index 
“Putnam” : “Mark Twain”! 
“Putnam” : “Dan Brown”! 
! 
Node 3 
Authors 
“Dan Brown” : “Putnam” 
“Tom Clancy” : “Putnam”! 
! 
Index 
“Putnam” : “Dan Brown”! 
“Putnam” : “Tom Clancy”! 
! 
… but node distribution based on original table key
Querying by Value 
pub idx 
pub idx 
pub idx pub idx 
pub idx 
pub idx 
SELECT * FROM authors 
WHERE publisher = ‘Putnam’ 
(CL = QUORUM)
Deletes 
DELETE FROM authors WHERE name = 'Tom Clancy';! 
! 
INSERT INTO authors (title, name) 
VALUES ('Patriot Games', 'Tom Clancy') 
USING TTL 86400;! 
! 
INSERT INTO authors (title, name, year) 
VALUES ('Patriot Games', 'Tom Clancy', null);! 
! 
UPDATE authors SET publisher = null 
WHERE name = 'Tom Clancy';! 
!
Deletes 
• Log-structured storage, so writes are immutable 
• Deletes create tombstones, one for each deleted column 
• Cassandra must read the tombstones to make sure it doesn’t revive 
deleted data 
• Lots of deletes is an anti-pattern
Missing Columns 
INSERT INTO authors (title, name, year)! 
VALUES ('Without Remorse', 'Tom Clancy', 1993);! 
! 
name | year | title | isbn | publisher! 
------------+------+-----------------+------+-----------! 
Tom Clancy | 1993 | Without Remorse | null | null! 
! 
RowKey: Tom Clancy! 
=> (name=1993:Without Remorse:, value=, timestamp=1409936754170000)!
Missing Columns 
activity | timestamp | source | source_elapsed! 
---------------------------------------------------------------------------+--------------+-----------+----------------! 
execute_cql3_query | 11:51:55,975 | 127.0.0.1 | 0! 
Parsing select * from authors where name = 'Tom Clancy' LIMIT 10000; | 11:51:55,975 | 127.0.0.1 | 47! 
Preparing statement | 11:51:55,975 | 127.0.0.1 | 105! 
Executing single-partition query on authors | 11:51:55,975 | 127.0.0.1 | 307! 
Acquiring sstable references | 11:51:55,975 | 127.0.0.1 | 315! 
Merging memtable tombstones | 11:51:55,975 | 127.0.0.1 | 328! 
Skipped 0/0 non-slice-intersecting sstables, included 0 due to tombstones | 11:51:55,975 | 127.0.0.1 | 374! 
Merging data from memtables and 0 sstables | 11:51:55,975 | 127.0.0.1 | 383! 
Read 1 live and 0 tombstoned cells | 11:51:55,975 | 127.0.0.1 | 420! 
Request complete | 11:51:55,975 | 127.0.0.1 | 585! 
Only 1 read required
Null Columns 
INSERT INTO authors (title, name, year, isbn, publisher) 
VALUES ('Without Remorse', 'Tom Clancy', 1993, null, null);! 
! 
name | year | title | isbn | publisher! 
------------+------+-----------------+------+-----------! 
Tom Clancy | 1993 | Without Remorse | null | null!
Null Columns 
activity | timestamp | source | source_elapsed! 
---------------------------------------------------------------------------+--------------+-----------+----------------! 
execute_cql3_query | 11:57:31,623 | 127.0.0.1 | 0! 
Parsing select * from authors where name = 'Tom Clancy' LIMIT 10000; | 11:57:31,623 | 127.0.0.1 | 41! 
Preparing statement | 11:57:31,623 | 127.0.0.1 | 101! 
Executing single-partition query on authors | 11:57:31,623 | 127.0.0.1 | 532! 
Acquiring sstable references | 11:57:31,623 | 127.0.0.1 | 544! 
Merging memtable tombstones | 11:57:31,623 | 127.0.0.1 | 571! 
Skipped 0/0 non-slice-intersecting sstables, included 0 due to tombstones | 11:57:31,623 | 127.0.0.1 | 596! 
Merging data from memtables and 0 sstables | 11:57:31,623 | 127.0.0.1 | 605! 
Read 1 live and 2 tombstoned cells | 11:57:31,624 | 127.0.0.1 | 669! 
Request complete | 11:57:31,623 | 127.0.0.1 | 777! 
3 reads required!
Why Queries Fail 
SELECT name FROM authors WHERE title = 'Patriot Games';! 
Bad Request: PRIMARY KEY part title cannot be 
restricted (preceding part year is either not 
restricted or by a non-EQ relation)!
Why Queries Fail 
• Failure to provide the full partition key 
• Querying by value without an index 
• Misunderstanding clustering columns
Missing Key Parts 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY ((name, year), title)! 
);! 
! 
! 
SELECT name FROM authors WHERE title
Missing Key Parts 
[default@Library] list authors;! 
! 
Partition keys (row key) 
RowKey: Tom Clancy:1993! 
=> (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! 
=> (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! 
-------------------! 
RowKey: Tom Clancy:1987! 
=> (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! 
=> (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)!
Missing Key Parts 
SELECT * FROM authors WHERE name = 'Tom Clancy’;! 
Bad Request: Partition key part year must be restricted 
since preceding part is!
Missing Key Parts 
SELECT * FROM authors WHERE year = 1987;! 
Bad Request: partition key part year cannot be 
restricted (preceding part name is either not 
restricted or by a non-EQ relation)!
Missing Key Parts 
SELECT * FROM authors WHERE year >= 1987;! 
Bad Request: partition key part year cannot be 
restricted (preceding part name is either not 
restricted or by a non-EQ relation)!
Missing Key Parts 
SELECT * FROM authors ! 
WHERE name = 'Tom Clancy' and year >= 1987;! 
! 
Bad Request: Only EQ and IN relation are supported on 
the partition key (unless you use the token() function)!
Querying by Value 
SELECT * FROM authors WHERE isbn = '0-399-13241-4';! 
Bad Request: No indexed columns present in by-columns 
clause with Equal operator!
Querying Clustering Columns 
CREATE TABLE authors (! 
!name text,! 
!year int,! 
!title text,! 
!isbn text,! 
!publisher text,! 
!PRIMARY KEY (name, year, title)! 
);! 
! 
! 
SELECT name FROM authors WHERE
Querying Clustering Columns 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
Clustering columns
Querying Clustering Columns 
SELECT * FROM authors ! 
WHERE name = 'Tom Clancy’! 
AND year = 1993;! 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Querying Clustering Columns 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)!
Querying Clustering Columns 
SELECT * FROM authors ! 
WHERE name = 'Tom Clancy’! 
AND year <= 1993;! 
name | year | title | isbn | publisher! 
------------+------+-----------------+---------------+-----------! 
Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! 
Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
Querying Clustering Columns 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)!
Querying Clustering Columns 
SELECT * FROM authors ! 
WHERE name = 'Tom Clancy’! 
AND title = 'Patriot Games';! 
! 
Bad Request: PRIMARY KEY part title cannot be restricted 
(preceding part year is either not restricted or by a 
non-EQ relation)! 
!!
Querying Clustering Columns 
RowKey: Tom Clancy! 
=> (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! 
=> (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! 
=> (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! 
=> (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! 
=> (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! 
?
Summary 
• Stop using Thrift; use CQL instead 
• … but know what your model/query is doing
Thanks! 
Robbie Strickland 
Software Development Manager 
@rs_atl
CQL Under the Hood

More Related Content

What's hot

Introduction to Cassandra Architecture
Introduction to Cassandra ArchitectureIntroduction to Cassandra Architecture
Introduction to Cassandra Architecturenickmbailey
 
Bulk Loading Data into Cassandra
Bulk Loading Data into CassandraBulk Loading Data into Cassandra
Bulk Loading Data into CassandraDataStax
 
Introduction to CQL and Data Modeling with Apache Cassandra
Introduction to CQL and Data Modeling with Apache CassandraIntroduction to CQL and Data Modeling with Apache Cassandra
Introduction to CQL and Data Modeling with Apache CassandraJohnny Miller
 
Storing time series data with Apache Cassandra
Storing time series data with Apache CassandraStoring time series data with Apache Cassandra
Storing time series data with Apache CassandraPatrick McFadin
 
Cassandra Data Modeling - Practical Considerations @ Netflix
Cassandra Data Modeling - Practical Considerations @ NetflixCassandra Data Modeling - Practical Considerations @ Netflix
Cassandra Data Modeling - Practical Considerations @ Netflixnkorla1share
 
Introduction to Cassandra Basics
Introduction to Cassandra BasicsIntroduction to Cassandra Basics
Introduction to Cassandra Basicsnickmbailey
 
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016DataStax
 
Understanding Data Partitioning and Replication in Apache Cassandra
Understanding Data Partitioning and Replication in Apache CassandraUnderstanding Data Partitioning and Replication in Apache Cassandra
Understanding Data Partitioning and Replication in Apache CassandraDataStax
 
Introduction to NoSQL Databases
Introduction to NoSQL DatabasesIntroduction to NoSQL Databases
Introduction to NoSQL DatabasesDerek Stainer
 
[TDC2016] Apache Cassandra Estratégias de Modelagem de Dados
[TDC2016]  Apache Cassandra Estratégias de Modelagem de Dados[TDC2016]  Apache Cassandra Estratégias de Modelagem de Dados
[TDC2016] Apache Cassandra Estratégias de Modelagem de DadosEiti Kimura
 
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...DataStax
 
Deep Dive into Cassandra
Deep Dive into CassandraDeep Dive into Cassandra
Deep Dive into CassandraBrent Theisen
 
Cassandra Data Modelling
Cassandra Data ModellingCassandra Data Modelling
Cassandra Data ModellingKnoldus Inc.
 
Cassandra concepts, patterns and anti-patterns
Cassandra concepts, patterns and anti-patternsCassandra concepts, patterns and anti-patterns
Cassandra concepts, patterns and anti-patternsDave Gardner
 
Introduction to NOSQL databases
Introduction to NOSQL databasesIntroduction to NOSQL databases
Introduction to NOSQL databasesAshwani Kumar
 
An Overview of Apache Cassandra
An Overview of Apache CassandraAn Overview of Apache Cassandra
An Overview of Apache CassandraDataStax
 
Impacts of Sharding, Partitioning, Encoding, and Sorting on Distributed Query...
Impacts of Sharding, Partitioning, Encoding, and Sorting on Distributed Query...Impacts of Sharding, Partitioning, Encoding, and Sorting on Distributed Query...
Impacts of Sharding, Partitioning, Encoding, and Sorting on Distributed Query...InfluxData
 
HBase in Practice
HBase in PracticeHBase in Practice
HBase in Practicelarsgeorge
 

What's hot (20)

Introduction to Cassandra Architecture
Introduction to Cassandra ArchitectureIntroduction to Cassandra Architecture
Introduction to Cassandra Architecture
 
Bulk Loading Data into Cassandra
Bulk Loading Data into CassandraBulk Loading Data into Cassandra
Bulk Loading Data into Cassandra
 
Introduction to CQL and Data Modeling with Apache Cassandra
Introduction to CQL and Data Modeling with Apache CassandraIntroduction to CQL and Data Modeling with Apache Cassandra
Introduction to CQL and Data Modeling with Apache Cassandra
 
Storing time series data with Apache Cassandra
Storing time series data with Apache CassandraStoring time series data with Apache Cassandra
Storing time series data with Apache Cassandra
 
Cassandra Data Modeling - Practical Considerations @ Netflix
Cassandra Data Modeling - Practical Considerations @ NetflixCassandra Data Modeling - Practical Considerations @ Netflix
Cassandra Data Modeling - Practical Considerations @ Netflix
 
Introduction to Cassandra Basics
Introduction to Cassandra BasicsIntroduction to Cassandra Basics
Introduction to Cassandra Basics
 
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
 
Log Structured Merge Tree
Log Structured Merge TreeLog Structured Merge Tree
Log Structured Merge Tree
 
Understanding Data Partitioning and Replication in Apache Cassandra
Understanding Data Partitioning and Replication in Apache CassandraUnderstanding Data Partitioning and Replication in Apache Cassandra
Understanding Data Partitioning and Replication in Apache Cassandra
 
Introduction to NoSQL Databases
Introduction to NoSQL DatabasesIntroduction to NoSQL Databases
Introduction to NoSQL Databases
 
[TDC2016] Apache Cassandra Estratégias de Modelagem de Dados
[TDC2016]  Apache Cassandra Estratégias de Modelagem de Dados[TDC2016]  Apache Cassandra Estratégias de Modelagem de Dados
[TDC2016] Apache Cassandra Estratégias de Modelagem de Dados
 
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
Maximum Overdrive: Tuning the Spark Cassandra Connector (Russell Spitzer, Dat...
 
Deep Dive into Cassandra
Deep Dive into CassandraDeep Dive into Cassandra
Deep Dive into Cassandra
 
Cassandra Data Modelling
Cassandra Data ModellingCassandra Data Modelling
Cassandra Data Modelling
 
Cassandra concepts, patterns and anti-patterns
Cassandra concepts, patterns and anti-patternsCassandra concepts, patterns and anti-patterns
Cassandra concepts, patterns and anti-patterns
 
Introduction to NOSQL databases
Introduction to NOSQL databasesIntroduction to NOSQL databases
Introduction to NOSQL databases
 
Deep Dive on Amazon DynamoDB
Deep Dive on Amazon DynamoDB Deep Dive on Amazon DynamoDB
Deep Dive on Amazon DynamoDB
 
An Overview of Apache Cassandra
An Overview of Apache CassandraAn Overview of Apache Cassandra
An Overview of Apache Cassandra
 
Impacts of Sharding, Partitioning, Encoding, and Sorting on Distributed Query...
Impacts of Sharding, Partitioning, Encoding, and Sorting on Distributed Query...Impacts of Sharding, Partitioning, Encoding, and Sorting on Distributed Query...
Impacts of Sharding, Partitioning, Encoding, and Sorting on Distributed Query...
 
HBase in Practice
HBase in PracticeHBase in Practice
HBase in Practice
 

Viewers also liked

DataStax: A deep look at the CQL WHERE clause
DataStax: A deep look at the CQL WHERE clauseDataStax: A deep look at the CQL WHERE clause
DataStax: A deep look at the CQL WHERE clauseDataStax Academy
 
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...DataStax
 
Cql – cassandra query language
Cql – cassandra query languageCql – cassandra query language
Cql – cassandra query languageCourtney Robinson
 
Cassandra internals
Cassandra internalsCassandra internals
Cassandra internalsnarsiman
 
CQL: SQL In Cassandra
CQL: SQL In CassandraCQL: SQL In Cassandra
CQL: SQL In CassandraEric Evans
 
Cassandra Troubleshooting 3.0
Cassandra Troubleshooting 3.0Cassandra Troubleshooting 3.0
Cassandra Troubleshooting 3.0J.B. Langston
 
Hardening cassandra q2_2016
Hardening cassandra q2_2016Hardening cassandra q2_2016
Hardening cassandra q2_2016zznate
 
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...DataStax Academy
 
Lambda at Weather Scale - Cassandra Summit 2015
Lambda at Weather Scale - Cassandra Summit 2015Lambda at Weather Scale - Cassandra Summit 2015
Lambda at Weather Scale - Cassandra Summit 2015Robbie Strickland
 
Hadoop 2.0 - The Next Level
Hadoop 2.0 - The Next LevelHadoop 2.0 - The Next Level
Hadoop 2.0 - The Next LevelSascha Dittmann
 
Cassandra presentation at NoSQL
Cassandra presentation at NoSQLCassandra presentation at NoSQL
Cassandra presentation at NoSQLEvan Weaver
 
Introduction to Apache Cassandra
Introduction to Apache CassandraIntroduction to Apache Cassandra
Introduction to Apache CassandraRobert Stupp
 
Overview of DataStax OpsCenter
Overview of DataStax OpsCenterOverview of DataStax OpsCenter
Overview of DataStax OpsCenterDataStax
 

Viewers also liked (20)

DataStax: A deep look at the CQL WHERE clause
DataStax: A deep look at the CQL WHERE clauseDataStax: A deep look at the CQL WHERE clause
DataStax: A deep look at the CQL WHERE clause
 
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
C* Keys: Partitioning, Clustering, & CrossFit (Adam Hutson, DataScale) | Cass...
 
Cassandra @ Yahoo Japan | Cassandra Summit 2016
Cassandra @ Yahoo Japan | Cassandra Summit 2016Cassandra @ Yahoo Japan | Cassandra Summit 2016
Cassandra @ Yahoo Japan | Cassandra Summit 2016
 
Cql – cassandra query language
Cql – cassandra query languageCql – cassandra query language
Cql – cassandra query language
 
NoSQL Essentials: Cassandra
NoSQL Essentials: CassandraNoSQL Essentials: Cassandra
NoSQL Essentials: Cassandra
 
Cassandra internals
Cassandra internalsCassandra internals
Cassandra internals
 
Cassandra Summit 2016 注目セッション報告
Cassandra Summit 2016 注目セッション報告Cassandra Summit 2016 注目セッション報告
Cassandra Summit 2016 注目セッション報告
 
Intro to Cassandra
Intro to CassandraIntro to Cassandra
Intro to Cassandra
 
CQL: SQL In Cassandra
CQL: SQL In CassandraCQL: SQL In Cassandra
CQL: SQL In Cassandra
 
Cassandra Troubleshooting 3.0
Cassandra Troubleshooting 3.0Cassandra Troubleshooting 3.0
Cassandra Troubleshooting 3.0
 
Hardening cassandra q2_2016
Hardening cassandra q2_2016Hardening cassandra q2_2016
Hardening cassandra q2_2016
 
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
Cassandra Community Webinar | Getting Started with Apache Cassandra with Patr...
 
Lambda at Weather Scale - Cassandra Summit 2015
Lambda at Weather Scale - Cassandra Summit 2015Lambda at Weather Scale - Cassandra Summit 2015
Lambda at Weather Scale - Cassandra Summit 2015
 
Hadoop 2.0 - The Next Level
Hadoop 2.0 - The Next LevelHadoop 2.0 - The Next Level
Hadoop 2.0 - The Next Level
 
Cassandra presentation at NoSQL
Cassandra presentation at NoSQLCassandra presentation at NoSQL
Cassandra presentation at NoSQL
 
Become a super modeler
Become a super modelerBecome a super modeler
Become a super modeler
 
Global Netflix Platform
Global Netflix PlatformGlobal Netflix Platform
Global Netflix Platform
 
Introduction to Apache Cassandra
Introduction to Apache CassandraIntroduction to Apache Cassandra
Introduction to Apache Cassandra
 
Overview of DataStax OpsCenter
Overview of DataStax OpsCenterOverview of DataStax OpsCenter
Overview of DataStax OpsCenter
 
Camunda and Apache Cassandra
Camunda and Apache CassandraCamunda and Apache Cassandra
Camunda and Apache Cassandra
 

More from DataStax Academy

Forrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craftForrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craftDataStax Academy
 
Introduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph DatabaseIntroduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph DatabaseDataStax Academy
 
Introduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache CassandraIntroduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache CassandraDataStax Academy
 
Cassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart LabsCassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart LabsDataStax Academy
 
Cassandra 3.0 Data Modeling
Cassandra 3.0 Data ModelingCassandra 3.0 Data Modeling
Cassandra 3.0 Data ModelingDataStax Academy
 
Cassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stackCassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stackDataStax Academy
 
Data Modeling for Apache Cassandra
Data Modeling for Apache CassandraData Modeling for Apache Cassandra
Data Modeling for Apache CassandraDataStax Academy
 
Production Ready Cassandra
Production Ready CassandraProduction Ready Cassandra
Production Ready CassandraDataStax Academy
 
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & PythonCassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & PythonDataStax Academy
 
Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1DataStax Academy
 
Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2DataStax Academy
 
Standing Up Your First Cluster
Standing Up Your First ClusterStanding Up Your First Cluster
Standing Up Your First ClusterDataStax Academy
 
Real Time Analytics with Dse
Real Time Analytics with DseReal Time Analytics with Dse
Real Time Analytics with DseDataStax Academy
 
Introduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraIntroduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraDataStax Academy
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseDataStax Academy
 
Advanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraAdvanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraDataStax Academy
 

More from DataStax Academy (20)

Forrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craftForrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craft
 
Introduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph DatabaseIntroduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph Database
 
Introduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache CassandraIntroduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache Cassandra
 
Cassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart LabsCassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart Labs
 
Cassandra 3.0 Data Modeling
Cassandra 3.0 Data ModelingCassandra 3.0 Data Modeling
Cassandra 3.0 Data Modeling
 
Cassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stackCassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stack
 
Data Modeling for Apache Cassandra
Data Modeling for Apache CassandraData Modeling for Apache Cassandra
Data Modeling for Apache Cassandra
 
Coursera Cassandra Driver
Coursera Cassandra DriverCoursera Cassandra Driver
Coursera Cassandra Driver
 
Production Ready Cassandra
Production Ready CassandraProduction Ready Cassandra
Production Ready Cassandra
 
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & PythonCassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
 
Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1
 
Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2
 
Standing Up Your First Cluster
Standing Up Your First ClusterStanding Up Your First Cluster
Standing Up Your First Cluster
 
Real Time Analytics with Dse
Real Time Analytics with DseReal Time Analytics with Dse
Real Time Analytics with Dse
 
Introduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraIntroduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache Cassandra
 
Cassandra Core Concepts
Cassandra Core ConceptsCassandra Core Concepts
Cassandra Core Concepts
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax Enterprise
 
Bad Habits Die Hard
Bad Habits Die Hard Bad Habits Die Hard
Bad Habits Die Hard
 
Advanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraAdvanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache Cassandra
 
Advanced Cassandra
Advanced CassandraAdvanced Cassandra
Advanced Cassandra
 

Recently uploaded

Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 

Recently uploaded (20)

Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 

CQL Under the Hood

  • 1. CQL Under the Hood Robbie Strickland
  • 2. whoami? Robbie Strickland Software Development Manager @rs_atl
  • 3. Target Audience • Veterans who don’t use or don’t understand CQL • Newcomers who only know CQL, but don’t know what’s happening underneath
  • 4. Definitions • Thrift: legacy RPC protocol + code generation tool • batch_mutate, get_range_slices, multiget_slice, etc. • Deprecated in favor of native protocol • Native protocol: replacement for Thrift • Only works with CQL
  • 5. Definitions • Storage rows: keys + columns as stored on disk • CQL rows: abstraction layer on top of storage rows • Not usually a direct mapping to storage rows • Make use of predefined schema • Data still sparse – no space used for null columns
  • 6. In the Old Days … • Lots of clients with lots of APIs • No common language for describing schemas or queries • Steep learning curve
  • 7. In the Old Days … • No cursors, so entire result set must fit in memory on client and server • Hard to add new features • Lag time between release of new features and client library adoption
  • 8. Solution: CQL? SELECT * FROM mytable WHERE mykey = ‘foo’; WAT???!!!
  • 9. Solution: CQL? Veterans “What happened to my NoSQL??!!”
  • 10. Solution: CQL? Newbies “Sweet, SQL! I don’t have to learn anything new!”
  • 11. Reality • Don’t panic • Thrift problems solved • You didn’t lose anything • Underlying storage is unchanged • Don’t get lazy • CQL is not SQL • You need to know what you’re doing • No, you can’t just index everything
  • 12. Simple CQL CREATE TABLE Books (! title varchar,! author varchar,! year int,! PRIMARY KEY (title)! SELECT * FROM Books;! );! ! INSERT INTO Books (title, author, year) ! VALUES ('Patriot Games', 'Tom Clancy', 1987);! INSERT INTO Books (title, author, year) ! VALUES ('Without Remorse', 'Tom Clancy', 1993);! ! title | author | year! -----------------+------------+------! Without Remorse | Tom Clancy | 1993! Patriot Games | Tom Clancy | 1987!
  • 13. Storage Rows [default@unknown] create keyspace Library;! [default@unknown] use Library;! [default@Library] create column family Books! ...! with key_validation_class=UTF8Type! ...! and comparator=UTF8Type! ...! and default_validation_class=UTF8Type;! [default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! [default@Library] set Books['Patriot Games']['year'] = '1987';! [default@Library] list Books;! ! RowKey: Patriot Games! => (name=author, value=Tom Clancy, timestamp=1393102991499000)! => (name=year, value=1987, timestamp=1393103015955000)!
  • 14. Storage Rows [default@unknown] create keyspace Library;! [default@unknown] use Library;! [default@Library] create column family Books! ...! with key_validation_class=UTF8Type! ...! and comparator=UTF8Type! ...! and default_validation_class=UTF8Type;! [default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! [default@Library] set Books['Patriot Games']['year'] = '1987';! [default@Library] list Books;! ! RowKey: Patriot Games! => (name=author, value=Tom Clancy, timestamp=1393102991499000)! => (name=year, value=1987, timestamp=1393103015955000)! Random hash (no ordering)
  • 15. Storage Rows [default@unknown] create keyspace Library;! [default@unknown] use Library;! [default@Library] create column family Books! ...! with key_validation_class=UTF8Type! ...! and comparator=UTF8Type! ...! and default_validation_class=UTF8Type;! [default@Library] set Books['Patriot Games']['author'] = 'Tom Clancy';! [default@Library] set Books['Patriot Games']['year'] = '1987';! [default@Library] list Books;! ! Ordered by name RowKey: Patriot Games! => (name=author, value=Tom Clancy, timestamp=1393102991499000)! => (name=year, value=1987, timestamp=1393103015955000)!
  • 16. Compound Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! );! name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 17. Compound Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! );! Partition key (row key) name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 18. Compound Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! );! Clustering columns name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 19. == Composite Columns [default@Library] list authors;! ! Partition key (row key) RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)!
  • 20. == Composite Columns [default@Library] list authors;! ! RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! Clustering columns
  • 21. == Composite Columns [default@Library] list authors;! ! RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! Ordered by name
  • 22. Reversing Sort Order CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! ) WITH CLUSTERING ORDER BY (year DESC);! name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam!
  • 23. Reversing Sort Order [default@Library] list authors;! ! RowKey: Tom Clancy! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 24. Composite Partition Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY ((name, year), title)! );! Composite partition key name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 25. Composite Partition Key CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY ((name, year), title)! );! Clustering column name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 26. == Composite Keys [default@Library] list authors;! ! Partition keys (row key) RowKey: Tom Clancy:1993! => (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! => (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! -------------------! RowKey: Tom Clancy:1987! => (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! => (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)!
  • 27. == Composite Keys [default@Library] list authors;! ! RowKey: Tom Clancy:1993! => (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! => (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! -------------------! RowKey: Tom Clancy:1987! => (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! => (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)! Clustering column
  • 28. Why This Matters • Queries must respect underlying storage, else they will either be slow or impossible • You have to know your partition key at query time • If you want fast multi-record queries, select a range, in storage order • With clustering columns, order matters
  • 29. Example CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! ) WITH CLUSTERING ORDER BY (year DESC);!
  • 30. Example name | year | title | isbn | publisher! ------------+------+-----------------------------+---------------+-----------! Tom Clancy | 1996 | Executive Orders | 0-399-13825-0 | Putnam! Tom Clancy | 1994 | Debt of Honor | 0-399-13826-1 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13927-0 | Putnam! Tom Clancy | 1991 | The Sum of All Fears | 0-399-12341-6 | Putnam! Tom Clancy | 1989 | Clear and Present Danger | 0-399-13341-1 | Putnam! Tom Clancy | 1988 | The Cardinal of the Kremlin | 0-399-13241-4 | Putnam! Tom Clancy | 1987 | Patriot Games | 0-399-13231-4 | Putnam! Tom Clancy | 1986 | Red Storm Rising | 0-399-13230-2 | Putnam! Tom Clancy | 1984 | The Hunt for Red October | 0-399-13251-1 | Putnam! !!
  • 31. Query by Key SELECT * FROM authors WHERE name = ‘Tom Clancy’ (CL = QUORUM) RF = 3 Tom Clancy Tom Clancy Tom Clancy
  • 32. Query by Key Find partition key RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 33. Query by Key Scan all columns in order RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 34. Range Query SELECT * FROM authors WHERE name = ‘Tom Clancy’ AND year >= 1990 (CL = QUORUM) Tom Clancy Tom Clancy Tom Clancy
  • 35. Range Query Find partition key RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 36. Range Query Scan until < 1990 RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 37. Querying Tail of Range SELECT * FROM authors WHERE name = ‘Tom Clancy’ AND year <= 1990 (CL = QUORUM) Tom Clancy Tom Clancy Tom Clancy
  • 38. Querying Tail of Range Find partition key RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 39. Querying Tail of Range Scan all, then filter <= 1990 RowKey: Tom Clancy! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1994:Debt of Honor:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1994:Debt of Honor:ISBN, value=0-399-13826-1, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1991:The Sum of All Fears:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1991:The Sum of All Fears:ISBN, value=0-399-13241-6, timestamp=1393104011458000)! ...! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)!
  • 40. Multiple Keys DK DK MG MG TC MG TC TC DK SELECT * FROM authors WHERE name IN (‘Tom Clancy’, ‘Dean Koontz’, ‘Malcolm Gladwell’) (CL = QUORUM)
  • 41. Lessons Learned • Sequential == fast • Query by key / clustering column (range) == Sequential • Multi-key query often == lots of nodes • Write in the intended read order
  • 42. Collections • Sets: unordered, unique • Lists: ordered, allow duplicates • Maps: key/value pairs – can be a good substitute for dynamic columns • Max 64k items, 64k per item • Always returns entire collection
  • 43. Sets CREATE TABLE authors (! !name text,! !books set<text>,! PRIMARY KEY (name)! name | books! ------------+--------------------------------------! Tom Clancy | {'Patriot Games', 'Without Remorse'}! );! ! INSERT INTO authors (name, books) ! VALUES ('Tom Clancy', {'Without Remorse', 'Patriot Games'});!
  • 44. Sets RowKey: Tom Clancy! => (name=books:50617472696f742047616d6573, value=, ...)! => (name=books:576974686f75742052656d6f727365, value=, ...)! Set name Set item Empty value
  • 45. Lists CREATE TABLE authors (! !name text,! !books list<text>,! PRIMARY KEY (name)! name | books! ------------+--------------------------------------! Tom Clancy | ['Without Remorse’, 'Patriot Games']! );! ! INSERT INTO authors (name, books) ! VALUES ('Tom Clancy', ['Without Remorse', 'Patriot Games']);!
  • 46. Lists RowKey: Tom Clancy! => (name=books:d36de8b0305011e4a0dddbbeade718be, value=576974686f75742052656d6f727365, ...)! => (name=books:d36de8b1305011e4a0dddbbeade718be, value=50617472696f742047616d6573, ...)! List name Ordering ID List item
  • 47. Maps CREATE TABLE authors (! !name text,! !books map<text, int>,! PRIMARY KEY (name)! name | books! ------------+-------------------------------------------------! Tom Clancy | {'Patriot Games': 1987, 'Without Remorse': 1993}! );! ! INSERT INTO authors (name, books) ! VALUES ('Tom Clancy', ! {'Without Remorse' : 1993, 'Patriot Games' : 1987});!
  • 48. Maps RowKey: Tom Clancy! => (name=books:50617472696f742047616d6573, value=000007c3, ...)! => (name=books:576974686f75742052656d6f727365, value=000007c9, ...)! Map name Map key Map value
  • 49. Indices CREATE INDEX author_publisher! ON author (publisher);!
  • 50. Indices • Allow query by value in certain cases • Partitioned based on row key of indexed table • Are updated atomically along with the data being inserted • Must be low cardinality, or it won’t scale well (to large cluster sizes) • But not too low, or it’s sort of pointless
  • 51. Index Distribution Node 1 Authors “Tom Clancy” : “Putnam”! “Mark Twain” : “Putnam”! ! Index “Putnam” : “Tom Clancy”! “Putnam” : “Mark Twain”! ! Node 2 Authors “Mark Twain” : “Putnam”! “Dan Brown” : “Putnam”! ! Index “Putnam” : “Mark Twain”! “Putnam” : “Dan Brown”! ! Node 3 Authors “Dan Brown” : “Putnam” “Tom Clancy” : “Putnam”! ! Index “Putnam” : “Dan Brown”! “Putnam” : “Tom Clancy”! ! Index key == indexed column value
  • 52. Index Distribution Node 1 Authors “Tom Clancy” : “Putnam”! “Mark Twain” : “Putnam”! ! Index “Putnam” : “Tom Clancy”! “Putnam” : “Mark Twain”! ! Node 2 Authors “Mark Twain” : “Putnam”! “Dan Brown” : “Putnam”! ! Index “Putnam” : “Mark Twain”! “Putnam” : “Dan Brown”! ! Node 3 Authors “Dan Brown” : “Putnam” “Tom Clancy” : “Putnam”! ! Index “Putnam” : “Dan Brown”! “Putnam” : “Tom Clancy”! ! … but node distribution based on original table key
  • 53. Querying by Value pub idx pub idx pub idx pub idx pub idx pub idx SELECT * FROM authors WHERE publisher = ‘Putnam’ (CL = QUORUM)
  • 54. Deletes DELETE FROM authors WHERE name = 'Tom Clancy';! ! INSERT INTO authors (title, name) VALUES ('Patriot Games', 'Tom Clancy') USING TTL 86400;! ! INSERT INTO authors (title, name, year) VALUES ('Patriot Games', 'Tom Clancy', null);! ! UPDATE authors SET publisher = null WHERE name = 'Tom Clancy';! !
  • 55. Deletes • Log-structured storage, so writes are immutable • Deletes create tombstones, one for each deleted column • Cassandra must read the tombstones to make sure it doesn’t revive deleted data • Lots of deletes is an anti-pattern
  • 56. Missing Columns INSERT INTO authors (title, name, year)! VALUES ('Without Remorse', 'Tom Clancy', 1993);! ! name | year | title | isbn | publisher! ------------+------+-----------------+------+-----------! Tom Clancy | 1993 | Without Remorse | null | null! ! RowKey: Tom Clancy! => (name=1993:Without Remorse:, value=, timestamp=1409936754170000)!
  • 57. Missing Columns activity | timestamp | source | source_elapsed! ---------------------------------------------------------------------------+--------------+-----------+----------------! execute_cql3_query | 11:51:55,975 | 127.0.0.1 | 0! Parsing select * from authors where name = 'Tom Clancy' LIMIT 10000; | 11:51:55,975 | 127.0.0.1 | 47! Preparing statement | 11:51:55,975 | 127.0.0.1 | 105! Executing single-partition query on authors | 11:51:55,975 | 127.0.0.1 | 307! Acquiring sstable references | 11:51:55,975 | 127.0.0.1 | 315! Merging memtable tombstones | 11:51:55,975 | 127.0.0.1 | 328! Skipped 0/0 non-slice-intersecting sstables, included 0 due to tombstones | 11:51:55,975 | 127.0.0.1 | 374! Merging data from memtables and 0 sstables | 11:51:55,975 | 127.0.0.1 | 383! Read 1 live and 0 tombstoned cells | 11:51:55,975 | 127.0.0.1 | 420! Request complete | 11:51:55,975 | 127.0.0.1 | 585! Only 1 read required
  • 58. Null Columns INSERT INTO authors (title, name, year, isbn, publisher) VALUES ('Without Remorse', 'Tom Clancy', 1993, null, null);! ! name | year | title | isbn | publisher! ------------+------+-----------------+------+-----------! Tom Clancy | 1993 | Without Remorse | null | null!
  • 59. Null Columns activity | timestamp | source | source_elapsed! ---------------------------------------------------------------------------+--------------+-----------+----------------! execute_cql3_query | 11:57:31,623 | 127.0.0.1 | 0! Parsing select * from authors where name = 'Tom Clancy' LIMIT 10000; | 11:57:31,623 | 127.0.0.1 | 41! Preparing statement | 11:57:31,623 | 127.0.0.1 | 101! Executing single-partition query on authors | 11:57:31,623 | 127.0.0.1 | 532! Acquiring sstable references | 11:57:31,623 | 127.0.0.1 | 544! Merging memtable tombstones | 11:57:31,623 | 127.0.0.1 | 571! Skipped 0/0 non-slice-intersecting sstables, included 0 due to tombstones | 11:57:31,623 | 127.0.0.1 | 596! Merging data from memtables and 0 sstables | 11:57:31,623 | 127.0.0.1 | 605! Read 1 live and 2 tombstoned cells | 11:57:31,624 | 127.0.0.1 | 669! Request complete | 11:57:31,623 | 127.0.0.1 | 777! 3 reads required!
  • 60. Why Queries Fail SELECT name FROM authors WHERE title = 'Patriot Games';! Bad Request: PRIMARY KEY part title cannot be restricted (preceding part year is either not restricted or by a non-EQ relation)!
  • 61. Why Queries Fail • Failure to provide the full partition key • Querying by value without an index • Misunderstanding clustering columns
  • 62. Missing Key Parts CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY ((name, year), title)! );! ! ! SELECT name FROM authors WHERE title
  • 63. Missing Key Parts [default@Library] list authors;! ! Partition keys (row key) RowKey: Tom Clancy:1993! => (name=Without Remorse:isbn, value=0-399-13241-4, timestamp=1409344246457000)! => (name=Without Remorse:publisher, value=5075746e616d, timestamp=1409344246457000)! -------------------! RowKey: Tom Clancy:1987! => (name=Patriot Games:isbn, value=0-399-13825-0, timestamp=1409344245715000)! => (name=Patriot Games:publisher, value=5075746e616d, timestamp=1409344245715000)!
  • 64. Missing Key Parts SELECT * FROM authors WHERE name = 'Tom Clancy’;! Bad Request: Partition key part year must be restricted since preceding part is!
  • 65. Missing Key Parts SELECT * FROM authors WHERE year = 1987;! Bad Request: partition key part year cannot be restricted (preceding part name is either not restricted or by a non-EQ relation)!
  • 66. Missing Key Parts SELECT * FROM authors WHERE year >= 1987;! Bad Request: partition key part year cannot be restricted (preceding part name is either not restricted or by a non-EQ relation)!
  • 67. Missing Key Parts SELECT * FROM authors ! WHERE name = 'Tom Clancy' and year >= 1987;! ! Bad Request: Only EQ and IN relation are supported on the partition key (unless you use the token() function)!
  • 68. Querying by Value SELECT * FROM authors WHERE isbn = '0-399-13241-4';! Bad Request: No indexed columns present in by-columns clause with Equal operator!
  • 69. Querying Clustering Columns CREATE TABLE authors (! !name text,! !year int,! !title text,! !isbn text,! !publisher text,! !PRIMARY KEY (name, year, title)! );! ! ! SELECT name FROM authors WHERE
  • 70. Querying Clustering Columns RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! Clustering columns
  • 71. Querying Clustering Columns SELECT * FROM authors ! WHERE name = 'Tom Clancy’! AND year = 1993;! name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 72. Querying Clustering Columns RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)!
  • 73. Querying Clustering Columns SELECT * FROM authors ! WHERE name = 'Tom Clancy’! AND year <= 1993;! name | year | title | isbn | publisher! ------------+------+-----------------+---------------+-----------! Tom Clancy | 1987 | Patriot Games | 0-399-13241-4 | Putnam! Tom Clancy | 1993 | Without Remorse | 0-399-13825-0 | Putnam!
  • 74. Querying Clustering Columns RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)!
  • 75. Querying Clustering Columns SELECT * FROM authors ! WHERE name = 'Tom Clancy’! AND title = 'Patriot Games';! ! Bad Request: PRIMARY KEY part title cannot be restricted (preceding part year is either not restricted or by a non-EQ relation)! !!
  • 76. Querying Clustering Columns RowKey: Tom Clancy! => (name=1987:Patriot Games:ISBN, value=0-399-13241-4, timestamp=1393104011458000)! => (name=1987:Patriot Games:publisher, value=Putnam, timestamp=1393103948577000)! => (name=1993:Without Remorse:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1993:Without Remorse:publisher, value=Putnam, timestamp=1393104083773000)! => (name=1996:Executive Orders:ISBN, value=0-399-13825-0, timestamp=1393104109214000)! => (name=1996:Executive Orders:publisher, value=Putnam, timestamp=1393104083773000)! ?
  • 77. Summary • Stop using Thrift; use CQL instead • … but know what your model/query is doing
  • 78. Thanks! Robbie Strickland Software Development Manager @rs_atl