Transcript
Page 1: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

DataStax Java Driver Unleashed!

Page 2: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

CQL The new face of Cassandra* CQL3

* Simpler Data Model using Denormalized Tables

* SQL-like Query Language

* Schema Definition

* CQL Native Protocol

* Introduced in Cassandra 1.2

* Designed for CQL3

* Thrift will keep being supported by Cassandra

Page 3: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

* Cassandra lives closer to users and application

* Data model expresses your application intent

* Not made for generalizable queries

* Key to a successful project

CQL Data Model Overview

Page 4: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

CQL3 Data Model

Data duplicated over several tables

CQL3 Query Language comes with a new Data

Model abstraction made of denormalized, statically defined tables

Page 5: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

CQL3 Data Model

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

Page 6: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

CQL3 Data Model

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

CREATE TABLE timeline ( user_id varchar, tweet_id timeuuid, author varchar, body varchar, PRIMARY KEY (user_id, tweet_id));

CQL

Page 7: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

DB API

CQL Native Protocol

CQL API OO API

Next Generation Driver

New Driver Architecture

Page 8: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

* Reference Implementation

* Asynchronous architecture based on Netty

* Prepared Statements Support

* Automatic Fail-over

* Node Discovery

* Cassandra Tracing Support

* Tunable Policies

Java Driver Overview

Page 9: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

Client

WithoutRequest Pipelining

Cassandra

Client CassandraWith

Request Pipelining

Request Pipelining

Page 10: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

Client

WithoutNotifications

WithNotifications

NodeNode

Node

Client

NodeNode

Node

Notifications

Page 11: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

ClientThread

Node

Node

Node

ClientThread

ClientThread

Node

Driver

Asynchronous Architecture

Page 12: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

1

23

45

6ClientThread

Node

Node

Node

ClientThread

ClientThread

Node

Driver

Asynchronous Architecture

Page 13: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

contactPoints = {“10.0.0.1”,”10.0.0.2”}

keyspace = “videodb”

public VideoDbBasicImpl(List<String> contactPoints, String keyspace) {

cluster = Cluster .builder() .addContactPoints(! contactPoints.toArray(new String[contactPoints.size()])) .build();

session = cluster.connect(keyspace); }

Creating a Basic Connection

Page 14: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

public void setUserByUsingString(User user) {

StringBuffer userInsert = new StringBuffer( "INSERT INTO users (username, firstname, lastname, email, password, created_date) VALUES (");

userInsert.append("'" + user.getUsername() + "'"); userInsert.append("'" + user.getFirstname() + "'"); userInsert.append("'" + user.getLastname() + "'"); userInsert.append("'" + user.getEmail() + "'"); userInsert.append("'" + user.getPassword() + "'"); userInsert.append("'" + user.getCreated_date().toString() + "'"); userInsert.append(")");

session.execute(userInsert.toString());}

Basic write using insert

Page 15: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

! public User getUserByUsernameUsingString(String username) {

! ! User user = new User();

! ! ResultSet rs = session.execute("SELECT * FROM users WHERE username = '"! ! ! ! + username + "'");

! ! // A result set has Rows which can be iterated over! ! for (Row row : rs) {! ! ! user.setUsername(username);! ! ! user.setFirstname(row.getString("firstname"));! ! ! user.setLastname(row.getString("lastname"));! ! ! user.setEmail(row.getString("email"));! ! ! user.setPassword(row.getString("Password"));! ! ! user.setCreated_date(row.getDate("created_date"));! ! }

! ! return user;

! }

Basic Read using Select

Page 16: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

public void setUserByPreparedStatement(User user) {

BoundStatement bs = setUser.bind();

bs.setString("username", user.getUsername()); bs.setString("firstname", user.getFirstname()); bs.setString("lastname", user.getLastname()); bs.setString("email", user.getEmail()); bs.setString("password", user.getPassword()); bs.setDate("created_date", user.getCreated_date());! ! session.execute(bs);

}

Writing with Prepared Statements

Page 17: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

public List<Video> getVideosByUsernameUsingAsyncRead(String username) {

BoundStatement bs = getVideosByUsernamePreparedStatement.bind();

List<ResultSetFuture> futures = new ArrayList<ResultSetFuture>(); List<Video> videos = new ArrayList<Video>();

bs.setString("username", username);

for (Row row : session.execute(bs)) {

futures.add(session.executeAsync(getVideoByIDPreparedStatement .bind(row.getUUID("videoid")))); }

for (ResultSetFuture future : futures) {

for (Row row : future.getUninterruptibly()) { Video video = new Video(); video.setVideoid(row.getUUID("videoid")); videos.add(video); } } return videos;}

Asynchronous Read

Page 18: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

for (String tag : tags) { BoundStatement bs = getVideosByTagPreparedStatement.bind(tag); final ResultSetFuture future = session.executeAsync(bs);

future.addListener(new Runnable() {

public void run() { for (Row row : future.getUninterruptibly()) { UUID videoId = row.getUUID("videoid");

if (videoIds.putIfAbsent(videoId, PRESENT) == null) {

videoFutures.add(session .executeAsync(getVideoByIDPreparedStatement .bind(videoId))); } } } }, executor);}

Performing a Read with a Listener

Page 19: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

public Video getVideoByIdUsingQueryBuilder(String videoId) {

Video video = new Video();

Query query = select().all().from("videodb", "videos") .where(eq("videoId", videoId)).limit(10);

query.setConsistencyLevel(ConsistencyLevel.ONE);

ResultSet rs = session.execute(query); for (Row row : rs) {

video.setVideoid(row.getUUID("videoid")); video.setVideoname(row.getString("videoName")); video.setUsername(row.getString("username")); video.setDescription(row.getString("description")); } return video;}

Using the Query Builder

Page 20: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

Load Balancing

Policy

Node

Node

Node

Health Monitor

Load Balancing and Failover

ReconnectionNotifications

Client

RetryPolicy

ResponseDispatcher

1 3

2

4

5

6

Page 21: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

Node

Node

NodeClient

Datacenter B

Node

Node

Node

Client

Client

Client

Client

Client

Datacenter ALocal nodes are queried first, if non are available, the request will be sent to a remote node.

Multi Datacenter Load Balancing

Page 22: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

Multi Datacenter Load Balancing

Node

Node

ReplicaNode

Client Node

NodeReplica

Replica

Nodes that own a Replica of the data being read or written by the query will be contacted first.

Page 23: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

contactPoints = {“10.0.0.1”,”10.0.0.2”}

keyspace = “videodb”

public VideoDbBasicImpl(List<String> contactPoints, String keyspace) {

cluster = Cluster .builder() .addContactPoints(! contactPoints.toArray(new String[contactPoints.size()])) .withLoadBalancingPolicy(Policies.defaultLoadBalancingPolicy()) .build();

session = cluster.connect(keyspace); }

Create your own policy!

Add a Load Balancing Policy

Page 24: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

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

Downgrading Retry Policy

Page 25: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

contactPoints = {“10.0.0.1”,”10.0.0.2”}

keyspace = “videodb”

public VideoDbBasicImpl(List<String> contactPoints, String keyspace) {

cluster = Cluster .builder() .addContactPoints(! contactPoints.toArray(new String[contactPoints.size()])) .withLoadBalancingPolicy(Policies.defaultLoadBalancingPolicy()) .withRetryPolicy(Policies.defaultRetryPolicy()) .build();

session = cluster.connect(keyspace); }

Create your own policy!

Specify a Retry Policy

Page 26: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

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;}

Object Mapping

Page 27: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

DevCenter an IDE for Developers

Page 28: C* Summit 2013: Java and .NET Client Drivers - Cassandra Developments on Fire by Michael Figuiere and Patrick McFadin

Questions ?


Recommended