RIAK & Node JS
About RIAK
Low-Latency: Riak is designed to store data and serve requests predictably and quickly, even during peak times.
Availability: Riak replicates and retrieves data intelligently, making it available for read and write operations even in failure conditions.
Fault-Tolerance: Riak is fault-tolerant so you can lose access to nodes due to network partition or hardware failure and never lose data.
Operational Simplicity: Riak allows you to add machines to the cluster easily, without a large operational burden.
Scalability: Riak automatically distributes data around the cluster and yields a near-linear performance increase as capacity is added.
HIGH AVAILABILITY
Riak is a masterless system designed to favor availability, even in the event of node failures and/or network partitions.
HIGH AVAILABILITY
Any server (“node” in Riak parlance) can serve any incoming request, regardless of data locality, and all data is replicated across multiple nodes.
HIGH AVAILABILITY
If a node experiences an outage, other nodes will continue to service write and read requests. Further, if a node becomes unavailable to the rest of the cluster, a neighboring node will take over write and update responsibilities for the missing node.
HIGH AVAILABILITY
The neighboring node will pass new or updated data (termed “objects”) back to the original node once it rejoins the cluster through a process called “hinted handoff.”
EVENTUAL CONSISTENCY
EVENTUAL CONSISTENCY
In a distributed and fault-tolerant environment like Riak, the unexpected is expected.
EVENTUAL CONSISTENCY
That means that nodes may leave and join the cluster at any time, be it by accident (node failure, network partitions, etc) or administratively for cluster maintenance.
EVENTUAL CONSISTENCY
Even with one or more nodes unreachable, the cluster is still expected to accept new writes and serve reads. Furthermore, the system is expected to return the same data from all nodes eventually, even from the failed nodes after the rejoin the cluster. This is made possible by mechanisms such as hinted handoff and read-repair.
EVENTUAL CONSISTENCY
Using quorums, users can set an r and w value that adjusts the number of replicas that must respond to a read or write request for it to succeed.
For example, if Riak has been configured to store three replicas of each object, a request with an r value of 2 will only require two out of the three replicas to respond before it is considered successful. In this scenario, Riak will be able to withstand a single node failure and still operate as expected. However, should another node fail simultaneously, this same request would fail to satisfy the quorum and not return an object.
conflict resolution
When using Riak in an eventually consistent way, conflicts between object values on different nodes is unavoidable. Often, Riak can resolve these conflicts on its own internally if you use causal context, i.e. vector clocks, or dotted version vectors, when updating objects.
conflict resolution
Timestamp-based Resolution
If the allow_mult parameter is set to false, Riak resolves all object replica conflicts internally and does not return siblings to the client.
How Riak resolves those conflicts depends on the value that you set for a different bucket property, last_write_wins. If last_write_wins is set to false, Riak will resolve all conflicts on the basis of timestamps, which are attached to all Riak objects as metadata.
conflict resolution
LAST-WRITE-WINS
Another way to manage conflicts is to set allow_mult to false, as with timestamp-based resolution, while also setting the last_write_wins parameter to true. This produces a so-called last-write-wins (LWW) strategy whereby Riak foregoes the use of all internal conflict resolution strategies when making writes, effectively disregarding all previous writes.
The problem with LWW is that it will necessarily drop some writes in the case of concurrent updates in the name of preventing sibling creation. If your use case requires that your application be able to reason about differing values produced in the case of concurrent updates, then we advise against LWW as a general conflict resolution strategy.
STORING DATA
Riak stores data using a simple key/value model. Data entries in Riak are referred to as “objects.” Key/value pairs are logically grouped together in a namespace called a bucket.
As you write new keys to Riak, the object’s bucket/key pair is hashed. The resulting value maps onto a 160-bit integer space. This integer space can be conceptualized as a ring that is used to determine where data is placed on physical machines.
STORING DATA
BUCKETS
In Riak, objects are comprised of key/value pairs, which are stored in flat namespaces called “buckets.” Riak does not dictate what types of data are persisted – all objects are stored on disk as binaries.
STORING DATA
var RiakPBC = require('riakpbc');
riak = RiakPBC.createClient();
riak.put({
key: 'MIA',
bucket: 'NFL_TEAMS',
content: {
value: JSON.stringify({
name: 'Miami Dolphins',
tags: ['best', 'team', 'ever']
}),
content_type: 'application/json',
indexes: [{
key: 'tags_bin',
value: 'best'
}, {
key: 'tags_bin',
value: 'team'
}, {
key: 'tags_bin',
value: 'ever'
}, ]
},
return_body: true
}).on('data', function(data) {
console.log('PASS COMPLETE', data);
}).on('error', function(err) {
console.log('FUMBLE!!!', err);
}).on('end', function() {
console.log('TOUCH DOWN');
});
$ node put.js
PASS COMPLETE { content:
[ { value: [Object],
content_type: 'application/json',
vtag: '6CHXjk9wNSi5sWGMU9p8Uv',
last_mod: 1423795804,
last_mod_usecs: 165634,
indexes: [Object] } ],
vclock: <Buffer 6b ce 61 60 60 60 cc 60 ca 05 52 1c ca 9c ff 7e 7e 7f f3 3f 39 83 29 91 29 8f 95 21 e6 51 e0 39 be 2c 00> }
TOUCH DOWN
Getting data
var util = require('util');
var RiakPBC = require('riakpbc');
riak = RiakPBC.createClient();
riak.get({
key: 'MIA',
bucket: 'NFL_TEAMS'
}).on('data', function(data) {
console.log('PASS COMPLETE', data ); // NO CONFLICTS!
console.log('VALUE', data.content[0].value ); // NO CONFLICTS!
console.log('INDEXES', data.content[0].indexes ); // NO CONFLICTS!
}).on('error', function(err) {
console.log('FUMBLE!!!', err);
}).on('end', function() {
console.log('TOUCH DOWN');
});
$ node put.js
PASS COMPLETE { content:
[ { value: [Object],
content_type: 'application/json',
vtag: '6CHXjk9wNSi5sWGMU9p8Uv',
last_mod: 1423795804,
last_mod_usecs: 165634,
indexes: [Object] } ],
vclock: <Buffer 6b ce 61 60 60 60 cc 60 ca 05 52 1c ca 9c ff 7e 7e 7f f3 3f 39 83 29 91 29 8f 95 21 e6 51 e0 39 be 2c 00> }
TOUCH DOWN
Getting data By index
var util = require('util');
var RiakPBC = require('riakpbc');
riak = RiakPBC.createClient();
riak.getIndex({
index: 'tags_bin',
bucket: 'NFL_TEAMS',
key: 'best',
stream: true,
qtype: 0
}).on('data', function(data) {
console.log('PASS COMPLETE', data ); // NO CONFLICTS!
}).on('error', function(err) {
console.log('FUMBLE!!!', err);
}).on('end', function() {
console.log('TOUCH DOWN');
});
$ node getIndex.js
PASS COMPLETE { keys: [ 'MIA' ] }
TOUCH DOWN
Riak NODE.JS CLIENTS
- zukai — Riak ODM for Node.js from Troy Melhase
- riak-pb — Riak Protocol Buffers client for Node.js from the team at CrowdProcess
- node_riak — Voxer's production Node.js client for Riak.
- riakpbc — A simple Riak Protocol Buffer client library for Node.js
- nodiak — Supports bulk get/save/delete, sibling auto-resolution, MapReduce chaining, Search, and 2i's
- resourceful-riak — A Riak engine to the resourceful model framework from flatiron
- Connect-Riak — Riak session store for Connect backed by Riak-js
- Riak-js — Node.js client for Riak with support for HTTP and Protocol Buffers
- riak-javascript-client — Node.js HTTP client from Basho (no longer supported)
- Riakjs-model — a model abstraction around riak-js
- Node-Riak — A wrapper around Node's HTTP facilities for communicating with Riak
- Nori — Experimental Riak HTTP library for Node.js modeled after Ripple
SOURCES
Basho
http://basho.com/riak/
Riak Application Guide http://docs.basho.com/riak/latest/dev/using/application-guide/
Relational to Riak
THAT'S ALL FOLKS
QUESTIONS? @DEFSTREAM
www.hectorgray.com
EXAMPLE CODE @ http://goo.gl/1MHtHz
RIAK & Node.JS
By Hector Gray
RIAK & Node.JS
Getting up and running with Node & Riak
- 1,379