Geneva JUG - Cassandra for Java Developers

22
Cassandra for Java Developers DataStax Driver & DevCenter Michaël Figuière Drivers & Developer Tools Architect

description

 

Transcript of Geneva JUG - Cassandra for Java Developers

Page 1: Geneva JUG - Cassandra for Java Developers

Cassandra for Java DevelopersDataStax Driver & DevCenter

Michaël FiguièreDrivers & Developer Tools Architect

Page 2: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Client / Server Communication

2

Client

Client

Client

Client

Node

Node Replica

Replica

ReplicaNode

Coordinator node:Forwards all R/W requeststo corresponding replicas

Page 3: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Request Pipelining

3

Client

WithoutRequest Pipelining

Cassandra

Client CassandraWith

Request Pipelining

Page 4: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Notifications

4

Client

WithoutNotifications

WithNotifications

NodeNode

Node

Client

NodeNode

Node

Page 5: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Asynchronous Driver Architecture

5

ClientThread

Node

Node

Node

ClientThread

ClientThread

Node

Driver

Page 6: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Asynchronous Driver Architecture

6

ClientThread

Node

Node

Node

ClientThread

ClientThread

Node

6

23

45

1

Driver

Page 7: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Failover

7

ClientThread

Node

Node

Node

ClientThread

ClientThread

Node

7

2

4

531

Driver

6

Page 8: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Java Driver Highlights

• Reference implementation• Asynchronous architecture based on Netty• Prepared Statements Support• Automatic Failover• Node Discovery• Tunable Load Balancing

• Round Robin, Multi Data Centers, Latency Awareness, Replica Awareness

• Cassandra Tracing Support• Compression & SSL

8

Page 9: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 9

DataStax Driver in Practice

<dependency>  <groupId>com.datastax.cassandra</groupId>  <artifactId>cassandra-­‐driver-­‐core</artifactId>  <version>2.1.0</version>  

</dependency>  

Available in Maven Central. Depends on Netty, Guava, Metrics

Supports Apache Cassandra 1.2 to 2.1

Page 10: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 10

Connect and Write

Cluster cluster = Cluster.builder() .addContactPoints("127.0.0.1", “127.0.0.2") .build();

Session session = cluster.connect(“my_keyspace");

session.execute( "INSERT INTO user (user_id, name, email) VALUES (12345, 'johndoe', '[email protected]')");

The rest of the nodes will be discovered by the driver

A keyspace is just like a schema in the SQL world

Page 11: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 11

Read

ResultSet resultSet = session.execute("SELECT * FROM user");

List<Row> rows = resultSet.all(); for (Row row : rows) {

String userId = row.getString("user_id"); String name = row.getString("name"); String email = row.getString("email");}

Actually ResultSet also implements Iterable<Row>

Session is a thread safe object. A singleton should be instantiated at startup

Page 12: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 12

Write with Prepared Statements

PreparedStatement insertUser = session.prepare( "INSERT INTO user (user_id, name, email) VALUES (?, ?, ?)");

BoundStatement statement = insertUser .bind(12345, "johndoe", "[email protected]") .setConsistencyLevel(ConsistencyLevel.QUORUM);

session.execute(statement);

Parameters can be named as well

PreparedStatement objects are also threadsafe, just create a singleton at startup

BoundStatement is a stateful, NON threadsafe object

Consistency Level can be set for each statement

Page 13: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 13

Asynchronous Read

ResultSetFuture future = session.executeAsync("SELECT * FROM user");

ResultSet resultSet = future.get();

List<Row> rows = resultSet.all(); for (Row row : rows) {

String userId = row.getString("user_id"); String name = row.getString("name"); String email = row.getString("email");}

Will NOT block unless all the connections are busy

Will block until less all the connections are busy

Page 14: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 14

Asynchronous Read with Callbacks

ResultSetFuture future = session.executeAsync("SELECT * FROM user");

future.addListener(new Runnable() { public void run() { // Process the results here }}, executor);

ResultSetFuture implements Guava’s ListenableFuture

executor = Executors .newCachedThreadPool();

executor = MoreExecutors .sameThreadExecutor();

Only if your listener code is trivial and non blocking as it’ll be executed in the IO Thread

…Or any thread pool that you prefer

Page 15: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 15

Query Builder

import staticcom.datastax.driver.core.querybuilder.QueryBuilder.*;

Statement selectAll = select().all().from("user").where(eq("user_id", userId));

session.execute(selectAll);

Statement insert = insertInto("user") .value("user_id", 2) .value("name", "johndoe") .value("email", "[email protected]");

session.execute(insert);

import static of QueryBuilder is required in order to use the DSL

Page 16: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Object Mapper

• Avoid boilerplate for common use cases

• Map Objects to Statements and ResultSets to Objects

• Do NOT hide Cassandra from the developer

• No “clever tricks” à la Hibernate

• Not JPA compatible, but JPA-ish API

16

Page 17: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 17

Object Mapper in Practice

<dependency>  <groupId>com.datastax.cassandra</groupId>  <artifactId>cassandra-­‐driver-­‐mapping</artifactId>  <version>2.1.0</version>  

</dependency>  

Additional artifact for object mapping

Available from Driver 2.1.0

Page 18: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 18

Basic Object Mapping

CREATE  TYPE  address  (          street  text,          city  text,          zip  int  );      CREATE  TABLE  users  (          email  text  PRIMARY  KEY,          address  address  );

@UDT(keyspace  =  "ks",  name  =  "address")  public  class  Address  {          private  String  street;          private  String  city;          private  int  zip;              //  getters  and  setters  omitted...  }      @Table(keyspace  =  "ks",  name  =  "users")  public  class  User  {          @PartitionKey          private  String  email;          private  Address  address;              //  getters  and  setters  omitted...  }  

Page 19: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 19

Basic Object Mapping

MappingManager  manager  =          new  MappingManager(session);  

Mapper  mapper  =  manager.mapper(User.class);      UserProfile  myProfile  =            mapper.get("[email protected]");  

ListenableFuture  saveFuture  =          mapper.saveAsync(anotherProfile);  

mapper.delete("[email protected]");  

Mapper, just like Session, is a thread-safe object. Create a singleton at startup.

get() returns a mapped row for the given Primary Key

ListenableFuture from Guava. Completed when the write is acknowledged.

Page 20: Geneva JUG - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 20

Accessors

UserAccessor  accessor  =          manager.createAccessor(UserAccessor.class);  Result<User>  users  =  accessor.firstN(10);  

for  (User  user  :  users)  {          System.out.println(                  profile.getAddress().getZip()          );  }  

Result is like ResultSet but specialized for a mapped class…

…so we iterate over it just like we would with a ResultSet

@Accessor  interface  UserAccessor  {          @Query("SELECT  *  FROM  user_profiles  LIMIT  :max")          Result<User>  firstN(@Param("max")  int  limit);  }

Page 21: Geneva JUG - Cassandra for Java Developers

DataStax DevCenterDemo

Page 22: Geneva JUG - Cassandra for Java Developers

We’re Hiring!

@mfiguiere

blog.datastax.com

github.com/datastax