KEMBAR78
Cassandra NodeJS driver & NodeJS Paris | PDF
NodeJS Cassandra driver 
DuyHai DOAN, Technical Advocate 
@doanduyhai
Shameless self-promotion! 
@doanduyhai 
2 
Duy Hai DOAN 
Cassandra technical advocate 
• talks, meetups, confs 
• open-source devs (Achilles, …) 
• Cassandra technical point of contact 
duy_hai.doan@datastax.com
Agenda! 
@doanduyhai 
3 
C* quick intro 
• Cluster, Replication, Consistency, Data Model 
NodeJS Driver 
• Architecture, Streaming, API 
Live DEMO!
Cassandra history! 
@doanduyhai 
4 
NoSQL database 
• created at Facebook 
• open-sourced since 2008 
• current version = 2.1 
• column-oriented ☞ distributed table
Cassandra in 5 points! 
@doanduyhai 
5 
• Linear scalability 
• Continuous availability (≈100% up-time) 
• Multi-data centers 
• Consistent performance (99% percentile) 
• Operational simplicity
Cassandra quick intro! 
Cluster 
Replication 
Consistency
Cluster! 
@doanduyhai 
7 
Random: hash of #partition → token = hash(#p) 
Hash: ]0, 2127-1] 
Each node: 1/8 of ]0, 2127-1] 
n1 
n2 
n3 
n4 
n5 
n6 
n7 
n8
Linear scalability! 
@doanduyhai 
8 
n1 
n2 
8 nodes 10 nodes 
n3 
n4 
n5 
n6 
n7 
n8 
n1 
n2 
n3 n4 
n5 
n6 
n7 
n9 n8 
n10
Failure tolerance! 
@doanduyhai 
9 
Replication Factor (RF) = 3 
n1 
n2 
n3 
n4 
n5 
n6 
n7 
n8 
1 
2 
3
Coordinator node! 
Incoming requests (read/write) 
Coordinator node handles the request 
Every node can be coordinator àmasterless 
@doanduyhai 
n1 
n2 
n3 
n4 
n5 
n6 
n7 
n8 
1 
2 
3 
coordinator 
request
Consistency! 
@doanduyhai 
11 
Tunable at runtime 
• ONE 
• QUORUM (strict majority w.r.t. RF) 
• ALL 
Apply both to read & write
Write consistency! 
Write ONE 
• write request to all replicas in // 
• wait for ONE ack before returning to 
client 
• other acks later, asynchronously 
@doanduyhai 
n1 
n2 
n3 
n4 
n5 
n6 
n7 
n8 
1 
2 
3 
coordinator
Write consistency! 
Write QUORUM 
• write request to all replicas in // 
• wait for QUORUM acks before 
returning to client 
• other acks later, asynchronously 
@doanduyhai 
n1 
n2 
n3 
n4 
n5 
n6 
n7 
n8 
1 
2 
3 
coordinator
Read consistency! 
Read ONE 
• read from one node among all replicas 
• contact the least-loaded node (stats) 
@doanduyhai 
n1 
n2 
n3 
n4 
n5 
n6 
n7 
n8 
1 
2 
3 
coordinator
Read consistency! 
Read QUORUM 
• read from one least-loaded node 
• AND request digest from other 
replicas to reach QUORUM 
• return most up-to-date data to client 
• repair if digest mismatch n1 
@doanduyhai 
n2 
n3 
n4 
n5 
n6 
n7 
n8 
1 
2 
3 
coordinator
Consistency trade-off! 
@doanduyhai 
16
CRUD Operations! 
@doanduyhai 
17 
INSERT INTO users(login, name, age) VALUES(‘jdoe’, ‘John DOE’, 33); 
UPDATE users SET age = 34 WHERE login = jdoe; 
DELETE age FROM users WHERE login = jdoe; 
SELECT age FROM users WHERE login = jdoe;
DDL! 
@doanduyhai 
18 
CREATE TABLE users ( 
login text, 
name text, 
age int, 
… 
PRIMARY KEY(login)); 
partition key (#partition)
Cassandra NodeJS Driver! 
Architecture! 
Streaming! 
API!
Connection pooling! 
@doanduyhai 
20 
n3 
n2 
n4 
Client 
Pool1 
Pool2 
Pool3 
CallBack1 
CallBack2 
CallBack3
Request Pipelining! 
@doanduyhai 
21 
Client Cassandra
Request Pipelining! 
@doanduyhai 
22 
Client Cassandra 
StreamID 
StreamID
Nodes Discovery! 
@doanduyhai 
23 
n2 
n3 
n4 
n5 
n6 
n7 
n8 
Control Connection 
n1 Client
Round Robin Load Balancing! 
@doanduyhai 
24 
n2 
n3 
n4 
n5 
n6 
n7 
n8 
n1 Client 
1 
2 
3 
4
DC Aware Load Balancing! 
@doanduyhai 
25 
Client1 DC1 
⤫ 
Client2 DC2
DC Aware Load Balancing! 
@doanduyhai 
26 
⤫ 
Client1 DC1 
Client2 DC2
Token Aware Load Balancing! 
@doanduyhai 
27 
n2 
n3 
n4 
n5 
n6 
n7 
n8 
1 
n1 Client 
2 
3 
⤫
Combining Load Balancing Policies! 
Token Aware 
Round Robin DC Aware Round Robin 
@doanduyhai 
28 
extends 
Load Balancing Policy 
wraps 
Default config
Automatic Failover! 
@doanduyhai 
29 
n3 
n2 
n4 
Client 
Pool1 
Pool2 
Pool3 
Request 
⤫
Other policies! 
@doanduyhai 
30 
Retry policy 
• write/read timeout 
• node unavailable 
Reconnection policy 
• constant schedule 
• exponential schedule
Where do I get the driver ?! 
@doanduyhai 
31 
$ npm install cassandra-driver
Common Usage! 
@doanduyhai 
32 
var cassandra = require('cassandra-driver'); 
var client = new cassandra.Client({contactPoints: [’192.168.0.12', ’node2'], 
keyspace: ’my_keyspace'}); 
var query = 'SELECT email, last_name FROM users WHERE login=?'; 
client.execute(query, [’jdoe'], function(err, result) { 
console.log('got user with email ' + result.rows[0].email); 
});
API! 
@doanduyhai 
33 
Insert/Update 
var query = ‘’INSERT INTO sensor_data(id,date,value) VALUES(?, ?, ?)’’; 
client.query(query, 
[‘mySensor’, ‘2014-10-15 12:00:00’, 34.5], 
{prepare: true, consistency: cassandra.types.consistencies.one}, 
function(err) { //error handling });
API! 
@doanduyhai 
34 
Select 
var query = ‘’SELECT * sensor_data WHERE id = ?’’; 
client.query(query, 
[‘mySensor’], 
{prepare: true, consistency: cassandra.types.consistencies.one}, 
function(err, result) { 
result.rows.forEach(function(row) { 
console.log(‘value = ‘ + row.value); 
}); 
});
API! 
@doanduyhai 
35 
Client creation 
new cassandra.Client( 
{ 
policies: {}, // load balancing, retry, reconnection 
queryOptions: {}, // default consistency, fetchSize 
protocolOptions: {}, // port 
pooling: {}, // #connection/host 
socketOptions: {}, //timeout 
authProvider: {}, //plain text login/password, SSL 
maxPrepared: 500});
Streaming! 
@doanduyhai 
36 
var query = ‘’SELECT * FROM sensor_data‘’; 
var stream = client.stream(query, [ ], {autoPage: true}); 
Default fetchSize = 5000
Streaming! 
@doanduyhai 
37 
stream 
.on(‘end’, function() { 
//no more data 
}) 
.on(‘readable’, function() { 
while (row = this.read()) { 
// do something with the row 
} 
}) 
.on(‘error’, function(err) { 
// process error 
});
Types! 
@doanduyhai 
38 
Cassandra Javascript 
bigint Long (dCodeIO) 
blob Buffer 
boolean Boolean 
counter Long (dCodeIO) 
Decimal Buffer 
Double Number 
Float Number 
int Number 
list Array 
map Object 
set Array 
Cassandra Javascript 
text String 
timestamp Date 
timeuuid String 
uuid String 
varchar* String 
varint* Buffer 
ascii* String
Special types! 
@doanduyhai 
39 
var cassandra = require('cassandra-driver'); 
//generate a new v4 uuid 
var id1 = cassandra.types.uuid(); 
//generate a new v1 uuid 
var id2 = cassandra.types.timeuuid(); 
//big int value 
var bigIntValue = new cassandra.types.Long.fromString("5764607523034211");
Code 
demo
! " 
! 
Q & R
Thank You 
@doanduyhai 
duy_hai.doan@datastax.com

Cassandra NodeJS driver & NodeJS Paris

  • 1.
    NodeJS Cassandra driver DuyHai DOAN, Technical Advocate @doanduyhai
  • 2.
    Shameless self-promotion! @doanduyhai 2 Duy Hai DOAN Cassandra technical advocate • talks, meetups, confs • open-source devs (Achilles, …) • Cassandra technical point of contact duy_hai.doan@datastax.com
  • 3.
    Agenda! @doanduyhai 3 C* quick intro • Cluster, Replication, Consistency, Data Model NodeJS Driver • Architecture, Streaming, API Live DEMO!
  • 4.
    Cassandra history! @doanduyhai 4 NoSQL database • created at Facebook • open-sourced since 2008 • current version = 2.1 • column-oriented ☞ distributed table
  • 5.
    Cassandra in 5points! @doanduyhai 5 • Linear scalability • Continuous availability (≈100% up-time) • Multi-data centers • Consistent performance (99% percentile) • Operational simplicity
  • 6.
    Cassandra quick intro! Cluster Replication Consistency
  • 7.
    Cluster! @doanduyhai 7 Random: hash of #partition → token = hash(#p) Hash: ]0, 2127-1] Each node: 1/8 of ]0, 2127-1] n1 n2 n3 n4 n5 n6 n7 n8
  • 8.
    Linear scalability! @doanduyhai 8 n1 n2 8 nodes 10 nodes n3 n4 n5 n6 n7 n8 n1 n2 n3 n4 n5 n6 n7 n9 n8 n10
  • 9.
    Failure tolerance! @doanduyhai 9 Replication Factor (RF) = 3 n1 n2 n3 n4 n5 n6 n7 n8 1 2 3
  • 10.
    Coordinator node! Incomingrequests (read/write) Coordinator node handles the request Every node can be coordinator àmasterless @doanduyhai n1 n2 n3 n4 n5 n6 n7 n8 1 2 3 coordinator request
  • 11.
    Consistency! @doanduyhai 11 Tunable at runtime • ONE • QUORUM (strict majority w.r.t. RF) • ALL Apply both to read & write
  • 12.
    Write consistency! WriteONE • write request to all replicas in // • wait for ONE ack before returning to client • other acks later, asynchronously @doanduyhai n1 n2 n3 n4 n5 n6 n7 n8 1 2 3 coordinator
  • 13.
    Write consistency! WriteQUORUM • write request to all replicas in // • wait for QUORUM acks before returning to client • other acks later, asynchronously @doanduyhai n1 n2 n3 n4 n5 n6 n7 n8 1 2 3 coordinator
  • 14.
    Read consistency! ReadONE • read from one node among all replicas • contact the least-loaded node (stats) @doanduyhai n1 n2 n3 n4 n5 n6 n7 n8 1 2 3 coordinator
  • 15.
    Read consistency! ReadQUORUM • read from one least-loaded node • AND request digest from other replicas to reach QUORUM • return most up-to-date data to client • repair if digest mismatch n1 @doanduyhai n2 n3 n4 n5 n6 n7 n8 1 2 3 coordinator
  • 16.
  • 17.
    CRUD Operations! @doanduyhai 17 INSERT INTO users(login, name, age) VALUES(‘jdoe’, ‘John DOE’, 33); UPDATE users SET age = 34 WHERE login = jdoe; DELETE age FROM users WHERE login = jdoe; SELECT age FROM users WHERE login = jdoe;
  • 18.
    DDL! @doanduyhai 18 CREATE TABLE users ( login text, name text, age int, … PRIMARY KEY(login)); partition key (#partition)
  • 19.
    Cassandra NodeJS Driver! Architecture! Streaming! API!
  • 20.
    Connection pooling! @doanduyhai 20 n3 n2 n4 Client Pool1 Pool2 Pool3 CallBack1 CallBack2 CallBack3
  • 21.
    Request Pipelining! @doanduyhai 21 Client Cassandra
  • 22.
    Request Pipelining! @doanduyhai 22 Client Cassandra StreamID StreamID
  • 23.
    Nodes Discovery! @doanduyhai 23 n2 n3 n4 n5 n6 n7 n8 Control Connection n1 Client
  • 24.
    Round Robin LoadBalancing! @doanduyhai 24 n2 n3 n4 n5 n6 n7 n8 n1 Client 1 2 3 4
  • 25.
    DC Aware LoadBalancing! @doanduyhai 25 Client1 DC1 ⤫ Client2 DC2
  • 26.
    DC Aware LoadBalancing! @doanduyhai 26 ⤫ Client1 DC1 Client2 DC2
  • 27.
    Token Aware LoadBalancing! @doanduyhai 27 n2 n3 n4 n5 n6 n7 n8 1 n1 Client 2 3 ⤫
  • 28.
    Combining Load BalancingPolicies! Token Aware Round Robin DC Aware Round Robin @doanduyhai 28 extends Load Balancing Policy wraps Default config
  • 29.
    Automatic Failover! @doanduyhai 29 n3 n2 n4 Client Pool1 Pool2 Pool3 Request ⤫
  • 30.
    Other policies! @doanduyhai 30 Retry policy • write/read timeout • node unavailable Reconnection policy • constant schedule • exponential schedule
  • 31.
    Where do Iget the driver ?! @doanduyhai 31 $ npm install cassandra-driver
  • 32.
    Common Usage! @doanduyhai 32 var cassandra = require('cassandra-driver'); var client = new cassandra.Client({contactPoints: [’192.168.0.12', ’node2'], keyspace: ’my_keyspace'}); var query = 'SELECT email, last_name FROM users WHERE login=?'; client.execute(query, [’jdoe'], function(err, result) { console.log('got user with email ' + result.rows[0].email); });
  • 33.
    API! @doanduyhai 33 Insert/Update var query = ‘’INSERT INTO sensor_data(id,date,value) VALUES(?, ?, ?)’’; client.query(query, [‘mySensor’, ‘2014-10-15 12:00:00’, 34.5], {prepare: true, consistency: cassandra.types.consistencies.one}, function(err) { //error handling });
  • 34.
    API! @doanduyhai 34 Select var query = ‘’SELECT * sensor_data WHERE id = ?’’; client.query(query, [‘mySensor’], {prepare: true, consistency: cassandra.types.consistencies.one}, function(err, result) { result.rows.forEach(function(row) { console.log(‘value = ‘ + row.value); }); });
  • 35.
    API! @doanduyhai 35 Client creation new cassandra.Client( { policies: {}, // load balancing, retry, reconnection queryOptions: {}, // default consistency, fetchSize protocolOptions: {}, // port pooling: {}, // #connection/host socketOptions: {}, //timeout authProvider: {}, //plain text login/password, SSL maxPrepared: 500});
  • 36.
    Streaming! @doanduyhai 36 var query = ‘’SELECT * FROM sensor_data‘’; var stream = client.stream(query, [ ], {autoPage: true}); Default fetchSize = 5000
  • 37.
    Streaming! @doanduyhai 37 stream .on(‘end’, function() { //no more data }) .on(‘readable’, function() { while (row = this.read()) { // do something with the row } }) .on(‘error’, function(err) { // process error });
  • 38.
    Types! @doanduyhai 38 Cassandra Javascript bigint Long (dCodeIO) blob Buffer boolean Boolean counter Long (dCodeIO) Decimal Buffer Double Number Float Number int Number list Array map Object set Array Cassandra Javascript text String timestamp Date timeuuid String uuid String varchar* String varint* Buffer ascii* String
  • 39.
    Special types! @doanduyhai 39 var cassandra = require('cassandra-driver'); //generate a new v4 uuid var id1 = cassandra.types.uuid(); //generate a new v1 uuid var id2 = cassandra.types.timeuuid(); //big int value var bigIntValue = new cassandra.types.Long.fromString("5764607523034211");
  • 40.
  • 41.
    ! " ! Q & R
  • 42.
    Thank You @doanduyhai duy_hai.doan@datastax.com