SlideShare a Scribd company logo
Microservices
with Node.js and Apache Cassandra
1
Jorge Bay Gondra
@jorgebg
Software Engineer, Drivers team at DataStax
© 2015 DataStax, All Rights Reserved. Company Confidential
Topics
1- Microservices
2- Why Node.js and Cassandra
3- The Node.js driver
4- Putting it all together: killr-service
2
1- Microservices
3
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
Defining microservices
4
- Service as software component
- 1 service per process
- Different data storage per service
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
From monolithic server architecture
5
- Single process contains all the logic
- Simple to develop
- Simple to deploy
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
From monolithic server architecture
6
- Large code bases
- Hard add new features
- Hard to train new developers
- Long term technology commitment
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
Why Microservices
7
- Codebase <---> teams
- Independently deployable: Versioning
- Fault isolation
- Best technology for the job
- Long lived systems, short lived services
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
But some things get harder
8
- Inter-service communication
- Deployment
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
9
Monolithic architecture
UI
Services
Data Access
Browser Monolithic Application Relational database
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
10
Monolithic architecture
Store UI Order UI Customer UI
Catalog Svc Order Svc Customer Svc
Product DA Order DA Customer DA
Browser Monolithic Application Relational database
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
11
Microservices architecture
Browser Front end Services Data storage
Order
Product
Customer
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
12
Inter-service communication
Products
Orders
Message Broker
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
Inter-service communication
13
- Event based
- Async
- Start simple
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
14
Microservices architecture
Browser Front end Services Data storage
Order
Product
Customer
Message broker
© 2015 DataStax, All Rights Reserved. Company Confidential
1- Microservices
Recap
15
- Service as component
- Deploy / Versioning
- Own your data
2- Node.js + Cassandra
16
© 2015 DataStax, All Rights Reserved. Company Confidential
2- Why Node.js and Cassandra
Node.js
17
- Single paradigm: async IO / event loop
- Minimum overhead per connection
- Predictable amount of memory usage under load
© 2015 DataStax, All Rights Reserved. Company Confidential
2- Why Node.js and Cassandra
Cassandra
18
- Tunable consistency
- No master / slave
- Fault tolerant
3- The Node.js Driver
for Apache Cassandra
19
© 2015 DataStax, All Rights Reserved. Company Confidential
3- The Node.js Driver for Cassandra
Features
20
- Automatic failover
- Node discovery
- Tunable policies
- Request pipelining
- TLS
© 2015 DataStax, All Rights Reserved. Company Confidential
3- The Node.js Driver for Cassandra
Automatic failover
21
Client 1
DC 1
DC 2
Requests
© 2015 DataStax, All Rights Reserved. Company Confidential
3- The Node.js Driver for Cassandra
Node discovery
22
Client
DC 1
Request
Events
Response
© 2015 DataStax, All Rights Reserved. Company Confidential
3- The Node.js Driver for Cassandra
Tunable policies
23
- Load balancing
- Retry
- Reconnection
© 2015 DataStax, All Rights Reserved. Company Confidential
3- The Node.js Driver for Cassandra
Load balancing policy sample
24
function BlackListPolicy(blackListedHost, childPolicy) {
this.blackListedHost = blackListedHost;
this.childPolicy = childPolicy;
}
util.inherits(BlackListPolicy, LoadBalancingPolicy);
BlackListPolicy.prototype.newQueryPlan = function (keyspace, queryOptions, callback) {
this.childPolicy.newQueryPlan(keyspace, queryOptions, function (err, iterator) {
callback(err, filter(iterator));
});
};
function *filter () {/**/}
© 2015 DataStax, All Rights Reserved. Company Confidential
3- The Node.js Driver for Cassandra
Ecmascript 6
25
- Load balancing policies: generators
- Encoding / decoding: ES6 Map / Set
© 2015 DataStax, All Rights Reserved. Company Confidential
3- The Node.js Driver for Cassandra
Request pipelining
26
Client
Sending first request
(1)
Cassandra Node
time
Received first response
(2)
© 2015 DataStax, All Rights Reserved. Company Confidential
3- The Node.js Driver for Cassandra
Recap
27
- Failover built-in
- Connection pooling
- Defaults
4- Putting it all together
Demo: Microservices with
Node.js and Cassandra Demo
28
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Functionality
29
- Video Comments
- Video Ratings
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Schema
30
CREATE TABLE comments_by_video (
videoid uuid,
commentid timeuuid,
userid uuid,
comment text,
PRIMARY KEY (videoid, commentid))
WITH CLUSTERING
ORDER BY (commentid DESC);
CREATE TABLE comments_by_user (
userid uuid,
commentid timeuuid,
videoid uuid,
comment text,
PRIMARY KEY (userid, commentid))
WITH CLUSTERING
ORDER BY (commentid DESC);
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Schema
31
CREATE TABLE video_rating (
videoid uuid,
rating_counter counter,
rating_total counter,
PRIMARY KEY (videoid));
CREATE TABLE video_ratings_by_user (
videoid uuid,
userid uuid,
rating int,
PRIMARY KEY (videoid, userid));
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Service methods
32
- GET comments by video
- POST comment
- GET rating by video
- POST rating
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
GET comments by video
33
var cassandra = require('cassandra-driver');
var client = new cassandra.Client({ contactPoints: ['localhost']});
var query = 'SELECT videoid, commentid, userid, comment FROM comments_by_video WHERE videoid = ?';
app.get('/v1/comments/:videoId([a-f0-9-]{36})', function (req, res, next) {
client.execute(query, [req.params.videoId], { prepare: true }, function (err, result) {
if (err) return next(err);
res.json(result.rows);
});
});
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
GET comments by video
34
var repository = new Repository(client);
//...
app.get('/v1/comment/:videoId([a-f0-9-]{36})', function (req, res, next) {
repository.getCommentsByVideo(req.params.videoId, function (err, comments) {
if (err) return next(err);
res.json(comments);
});
});
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
POST comment
35
app.post('/v1/comment/:videoId([a-f0-9-]{36})', function (req, res, next) {
repository.insertComment(req.params.videoId, req.body.userId, req.body.comment, (err, id) {
if (err) return next(err);
res.send(id.toString());
});
});
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Repository: Insert comment
36
Repository.prototype.insertComment = function (videoId, userId, comment, callback) {
var commentId = cassandra.types.TimeUuid.now();
var queries = [
{ query: 'INSERT INTO comments_by_video (videoid, commentid, userid, comment) VALUES (?, ?, ?, ?)',
params: [videoId, commentId, userId, comment]},
{ query: 'INSERT INTO comments_by_user (userid, commentid, videoid, comment) VALUES (?, ?, ?, ?)',
params: [userId, commentId, videoId, comment]}];
this.client.batch(queries, { prepare: true }, callback);
});
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Repository: Insert comment
37
Repository.prototype.insertComment = function (videoId, userId, comment, callback) {
var commentId = cassandra.types.TimeUuid.now();
var queries = [/*...*/];
var bus = this.bus;
this.client.batch(queries, { prepare: true }, function (err) {
if (!err) {
bus.publishNewComment(videoId, commentId, userId, comment);
}
callback(err, commentId);
});
});
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Message broker client
38
function Bus() {
}
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Message broker client
39
function Bus() {
}
Bus.prototype.publishNewComment = function (videoId, /*...*/) {
//Insert magic here
};
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Message broker client
40
function Bus() {
events.EventEmitter.call(this);
var self = this;
serverLib.on('whatever.topic.event.name', function (data) {
self.emit('whatever-client-name', data);
});
}
util.inherits(Bus, events.EventEmitter);
Bus.prototype.publishNewComment = function () {/*...*/};
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Seneca sample: GET comments
41
seneca.add( {role: 'comment', cmd: 'get'}, function (args, done) {
repository.getCommentsByVideo(args.id, done);
});
© 2015 DataStax, All Rights Reserved. Company Confidential
4- Microservices Demo
Recap
42
- 3 classes
- ~150 LoC
- Boundaries
© 2015 DataStax, All Rights Reserved. Company Confidential
Thanks
@jorgebg
github.com/jorgebay/killr-service
datastax.com/dev/blog
bit.ly/nodejs-cassandra-user
43
© 2015 DataStax, All Rights Reserved. Company Confidential
Thanks
Further reading
- Sample project: killr-service
- Presentation: Implementing Micro-Service Architecture by Fred George
- Book: Building Microservices By Sam Newman (O'Reilly)
- Article: Microservices Architecture By James Lewis and Martin Fowler
44

More Related Content

What's hot (20)

PPTX
Ibm spectrum scale fundamentals workshop for americas part 4 spectrum scale_r...
xKinAnx
 
PDF
VMware Virtual SAN Presentation
virtualsouthwest
 
PDF
Ebs12.2 online patching
aioughydchapter
 
PDF
Oracle Real Application Clusters (RAC) 12c Rel. 2 - Operational Best Practices
Markus Michalewicz
 
PDF
DevOpsMtl, Metal edition – MaaS and Juju
Leonardo Borda
 
PDF
event mesh cpi Cloud Integration – Connecting to Messaging System... - SAP Co...
HaydarV
 
PDF
Understanding oracle rac internals part 2 - slides
Mohamed Farouk
 
PDF
Traffic Control with Envoy Proxy
Mark McBride
 
PDF
PGConf APAC 2018 - Managing replication clusters with repmgr, Barman and PgBo...
PGConf APAC
 
PDF
NoSQL MeetUp
Eric DYKSTEIN
 
PPT
Galera Cluster Best Practices for DBA's and DevOps Part 1
Codership Oy - Creators of Galera Cluster
 
PPTX
Materialized Views and Secondary Indexes in Scylla: They Are finally here!
ScyllaDB
 
PPTX
Citrix XenDesktop and XenApp 7.5 Architecture Deployment
Huy Pham
 
PDF
Oracle E-Business Suite R12.2.5 on Database 12c: Install, Patch and Administer
Andrejs Karpovs
 
PDF
Nick Fisk - low latency Ceph
ShapeBlue
 
PPTX
VMware vSAN - Novosco, June 2017
Novosco
 
PDF
Sa1 chapter-5-managing-local-linux-users-and-groups-v2 (4)
Chinthaka Deshapriya (RHCA)
 
PDF
Introduction to LDAP and Directory Services
Radovan Semancik
 
PPTX
Understanding Storage I/O Under Load
ScyllaDB
 
PPT
Ibm spectrum scale fundamentals workshop for americas part 8 spectrumscale ba...
xKinAnx
 
Ibm spectrum scale fundamentals workshop for americas part 4 spectrum scale_r...
xKinAnx
 
VMware Virtual SAN Presentation
virtualsouthwest
 
Ebs12.2 online patching
aioughydchapter
 
Oracle Real Application Clusters (RAC) 12c Rel. 2 - Operational Best Practices
Markus Michalewicz
 
DevOpsMtl, Metal edition – MaaS and Juju
Leonardo Borda
 
event mesh cpi Cloud Integration – Connecting to Messaging System... - SAP Co...
HaydarV
 
Understanding oracle rac internals part 2 - slides
Mohamed Farouk
 
Traffic Control with Envoy Proxy
Mark McBride
 
PGConf APAC 2018 - Managing replication clusters with repmgr, Barman and PgBo...
PGConf APAC
 
NoSQL MeetUp
Eric DYKSTEIN
 
Galera Cluster Best Practices for DBA's and DevOps Part 1
Codership Oy - Creators of Galera Cluster
 
Materialized Views and Secondary Indexes in Scylla: They Are finally here!
ScyllaDB
 
Citrix XenDesktop and XenApp 7.5 Architecture Deployment
Huy Pham
 
Oracle E-Business Suite R12.2.5 on Database 12c: Install, Patch and Administer
Andrejs Karpovs
 
Nick Fisk - low latency Ceph
ShapeBlue
 
VMware vSAN - Novosco, June 2017
Novosco
 
Sa1 chapter-5-managing-local-linux-users-and-groups-v2 (4)
Chinthaka Deshapriya (RHCA)
 
Introduction to LDAP and Directory Services
Radovan Semancik
 
Understanding Storage I/O Under Load
ScyllaDB
 
Ibm spectrum scale fundamentals workshop for americas part 8 spectrumscale ba...
xKinAnx
 

Viewers also liked (20)

PDF
API Microservices with Node.js and Docker
Apigee | Google Cloud
 
PPTX
From Monolith to Microservices with Cassandra, Grpc, and Falcor (Luke Tillman...
DataStax
 
PDF
Getting Started with the Node.js LoopBack APi Framework
Jimmy Guerrero
 
PDF
REST vs. Messaging For Microservices
Eberhard Wolff
 
PPTX
Data Modeling for Microservices with Cassandra and Spark
Jeffrey Carpenter
 
PDF
Asynchronous Microservices in nodejs
Bruno Pedro
 
PDF
Microservices with Node.js and RabbitMQ
Paulius Uza
 
PDF
Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...
Chris Richardson
 
PDF
Building Scalable Micro-services with Nodejs
Michal Juhas
 
PPTX
Building an API in Node with HapiJS
Loc Nguyen
 
PDF
Adventures with Microservices
Anand Agrawal
 
PDF
Developing and Deploying Java applications on the Amazon Elastic Compute Clou...
Chris Richardson
 
PPTX
Building microservices with docker
Roman Melnyk
 
PDF
Odoo acces rights & groups
Lithin Thampan
 
PDF
Decomposing applications for scalability and deployability (devnexus 2013)
Chris Richardson
 
PDF
CQL: SQL In Cassandra
Eric Evans
 
PPTX
Microservice architecture case study
Rudra Tripathy
 
PDF
Monitoring microservices platform
Boyan Dimitrov
 
PPTX
Developing Enterprise Applications for the Cloud, from Monolith to Microservices
David Currie
 
PDF
Lessons Learned: Using Spark and Microservices
Alexis Seigneurin
 
API Microservices with Node.js and Docker
Apigee | Google Cloud
 
From Monolith to Microservices with Cassandra, Grpc, and Falcor (Luke Tillman...
DataStax
 
Getting Started with the Node.js LoopBack APi Framework
Jimmy Guerrero
 
REST vs. Messaging For Microservices
Eberhard Wolff
 
Data Modeling for Microservices with Cassandra and Spark
Jeffrey Carpenter
 
Asynchronous Microservices in nodejs
Bruno Pedro
 
Microservices with Node.js and RabbitMQ
Paulius Uza
 
Handling Eventual Consistency in JVM Microservices with Event Sourcing (javao...
Chris Richardson
 
Building Scalable Micro-services with Nodejs
Michal Juhas
 
Building an API in Node with HapiJS
Loc Nguyen
 
Adventures with Microservices
Anand Agrawal
 
Developing and Deploying Java applications on the Amazon Elastic Compute Clou...
Chris Richardson
 
Building microservices with docker
Roman Melnyk
 
Odoo acces rights & groups
Lithin Thampan
 
Decomposing applications for scalability and deployability (devnexus 2013)
Chris Richardson
 
CQL: SQL In Cassandra
Eric Evans
 
Microservice architecture case study
Rudra Tripathy
 
Monitoring microservices platform
Boyan Dimitrov
 
Developing Enterprise Applications for the Cloud, from Monolith to Microservices
David Currie
 
Lessons Learned: Using Spark and Microservices
Alexis Seigneurin
 
Ad

Similar to Microservices with Node.js and Apache Cassandra (20)

PDF
Paris Cassandra Meetup - Cassandra for Developers
Michaël Figuière
 
PPTX
Patterns for Persistence and Streaming in Microservice Architectures
Jeffrey Carpenter
 
PDF
ChtiJUG - Cassandra 2.0
Michaël Figuière
 
PPTX
Data Con LA 2019 - Patterns for Persistence and Streaming in Cloud Architectu...
Data Con LA
 
PPTX
DataStax NYC Java Meetup: Cassandra with Java
carolinedatastax
 
PDF
Geneva JUG - Cassandra for Java Developers
Michaël Figuière
 
PDF
YaJug - Cassandra for Java Developers
Michaël Figuière
 
PDF
Cassandra Community Webinar: From Mongo to Cassandra, Architectural Lessons
DataStax
 
PDF
Cassandra introduction 2016
Duyhai Doan
 
PPTX
VoxxedDays Luxembourg 2019
Cédrick Lunven
 
PDF
Cassandra: An Alien Technology That's not so Alien
Brian Hess
 
PDF
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
Red Hat Developers
 
PDF
Slides: Relational to NoSQL Migration
DATAVERSITY
 
PDF
Cassandra NodeJS driver & NodeJS Paris
Duyhai Doan
 
PDF
Apache Cassandra and The Multi-Cloud by Amanda Moran
Data Con LA
 
PDF
DataStax GeekNet Webinar - Apache Cassandra: Enterprise NoSQL
DataStax
 
PDF
From Monolith to Microservices with Cassandra, gRPC, and Falcor (from Cassand...
Luke Tillman
 
PDF
Ruby Driver Explained: DataStax Webinar May 5th 2015
DataStax
 
PDF
Cassandra drivers and libraries
Duyhai Doan
 
PDF
Five Lessons in Distributed Databases
jbellis
 
Paris Cassandra Meetup - Cassandra for Developers
Michaël Figuière
 
Patterns for Persistence and Streaming in Microservice Architectures
Jeffrey Carpenter
 
ChtiJUG - Cassandra 2.0
Michaël Figuière
 
Data Con LA 2019 - Patterns for Persistence and Streaming in Cloud Architectu...
Data Con LA
 
DataStax NYC Java Meetup: Cassandra with Java
carolinedatastax
 
Geneva JUG - Cassandra for Java Developers
Michaël Figuière
 
YaJug - Cassandra for Java Developers
Michaël Figuière
 
Cassandra Community Webinar: From Mongo to Cassandra, Architectural Lessons
DataStax
 
Cassandra introduction 2016
Duyhai Doan
 
VoxxedDays Luxembourg 2019
Cédrick Lunven
 
Cassandra: An Alien Technology That's not so Alien
Brian Hess
 
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
Red Hat Developers
 
Slides: Relational to NoSQL Migration
DATAVERSITY
 
Cassandra NodeJS driver & NodeJS Paris
Duyhai Doan
 
Apache Cassandra and The Multi-Cloud by Amanda Moran
Data Con LA
 
DataStax GeekNet Webinar - Apache Cassandra: Enterprise NoSQL
DataStax
 
From Monolith to Microservices with Cassandra, gRPC, and Falcor (from Cassand...
Luke Tillman
 
Ruby Driver Explained: DataStax Webinar May 5th 2015
DataStax
 
Cassandra drivers and libraries
Duyhai Doan
 
Five Lessons in Distributed Databases
jbellis
 
Ad

Recently uploaded (20)

PPTX
Comprehensive Guide: Shoviv Exchange to Office 365 Migration Tool 2025
Shoviv Software
 
PPTX
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
PDF
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
PDF
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
PDF
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
PPTX
The Role of a PHP Development Company in Modern Web Development
SEO Company for School in Delhi NCR
 
PPTX
Java Native Memory Leaks: The Hidden Villain Behind JVM Performance Issues
Tier1 app
 
PDF
Thread In Android-Mastering Concurrency for Responsive Apps.pdf
Nabin Dhakal
 
PPTX
Engineering the Java Web Application (MVC)
abhishekoza1981
 
PPTX
MailsDaddy Outlook OST to PST converter.pptx
abhishekdutt366
 
PPTX
Tally software_Introduction_Presentation
AditiBansal54083
 
PPTX
Revolutionizing Code Modernization with AI
KrzysztofKkol1
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PPTX
An Introduction to ZAP by Checkmarx - Official Version
Simon Bennetts
 
PPTX
A Complete Guide to Salesforce SMS Integrations Build Scalable Messaging With...
360 SMS APP
 
PDF
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
PPTX
Feb 2021 Cohesity first pitch presentation.pptx
enginsayin1
 
PPTX
Equipment Management Software BIS Safety UK.pptx
BIS Safety Software
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PDF
Capcut Pro Crack For PC Latest Version {Fully Unlocked} 2025
hashhshs786
 
Comprehensive Guide: Shoviv Exchange to Office 365 Migration Tool 2025
Shoviv Software
 
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
The Role of a PHP Development Company in Modern Web Development
SEO Company for School in Delhi NCR
 
Java Native Memory Leaks: The Hidden Villain Behind JVM Performance Issues
Tier1 app
 
Thread In Android-Mastering Concurrency for Responsive Apps.pdf
Nabin Dhakal
 
Engineering the Java Web Application (MVC)
abhishekoza1981
 
MailsDaddy Outlook OST to PST converter.pptx
abhishekdutt366
 
Tally software_Introduction_Presentation
AditiBansal54083
 
Revolutionizing Code Modernization with AI
KrzysztofKkol1
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
An Introduction to ZAP by Checkmarx - Official Version
Simon Bennetts
 
A Complete Guide to Salesforce SMS Integrations Build Scalable Messaging With...
360 SMS APP
 
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
Feb 2021 Cohesity first pitch presentation.pptx
enginsayin1
 
Equipment Management Software BIS Safety UK.pptx
BIS Safety Software
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
Capcut Pro Crack For PC Latest Version {Fully Unlocked} 2025
hashhshs786
 

Microservices with Node.js and Apache Cassandra

  • 1. Microservices with Node.js and Apache Cassandra 1 Jorge Bay Gondra @jorgebg Software Engineer, Drivers team at DataStax
  • 2. © 2015 DataStax, All Rights Reserved. Company Confidential Topics 1- Microservices 2- Why Node.js and Cassandra 3- The Node.js driver 4- Putting it all together: killr-service 2
  • 4. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices Defining microservices 4 - Service as software component - 1 service per process - Different data storage per service
  • 5. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices From monolithic server architecture 5 - Single process contains all the logic - Simple to develop - Simple to deploy
  • 6. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices From monolithic server architecture 6 - Large code bases - Hard add new features - Hard to train new developers - Long term technology commitment
  • 7. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices Why Microservices 7 - Codebase <---> teams - Independently deployable: Versioning - Fault isolation - Best technology for the job - Long lived systems, short lived services
  • 8. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices But some things get harder 8 - Inter-service communication - Deployment
  • 9. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices 9 Monolithic architecture UI Services Data Access Browser Monolithic Application Relational database
  • 10. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices 10 Monolithic architecture Store UI Order UI Customer UI Catalog Svc Order Svc Customer Svc Product DA Order DA Customer DA Browser Monolithic Application Relational database
  • 11. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices 11 Microservices architecture Browser Front end Services Data storage Order Product Customer
  • 12. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices 12 Inter-service communication Products Orders Message Broker
  • 13. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices Inter-service communication 13 - Event based - Async - Start simple
  • 14. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices 14 Microservices architecture Browser Front end Services Data storage Order Product Customer Message broker
  • 15. © 2015 DataStax, All Rights Reserved. Company Confidential 1- Microservices Recap 15 - Service as component - Deploy / Versioning - Own your data
  • 16. 2- Node.js + Cassandra 16
  • 17. © 2015 DataStax, All Rights Reserved. Company Confidential 2- Why Node.js and Cassandra Node.js 17 - Single paradigm: async IO / event loop - Minimum overhead per connection - Predictable amount of memory usage under load
  • 18. © 2015 DataStax, All Rights Reserved. Company Confidential 2- Why Node.js and Cassandra Cassandra 18 - Tunable consistency - No master / slave - Fault tolerant
  • 19. 3- The Node.js Driver for Apache Cassandra 19
  • 20. © 2015 DataStax, All Rights Reserved. Company Confidential 3- The Node.js Driver for Cassandra Features 20 - Automatic failover - Node discovery - Tunable policies - Request pipelining - TLS
  • 21. © 2015 DataStax, All Rights Reserved. Company Confidential 3- The Node.js Driver for Cassandra Automatic failover 21 Client 1 DC 1 DC 2 Requests
  • 22. © 2015 DataStax, All Rights Reserved. Company Confidential 3- The Node.js Driver for Cassandra Node discovery 22 Client DC 1 Request Events Response
  • 23. © 2015 DataStax, All Rights Reserved. Company Confidential 3- The Node.js Driver for Cassandra Tunable policies 23 - Load balancing - Retry - Reconnection
  • 24. © 2015 DataStax, All Rights Reserved. Company Confidential 3- The Node.js Driver for Cassandra Load balancing policy sample 24 function BlackListPolicy(blackListedHost, childPolicy) { this.blackListedHost = blackListedHost; this.childPolicy = childPolicy; } util.inherits(BlackListPolicy, LoadBalancingPolicy); BlackListPolicy.prototype.newQueryPlan = function (keyspace, queryOptions, callback) { this.childPolicy.newQueryPlan(keyspace, queryOptions, function (err, iterator) { callback(err, filter(iterator)); }); }; function *filter () {/**/}
  • 25. © 2015 DataStax, All Rights Reserved. Company Confidential 3- The Node.js Driver for Cassandra Ecmascript 6 25 - Load balancing policies: generators - Encoding / decoding: ES6 Map / Set
  • 26. © 2015 DataStax, All Rights Reserved. Company Confidential 3- The Node.js Driver for Cassandra Request pipelining 26 Client Sending first request (1) Cassandra Node time Received first response (2)
  • 27. © 2015 DataStax, All Rights Reserved. Company Confidential 3- The Node.js Driver for Cassandra Recap 27 - Failover built-in - Connection pooling - Defaults
  • 28. 4- Putting it all together Demo: Microservices with Node.js and Cassandra Demo 28
  • 29. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Functionality 29 - Video Comments - Video Ratings
  • 30. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Schema 30 CREATE TABLE comments_by_video ( videoid uuid, commentid timeuuid, userid uuid, comment text, PRIMARY KEY (videoid, commentid)) WITH CLUSTERING ORDER BY (commentid DESC); CREATE TABLE comments_by_user ( userid uuid, commentid timeuuid, videoid uuid, comment text, PRIMARY KEY (userid, commentid)) WITH CLUSTERING ORDER BY (commentid DESC);
  • 31. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Schema 31 CREATE TABLE video_rating ( videoid uuid, rating_counter counter, rating_total counter, PRIMARY KEY (videoid)); CREATE TABLE video_ratings_by_user ( videoid uuid, userid uuid, rating int, PRIMARY KEY (videoid, userid));
  • 32. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Service methods 32 - GET comments by video - POST comment - GET rating by video - POST rating
  • 33. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo GET comments by video 33 var cassandra = require('cassandra-driver'); var client = new cassandra.Client({ contactPoints: ['localhost']}); var query = 'SELECT videoid, commentid, userid, comment FROM comments_by_video WHERE videoid = ?'; app.get('/v1/comments/:videoId([a-f0-9-]{36})', function (req, res, next) { client.execute(query, [req.params.videoId], { prepare: true }, function (err, result) { if (err) return next(err); res.json(result.rows); }); });
  • 34. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo GET comments by video 34 var repository = new Repository(client); //... app.get('/v1/comment/:videoId([a-f0-9-]{36})', function (req, res, next) { repository.getCommentsByVideo(req.params.videoId, function (err, comments) { if (err) return next(err); res.json(comments); }); });
  • 35. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo POST comment 35 app.post('/v1/comment/:videoId([a-f0-9-]{36})', function (req, res, next) { repository.insertComment(req.params.videoId, req.body.userId, req.body.comment, (err, id) { if (err) return next(err); res.send(id.toString()); }); });
  • 36. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Repository: Insert comment 36 Repository.prototype.insertComment = function (videoId, userId, comment, callback) { var commentId = cassandra.types.TimeUuid.now(); var queries = [ { query: 'INSERT INTO comments_by_video (videoid, commentid, userid, comment) VALUES (?, ?, ?, ?)', params: [videoId, commentId, userId, comment]}, { query: 'INSERT INTO comments_by_user (userid, commentid, videoid, comment) VALUES (?, ?, ?, ?)', params: [userId, commentId, videoId, comment]}]; this.client.batch(queries, { prepare: true }, callback); });
  • 37. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Repository: Insert comment 37 Repository.prototype.insertComment = function (videoId, userId, comment, callback) { var commentId = cassandra.types.TimeUuid.now(); var queries = [/*...*/]; var bus = this.bus; this.client.batch(queries, { prepare: true }, function (err) { if (!err) { bus.publishNewComment(videoId, commentId, userId, comment); } callback(err, commentId); }); });
  • 38. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Message broker client 38 function Bus() { }
  • 39. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Message broker client 39 function Bus() { } Bus.prototype.publishNewComment = function (videoId, /*...*/) { //Insert magic here };
  • 40. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Message broker client 40 function Bus() { events.EventEmitter.call(this); var self = this; serverLib.on('whatever.topic.event.name', function (data) { self.emit('whatever-client-name', data); }); } util.inherits(Bus, events.EventEmitter); Bus.prototype.publishNewComment = function () {/*...*/};
  • 41. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Seneca sample: GET comments 41 seneca.add( {role: 'comment', cmd: 'get'}, function (args, done) { repository.getCommentsByVideo(args.id, done); });
  • 42. © 2015 DataStax, All Rights Reserved. Company Confidential 4- Microservices Demo Recap 42 - 3 classes - ~150 LoC - Boundaries
  • 43. © 2015 DataStax, All Rights Reserved. Company Confidential Thanks @jorgebg github.com/jorgebay/killr-service datastax.com/dev/blog bit.ly/nodejs-cassandra-user 43
  • 44. © 2015 DataStax, All Rights Reserved. Company Confidential Thanks Further reading - Sample project: killr-service - Presentation: Implementing Micro-Service Architecture by Fred George - Book: Building Microservices By Sam Newman (O'Reilly) - Article: Microservices Architecture By James Lewis and Martin Fowler 44

Editor's Notes

  • #3: These are the high-level topics we'll be getting into: - We start with an introduction of Microservices, usage, common patterns. - Second, we continue with a case why Node.js and Apache Cassandra, and what makes them an excellent choice for Microservices. - Then, we will talk about the Node.js driver: tuning, best practices and some of the driver internals. - Finally we will put it all together in a demo, called killr-service, based on a killr-video schema used by Patrick McFadin to demonstrate data modeling technique. With this project we will try to cover what we discussed on the previous topics.
  • #4: Let's start with a brief theory microservices, there is a lot of buzz about microservices but there is no precise definition about it. There are certain characteristics that define microservices.
  • #5: Besides a hyped word, microservices is an architectural approach to develop applications using a suite of services. Each service is a component that is developed around a functionality, a unit of software that can be independently replaceable and upgradeable. Each service runs in its own process. Each service should have a different data storage. Each service generates events, that can be picked up by another microservices to perform specific actions based on it. In the following slides, we are going to describe the reasons behind this pattern.
  • #6: It's hard to talk about microservices without talking about where we all came from. We are used to build monolithic applications as a single unit, where all the logic for handling user requests go through a single process. A system with multiple software components, components that depend on each other, is relatively easy to develop and deploy. You just end up with 1 package (jar).
  • #7: But monoliths have their problems, they tend to grow big, making it hard to implement new features without a deep knowledge of the internals. Overtime, it starts to be difficult to understand how to correctly implement a change and the quality of the code declines. To add functionality for which your application was not originally designed, you are sometimes forced to "hack" into the code base. Additionally, a monolith means a long term commitment to a technology stack, making it hard to benefit from newer technology.
  • #8: This pattern allows cross functional teams to be responsible of the whole life cycle of a component, organized around a business capability. Keeping things that can change at the same time in the same module, enable us to quickly implement new changes and make the system evolve faster. That's is the reason for the microservice to have their own data, to manage schema changes independently. It is even OK to have multiple versions of the same service, online. No single point of failure, if one of the services goes down, the application can remain operative. As a microservice is loosely coupled with others, it allows teams to choose the technology stack (from the programming language to the database). Microservices architecture makes sense under the premise that system are long lived but versions of the services are short lived.
  • #9: But it is not all good news, some parts of your development life cycle do get harder. Now you have to deal with inter-service communication, each service is a different process and probably is located in a different server, so there should be a network protocol to communicate. The microservices architecture replaces 1 monolithic application but there are multiple services per application, making deployment not trivial.
  • #10: Let's look at a basic design of a monolithic architecture of server application. You can use layers to allocate different responsibilities of the application, typically: - Presentation layer - Service layer - Data access layer
  • #11: Each layer has different components. Components can call each other and boundaries are not defined in the design. For example the order service can call the products, order and customer data access to process an order.
  • #12: Now, lets consider the microservice architecture, this looks simple enough. Components are functionally decomposed. Each service contains the logic to deal with an specific functionality. Each service with has its own data storage, you can even denote the service as the group containing the package and the database.
  • #13: Lets focus now in 2 of the services, Orders and Products. Keeping in mind that there can be multiple instances of each service running in production. If we start making direct calls from one service to the other we end up with the same problems as the monolithic pattern, plus we must implement the logic for handling other services going down, plus knowing details of other services like address / contracts. [Next] That is why we should introduce a message broker. [Next][Next] That deals with messages coming from one service and delivers them asynchronously.
  • #14: About communication between services, there are a few principles that we can follow. We publish and consume events, for example: order made, a product has been restocked. We just have to worry about the event being received by the broker, not about what other services have to do with it. Start simple and cheap, it doesn't have to be a fancy enterprise service bus, think of it as a dumb pipe. Message queue protocol is a good fit, products like RabbitMQ/ActiveMQ are fully featured.
  • #15: Now, lets look at the complete example, focused on the Order service. The order service package communicates with a database and the message broker. The order service publish events and consume events from other services or systems.
  • #16: This pattern allow us to organize software components around business capabilities. We can deploy new versions of a service independently. Owning the data allow us to implement schema changes knowing that we won't affect other services. [Long Pause]
  • #17: What we will see in this small section is why Node.js and Cassandra are a great fit for Microservices. It will be very short because I don't want to make this presentation to turn into a Marketing or Sales presentation...
  • #18: Node.js is really good for IO Bound scenarios. There is one or few ways to implement a functionality, for example most IO libraries do not include synchronous method, just async. Node.js performs very well for high number concurrent connections, where most of the time is spent waiting for IO.
  • #19: Well, and with Cassandra: You get tunable consistency, for any given read or write operation, the we can decide how consistent the requested data must be. The peer-to-peer architecture, which can include several identical nodes, protects us from data loss. It's not just a key value store, via cql, it provides tabular outputs and a rich type system, including maps, lists, sets and user defined types. [Long Pause]
  • #20: Let’s have a quick look at the Node.js driver before trying to build our own microservice demo.
  • #21: The Node.js driver provides: - Connection pooling - Automatic failover and retry - The driver discovers the Cassandra cluster topology automatically. - Tunable load balancing, retry and reconnection policies. - Request pipelining, meaning that you can issue more than multiple requests without waiting for a response. - Client-server SSL support.
  • #22: I tried to illustrate how automatic failover works. [Next] If a Cassandra node fails or becomes unreachable [Next] the driver automatically tries other nodes in the cluster and schedules reconnections to the dead nodes in the background. It can try with another node in the same datacenter. [Next] Or, In the case the local datacenter becomes unavailable [Next] it will issue the request on a node of another datacenter.
  • #23: The Cassandra protocol is a request-response based communication mechanism but it also features notification of events. These events can be: - A new node being added. - An existing node being moved or removed - A change in the schema. - Or a node status change: a node went DOWN or back UP. To discover the nodes that are part of the cluster, the driver initially fetches the topology information and then uses this notification mechanism to keep the cluster information up to date.
  • #24: In the driver, you can select the load balancing policies, to define which node should be the coordinator of each query. The driver has 3 built-in load balancing policies: - Round robin policy - Datacenter Aware policy. - Token Aware policy. You can also create your own load balancing policy. With the retry policy, you can choose when a query should be retried when an specific error occurred. With the reconnection policy, you can define what should be the delay for the reconnection attempts, in case a node goes down.
  • #25: Here is a code sample of a load balancing policy. I don't want to dig deep into it, as you probably would not need to implement your own policy (built-in ones are suitable for most cases). But it's just a way to show you that, with a couple of lines of code, you can override the behaviour of the driver. In this case, by inheriting from LoadBalancingPolicy base class and yielding the hosts, you are able to build your own policy.
  • #26: Do you fancy Ecmascript 6? The driver enables you to use the latest ES6 features. For the load balancing policies, you can use the generators (using yield keyword), as it uses the iterator protocol. For encoding and decoding Cassandra maps and sets, you can configure the driver to use Ecmascript 6 Maps and Sets.
  • #27: Cassandra native protocol supports multiple requests to be sent without waiting for a response. This enables higher levels of parallelism with just one connection. What the graph is trying to show is that, thanks to request pipelining, the driver does not have to wait for the response to be received to issue the following requests. Other database protocols that don't support request pipelining (I don't want to name names), force clients to maintain lots of connections to the same host to achieve the same level of concurrency.
  • #28: The driver implements failover and retry, so you don't have to implement your own failover / retry functionality. The driver uses connection pooling to the Cassandra nodes, so you should reuse the same client instance and don't worry about it. The driver supports fine tuning through policies and setting, but the default policies and configuration settings are suitable for most of the use cases, so you don't need to spend time on this. [Long pause]
  • #29: Well let's try to build a demo of a microservice with Node.js and Cassandra.
  • #30: The service will focus in user feedback of videos (comments and ratings). It is based on a sample schema for a video sharing site that Patrick McFadin has been using to demonstrate data modeling techniques with Cassandra. There are other sample applications using this schema, most notably there is a live site built by Luke Tillman from DataStax: killrvideo.com And here it comes, a lot of code in presentation slides, ...
  • #31: We will be using these two column families for comments, one partitioned by videoId and the other by user. [Long Pause]
  • #32: And we will be using these two column families for ratings, the To keep the presentation short, I will be showing the code for the comments functionality and not the ratings but on GitHub you have all the functionality if you want to look into it.
  • #33: We will be using HTTP and just GET and POST verbs. We will be implement it with ExpressJS but I will also provide samples with Seneca.
  • #34: Let's start with a simple one: Expose a GET route to get all the comments and return them as JSON. We reuse the same cassandra client instance and execute using different parameters.
  • #35: Well, using the repository pattern, we moved all the logic of the data accessing and adapting of results to the repository class. We set the cassandra driver instance as a dependency to the repository class. Now, we have a cleaner code there. I made it as a personal choice to provide more concise code snippets, but we could have it all in just one module as there are very few lines of code.
  • #36: Now, lets looks at a more complete example. The routing part is very similar, we route POST requests, insert the comment and return the id of the comment. All the logic is on the repository.
  • #37: As we have a denormalized schema, we have to make 2 inserts. We execute them in a single batch, that translates into a single request to Cassandra.
  • #38: Let's complete the example of the insertion of a comment pushing a notification to the BUS, the message broker. Consumers of that event, could perform specific actions with that message: An example would be a user profile service that outputs some stats related to comments cleaning its internal cache. An example would be a service cache being cleaned before a bit of content that needs to be rendered in a webpage, in this case a new comment, changed.
  • #39: The internal implementation of a message broker client is out of scope of this presentation. But let's look into in what it should expose.
  • #40: It should expose typed methods to publish events, like the one we invoked from the repository.
  • #41: It should emit events based on server events. In this example, I'm using an imaginary library, but the idea would be to subscribe to a topic and emit an client event of that. Listeners of this event within this service could perform specific actions out of it. So that is the complete example of a service bus client class, there's a lack of real code in this example but hope it helps to build your own.
  • #42: Just as a quick note, here is the same action to retrieve comments but using SenecaJs. Seneca is a tool that separates an application into small actions. An action is not aware if it is being exposed through HTTP or any other protocol.
  • #43: Let's recap It can be traversed, the 3 classes can be setup, comment and rating. It's around 150 lines of code, it can be less without code comments and a less verbose programming style. Around a functionality… it can even splitted up into comment service and rating service.
  • #44: And that's about it, here is the link to the sample project, killr-service. Check out the DataStax dev blog, where we publish news about the Cassandra and it's drivers.