nyc* tech day - new cassandra drivers in depth
DESCRIPTION
Cassandra 1.2 finalizes CQL3 and introduces a new binary protocol for client/server communication. These two components are the foundation of the new line of drivers developed by DataStax. Based on years of experience with Cassandra, these new drivers for Java, .Net and Python come with an asynchronous and lightweight architecture, a clean and simple API, a standardized way to discover nodes and to manage load balancing and fail over. This presentation will give an in depth look at these new drivers which will make your Cassandra-based applications even more robust, efficient and simple to write.TRANSCRIPT
New Cassandra Drivers in Depth
Michaël Figuière@mfiguiere
©2012 DataStax
Speaker
Michaël Figuière
@mfiguiere
2
©2012 DataStax
CQL: the new face of Cassandra
• CQL 3• Simpler Data Model using denormalized Tables• SQL-like query language• Schema definition
• CQL Binary Protocol• Introduced in Cassandra 1.2 (CASSANDRA-2478)• Designed for CQL 3• Opens doors for Streaming, Notifications, ...• Thrift will keep being supported by Cassandra
3
©2012 DataStax
CQL3 Denormalized Model
4
Data duplicated over several tables
CQL3 Query Language comes with a new Data Model abstraction made of denormalized, statically defined tables
©2012 DataStax
CQL3 Data Model
5
gmason
user_id
1735
tweet_id
phenry
author
Give me liberty or give me death
body
PartitionKey
gmason 1742 gwashington I chopped down the cherry tree
ahamilton 1767 jadams A government of laws, not men
ahamilton 1794 gwashington I chopped down the cherry tree
ClusteringKey
Timeline Table
©2012 DataStax
CQL3 Data Model
6
gmason
user_id
1735
tweet_id
phenry
author
Give me liberty or give me death
body
gmason 1742 gwashington I chopped down the cherry tree
ahamilton 1767 jadams A government of laws, not men
ahamilton 1794 gwashington I chopped down the cherry tree
Timeline Table
CREATE TABLE timeline ( user_id varchar, tweet_id timeuuid, author varchar, body varchar, PRIMARY KEY (user_id, tweet_id));
CQL
©2012 DataStax
CQL3 Data Model
7
gmason
user_id tweet_id
phenry
author
Give me liberty or give me death
body
gmason gwashington I chopped down the cherry tree
ahamilton jadams A government of laws, not men
ahamilton gwashington I chopped down the cherry tree
gwashington
[1735, author]
I chopped down the...
[1735, body]
phenry
[1742, author]
Give me liberty or give...
[1742, body]gmason
gwashington
[1767, author]
I chopped down the...
[1767, body]
jadams
[1794, author]
A government of laws...
[1794, body]ahamilton
Timeline Table
Timeline Physical Layout
1735
1742
1767
1794
©2012 DataStax
Current Drivers Architecture
8
Thrift API
Thrift RPC
CQL API
Thrift RPC
DB API
* This is a simplified view of drivers architecture. Details vary from one language to another.
OO API
Client Library CQL Driver
©2012 DataStax
New Drivers Architecture
9
DB API
CQL Native Protocol
CQL API OO API
* This is a simplified view of drivers architecture. Details vary from one language to another.
Next Generation Driver
©2012 DataStax
DataStax Java Driver• Reference Implementation
• Asynchronous architecture based on Netty
• Prepared Statements Support
• Automatic Fail-over
• Node Discovery
• Cassandra Tracing Support
• Tunable policies• LoadBalancingPolicy• ReconnectionPolicy• RetryPolicy
10
©2012 DataStax
Request Pipelining
11
Client
WithoutRequest Pipelining
Cassandra
Client CassandraWith
Request Pipelining
©2012 DataStax
Notifications
12
Client
WithoutNotifications
WithNotifications
NodeNode
Node
Client
NodeNode
Node
©2012 DataStax
Asynchronous Architecture
13
ClientThread
Node
Node
Node
ClientThread
ClientThread
Node
Driver
©2012 DataStax
Asynchronous Architecture
14
ClientThread
Node
Node
Node
ClientThread
ClientThread
Node
1
23
45
6
Driver
©2012 DataStax
LoadBalancingPolicy
15
public interface LoadBalancingPolicy {
HostDistance distance(Host host);
Iterator<Host> newQueryPlan(Query query);
[...]
}
©2012 DataStax
DCAwareRoundRobinPolicy
16
Node
Node
NodeClient
Datacenter B
Node
Node
Node
Client
Client
Client
Client
Client
Datacenter A
Local nodes are queried first, if non are available, the request will be sent to a remote node.
©2012 DataStax
Node
Node
ReplicaNode
TokenAwarePolicy
17
Client Node
NodeReplica
Replica
Nodes that own a Replica of the data being read or written by the query will be contacted first.
©2012 DataStax
RetryPolicy
18
public interface RetryPolicy {
RetryDecision onReadTimeout(Query query, ConsistencyLevel cl, [...] );
RetryDecision onWriteTimeout(Query query, ConsistencyLevel cl, [...] );
RetryDecision onUnavailable(Query query, ConsistencyLevel cl, [...] );
public static class RetryDecision { public static enum Type { RETRY, RETHROW, IGNORE };
private final Type type; private final ConsistencyLevel retryCL; [...] }}
©2012 DataStax
Downgrading Consistency
19
Client
If the requested Consistency Level cannot be reached (QUORUM here), a second request with a lower CL is sent automatically.
Node
Node Replica
Replica
NodeReplica
©2012 DataStax
Connect and Write
20
Cluster cluster = Cluster.builder() .addContactPoints("10.0.0.1", "10.0.0.2") .build();
Session session = cluster.connect("myKeyspace");
session.execute( "INSERT INTO user (user_id, name, email) VALUES (12345, 'johndoe', '[email protected]')");
©2012 DataStax
Read
21
ResultSet rs = session.execute("SELECT * FROM test");
List<Row> rows = rs.all(); for (Row row : rows) {
String userId = row.getString("user_id"); String name = row.getString("name"); String email = row.getString("email");}
©2012 DataStax
Asynchronous Read
22
ResultSetFuture future = session.executeAsync("SELECT * FROM test");
for (Row row : future.get()) {
String userId = row.getString("user_id"); String name = row.getString("name"); String email = row.getString("email");}
©2012 DataStax
Prepared Statements
23
PreparedStatement ps = session.prepare("SELECT * FROM users WHERE id = ?");
BoundStatement bs = session.execute(ps.bind("123")).one().getInt("age");
bs.setString("k");
int age = session.execute(bs).one().getInt("age");
age = session.execute(ps.bind("123")).one().getInt("age");
©2012 DataStax
Query Builder
24
String query = "SELECT a,b,\"C\" FROM foo WHERE a IN (127.0.0.1,127.0.0.3) AND \"C\"='foo' ORDER BY a ASC,b DESC LIMIT 42;";
Query select = select("a", "b", quote("C")).from("foo") .where(in("a", InetAddress.getByName("127.0.0.1"), InetAddress.getByName("127.0.0.3"))) .and(eq(quote("C"), "foo")) .orderBy(asc("a"), desc("b")) .limit(42);
©2012 DataStax
Object Mapping
25
public enum Gender {
@EnumValue("m") MALE, @EnumValue("f") FEMALE;}
@Table(name = "user")public class User { @PartitionKey @Column(name = "user_id") private String userId; private String name; private String email; private Gender gender;}
©2012 DataStax
Inheritance
26
@InheritanceValue("tv")public class TV extends Product {
private float size;}
@Table(name = "catalog")@Inheritance( subClasses = {Phone.class, TV.class}, column = "product_type")public abstract class Product {
@Column(name = "product_id") private String productId; private float price; private String vendor; private String model;
}
https://github.com/datastax/
Betas now available!
@mfiguiere
blog.datastax.com
Stay Tuned!