YaJug - Cassandra for Java Developers

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

description

 

Transcript of YaJug - Cassandra for Java Developers

Page 1: YaJug - Cassandra for Java Developers

Cassandra for Java DevelopersDataStax Driver & DevCenter

Michaël FiguièreDrivers & Developer Tools Architect

Page 2: YaJug - 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: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Request Pipelining

3

Client

WithoutRequest Pipelining

Cassandra

Client CassandraWith

Request Pipelining

Page 4: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Notifications

4

Client

WithoutNotifications

WithNotifications

NodeNode

Node

Client

NodeNode

Node

Page 5: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Asynchronous Driver Architecture

5

ClientThread

Node

Node

Node

ClientThread

ClientThread

Node

Driver

Page 6: YaJug - 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: YaJug - 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: YaJug - 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, Latency Awareness, Multi Data Centers, Replica Awareness

• Cassandra Tracing Support• Compression & SSL

8

Page 9: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

DataCenter Aware Balancing

9

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 could be sent to a remote node.

Page 10: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved.

Token Aware Balancing

10

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

Node

Node

ReplicaNode

Client

Replica

Replica

Partition Key will be inferred from Prepared Statements metadata

Page 11: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 11

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 12: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 12

Connect and Write

Cluster cluster = Cluster.builder() .addContactPoints("10.1.2.5", "cassandra_node3") .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 13: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 13

Read

ResultSet resultSet = session.execute( "SELECT * FROM user WHERE user_id IN (1,8,13)");

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 14: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 14

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 15: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 15

Asynchronous Read

ResultSetFuture future = session.executeAsync( "SELECT * FROM user WHERE user_id IN (1,2,3)");

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. Returns immediately

Will block until less all the connections are busy

Page 16: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 16

Asynchronous Read with Callbacks

ResultSetFuture future = session.executeAsync( "SELECT * FROM user WHERE user_id IN (1,2,3)");

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 17: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 17

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 18: YaJug - 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

18

Page 19: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 19

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 20: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 20

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 21: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 21

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 22: YaJug - Cassandra for Java Developers

© 2014 DataStax, All Rights Reserved. 22

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 23: YaJug - Cassandra for Java Developers

DataStax DevCenterDemo

Page 24: YaJug - Cassandra for Java Developers

We’re Hiring!

@mfiguiere

blog.datastax.com

github.com/datastax

…seriously I really mean it, so if you’re passionated about beautiful technology feel free to talk to me!

Work remotely from anywhere in Europe, even Luxembourg…