Apache Cassandra An Introduction for Java Developers Nate McCall [email_address] @zznate
What is Apache Cassandra?
CAP Theorem  C onsistency A vailability  P artition Tolerance “ Though shalt have but 2”  - Conjecture made by Eric Brewer in 2000 - Published as formal proof in 2002 - See:  http://en.wikipedia.org/wiki/CAP_theorem  for more
Apache Cassandra Concepts - Explicit choice of partition tolerance and availability. Consistency is tunable. - No read before write - Merge on read - Idempotent - Schema Optional - All nodes share the same roll - Still performs well with larger-than-memory data sets
Generally complements another system(s)  (Not intended to be one-size-fits-all) *** You should always use the right tool for the right job anyway
How does this differ from an RDBMS?
How does this differ from an RDBMS? Substantially.
vs. RDBMS - No Joins  Unless:  - you do them on the client  - you do them via Map/Reduce
vs. RDBMS - Schema Optional  (Though you can add meta information for validation and type checking)  *** Supports secondary indexes too: “ …  WHERE state = 'TX' ”
vs. RDBMS - Prematerialized and Transaction-less - No ACID transactions  - Limited support for ad-hoc queries
vs. RDBMS - Prematerialized and Transaction-less - No ACID transactions  - Limited support for ad-hoc queries *** You are going to give up both of these anyway when you shard an RDBMS ***
vs. RDBMS - Facilitates Consolidation It can be your caching layer * Off-heap cache (provided you install JNA) It can be your analytics infrastructure * true map/reduce * pig driver * hive driver coming soon
vs. RDBMS - Shared-Nothing Architecture Every node plays the same role: no masters, no slaves, no special nodes *** No single point of failure
vs. RDBMS - Real Linear Scalability Want 2x performance? Add 2x nodes. *** 'No downtime' included!
vs. RDBMS - Performance Reads on par with writes
Clustering
Clustering Single node cluster (easy development setup) - one node owns the whole hash range
Clustering Two node cluster - Key range divided between nodes
Clustering Consistent Hashing: md5(“zznate”) = “C”
Clustering Consistent Hashing FTW: - Ring ownership continuously “gossiped” between nodes - Any node can act as a “coordinator” to service client requests for any key * requests forwarded to the appropriate nodes by coordinator transparently to the client
Clustering Client Read:  get(“zznate”) md5 = “C”
Clustering – Scale Out
Clustering – Scale Out
Clustering – Scale Out
Clustering - Multi-DC
Clustering - Reliability
Clustering - Reliability
Clustering - Reliability
Clustering - Reliability
Clustering - Multi-Datacenter
Clustering – Multi-DC Reliability
Storage (Briefly)
Storage (Briefly)  Understanding the on-disk format is extremely helpful in designing your data model correctly
Storage - SSTable - SSTables are immutable (“Merge on read”) - Newest timestamp wins
Storage – Compaction Merge SSTables – keeping count down making Merge on Read more efficient Discards Tombstones (more on this later!)
Data Model
Data Model "...sparse, persistent, distributed, multi-dimensional sorted map." (The “Bigtable” paper)
Data Model Keyspace - Collection of Column Families
- Controls replication
Column Family
- Similar to a table
- Columns ordered by name
Data Model – Column Family Static Column Family - Model my object data
Dynamic Column Family
- Pre-calculated query results
Nothing stopping you from mixing them!
Data Model – Static CF zznate driftx thobbs jbellis password : * password : * password : * name : Nate name : Brandon name : Tyler password : * name : Jonathan site : datastax.com Users
Data Model – Prematerialized Query Following zznate driftx thobbs jbellis driftx: thobbs: driftx: thobbs: mdennis: zznate zznate: pcmanus xedin:
Data Model – Prematerialized Query Additional examples: Timeline of tweets by a user Timeline of tweets by all of the people a user is following List of comments sorted by score List of friends grouped by state
API Operations
Five general categories Retrieving Writing/Updating/Removing (all the same op!) Increment counters Meta Information Schema Manipulation CQL Execution
Using a Client Hector Client: http://hector-client.org - Most popular Java client  - In use at very large installations - A number of tools and utilities built on top - Very active community - MIT Licensed  *** like any open source project fully dependent on another open source project it has it's worts
Sample Project for Experimenting https://github.com/zznate/cassandra-tutorial https://github.com/zznate/hector-examples Built using Hector  Really basic – designed to be beginner level w/ very few moving parts Modify/abuse/alter as needed *** Descriptions of what is going on and how to run each example are in the Javadoc comments. 
ColumnFamilyTemplate Familiar, type-safe approach - based on template-method design pattern - generic: ColumnFamilyTemplate<K,N> (K is the key type, N the column name type) ColumnFamilyTemplate template = new ThriftColumnFamilyTemplate(keyspaceName,  columnFamilyName,  StringSerializer.get(),  StringSerializer.get()); *** (no generics for clarity)
ColumnFamilyTemplate new ThriftColumnFamilyTemplate(keyspaceName,  columnFamilyName,  StringSerializer.get(),  StringSerializer.get()); Key Format Column Name Format - Cassandra calls this a “comparator” - Remember: defines column order in on-disk format
ColumnFamilyTemplate ColumnFamilyResult<String, String> res = cft.queryColumns(&quot;zznate&quot;); String value = res.getString(&quot;email&quot;); Date startDate = res.getDate(“startDate”); Key Format Column Name Format
ColumnFamilyTemplate ColumnFamilyResult wrapper =  template.queryColumns(&quot;zznate&quot;, &quot;patricioe&quot;, &quot;thobbs&quot;); String nateEmail = wrapper.getString(&quot;email&quot;);  wrapper.next(); String patoEmail = wrapper.getString(&quot;email&quot;); wrapper.next(); String tylerEmail = wrapper.getString(&quot;email&quot;); Querying multiple rows and iterating over results
ColumnFamilyTemplate ColumnFamilyUpdater updater = template.createUpdater(&quot;zznate&quot;);  updater.setString(&quot;companyName&quot;,&quot;DataStax&quot;); updater.addKey(&quot;sergek&quot;); updater.setString(&quot;companyName&quot;,&quot;PrestoSports&quot;); template.update(updater); Inserting data with ColumnFamilyUpdater
ColumnFamilyTemplate template.deleteColumn(&quot;zznate&quot;, &quot;notNeededStuff&quot;); template.deleteColumn(&quot;zznate&quot;, &quot;somethingElse&quot;); template.deleteColumn(&quot;patricioe&quot;, &quot;aDifferentColumnName&quot;); ... template.deleteRow(“someuser”); template.executeBatch(); Deleting Data with ColumnFamilyTemplate
Deletion
Deletion Again: Every mutation is an insert!
- Merge on read
- Sstables are immutable
- Highest timestamp wins
Deletion – As Seen by CLI [default@Tutorial] list StateCity; Using default limit of 100
-------------------
RowKey: CA Burlingame
=> (column=650, value=33372e3537783132322e3334, timestamp=1310340410528000)
-------------------
RowKey: TX Austin

Introduciton to Apache Cassandra for Java Developers (JavaOne)