Successfully reported this slideshow.
DataStax Java Driver Unleashed!
CQL The new face of Cassandra
* CQL3
* Simpler Data Model using Denormalized Tables
* SQL-like Query Language
* Schema Def...
* Cassandra lives closer to users and application
* Data model expresses your application intent
* Not made for generaliza...
CQL3 Data Model
Data duplicated over several tables
CQL3 Query Language
comes with a new Data
Model abstraction
made of de...
CQL3 Data Model
gmason
user_id
1735
tweet_id
phenry
author
Give me liberty or give me death
body
Partition
Key
gmason 1742...
CQL3 Data Model
gmason
user_id
1735
tweet_id
phenry
author
Give me liberty or give me death
body
Partition
Key
gmason 1742...
DB API
CQL Native Protocol
CQL API OO API
Next Generation Driver
New Driver Architecture
* Reference Implementation
* Asynchronous architecture based on Netty
* Prepared Statements Support
* Automatic Fail-over
...
Client
Without
Request Pipelining
Cassandra
Client Cassandra
With
Request Pipelining
Request Pipelining
Client
Without
Notifications
With
Notifications
Node
Node
Node
Client
Node
Node
Node
Notifications
Client
Thread
Node
Node
Node
Client
Thread
Client
Thread
Node
Driver
Asynchronous Architecture
1
2
3
4
5
6
Client
Thread
Node
Node
Node
Client
Thread
Client
Thread
Node
Driver
Asynchronous Architecture
contactPoints = {“10.0.0.1”,”10.0.0.2”}
keyspace = “videodb”
public VideoDbBasicImpl(List<String> contactPoints, String ke...
public void setUserByUsingString(User user) {
StringBuffer userInsert = new StringBuffer(
"INSERT INTO users (username, fi...
! public User getUserByUsernameUsingString(String username) {
! ! User user = new User();
! ! ResultSet rs = session.execu...
public void setUserByPreparedStatement(User user) {
BoundStatement bs = setUser.bind();
bs.setString("username", user.getU...
public List<Video> getVideosByUsernameUsingAsyncRead(String username) {
BoundStatement bs = getVideosByUsernamePreparedSta...
for (String tag : tags) {
BoundStatement bs = getVideosByTagPreparedStatement.bind(tag);
final ResultSetFuture future = se...
public Video getVideoByIdUsingQueryBuilder(String videoId) {
Video video = new Video();
Query query = select().all().from(...
Load
Balancing
Policy
Node
Node
Node
Health
Monitor
Load Balancing and Failover
ReconnectionNotifications
Client
Retry
Poli...
Node
Node
NodeClient
Datacenter B
Node
Node
Node
Client
Client
Client
Client
Client
Datacenter A
Local nodes are queried
fi...
Multi Datacenter Load Balancing
Node
Node
Replica
Node
Client Node
NodeReplica
Replica
Nodes that own a
Replica of the dat...
contactPoints = {“10.0.0.1”,”10.0.0.2”}
keyspace = “videodb”
public VideoDbBasicImpl(List<String> contactPoints, String ke...
Client
If the requested
Consistency Level
cannot be reached
(QUORUM here), a
second request with a
lower CL is sent
automa...
contactPoints = {“10.0.0.1”,”10.0.0.2”}
keyspace = “videodb”
public VideoDbBasicImpl(List<String> contactPoints, String ke...
public enum Gender {
	 @EnumValue("m")
	 MALE,
	
	 @EnumValue("f")
	 FEMALE;
}
@Table(name = "user")
public class User {
	...
DevCenter an IDE for Developers
Questions ?
Upcoming SlideShare
Loading in …5
×

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

1,641 views

Published on

Speakers: Michael Figuiere and Patrick McFadin, Principal Solutions Architect at DataStax
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.

Published in: Technology, Education
  • Be the first to comment

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

  1. 1. DataStax Java Driver Unleashed!
  2. 2. 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
  3. 3. * 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
  4. 4. CQL3 Data Model Data duplicated over several tables CQL3 Query Language comes with a new Data Model abstraction made of denormalized, statically defined tables
  5. 5. CQL3 Data Model gmason user_id 1735 tweet_id phenry author Give me liberty or give me death body Partition Key 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 Clustering Key Timeline Table
  6. 6. CQL3 Data Model gmason user_id 1735 tweet_id phenry author Give me liberty or give me death body Partition Key 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 Clustering Key Timeline Table CREATE TABLE timeline ( user_id varchar, tweet_id timeuuid, author varchar, body varchar, PRIMARY KEY (user_id, tweet_id)); CQL
  7. 7. DB API CQL Native Protocol CQL API OO API Next Generation Driver New Driver Architecture
  8. 8. * Reference Implementation * Asynchronous architecture based on Netty * Prepared Statements Support * Automatic Fail-over * Node Discovery * Cassandra Tracing Support * Tunable Policies Java Driver Overview
  9. 9. Client Without Request Pipelining Cassandra Client Cassandra With Request Pipelining Request Pipelining
  10. 10. Client Without Notifications With Notifications Node Node Node Client Node Node Node Notifications
  11. 11. Client Thread Node Node Node Client Thread Client Thread Node Driver Asynchronous Architecture
  12. 12. 1 2 3 4 5 6 Client Thread Node Node Node Client Thread Client Thread Node Driver Asynchronous Architecture
  13. 13. 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
  14. 14. 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
  15. 15. ! 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
  16. 16. 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
  17. 17. 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
  18. 18. 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
  19. 19. 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
  20. 20. Load Balancing Policy Node Node Node Health Monitor Load Balancing and Failover ReconnectionNotifications Client Retry Policy Response Dispatcher 1 3 2 4 5 6
  21. 21. 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. Multi Datacenter Load Balancing
  22. 22. Multi Datacenter Load Balancing Node Node Replica Node Client Node NodeReplica Replica Nodes that own a Replica of the data being read or written by the query will be contacted first.
  23. 23. 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
  24. 24. 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 Node Replica Downgrading Retry Policy
  25. 25. 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
  26. 26. 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
  27. 27. DevCenter an IDE for Developers
  28. 28. Questions ?

×