Upload
planet-cassandra
View
1.158
Download
3
Tags:
Embed Size (px)
DESCRIPTION
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.
Citation preview
DataStax Java Driver Unleashed!
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
* 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
CQL3 Data Model
Data duplicated over several tables
CQL3 Query Language comes with a new Data
Model abstraction made of denormalized, statically defined tables
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
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
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
* Node Discovery
* Cassandra Tracing Support
* Tunable Policies
Java Driver Overview
Client
WithoutRequest Pipelining
Cassandra
Client CassandraWith
Request Pipelining
Request Pipelining
Client
WithoutNotifications
WithNotifications
NodeNode
Node
Client
NodeNode
Node
Notifications
ClientThread
Node
Node
Node
ClientThread
ClientThread
Node
Driver
Asynchronous Architecture
1
23
45
6ClientThread
Node
Node
Node
ClientThread
ClientThread
Node
Driver
Asynchronous Architecture
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
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
! 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
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
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
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
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
Load Balancing
Policy
Node
Node
Node
Health Monitor
Load Balancing and Failover
ReconnectionNotifications
Client
RetryPolicy
ResponseDispatcher
1 3
2
4
5
6
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
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.
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
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
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
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
DevCenter an IDE for Developers
Questions ?