On Github jweaver / captheorem-tech-talk
Created by Jack Weaver / @teh_jack
Hosted at http://captheorem-jweaver.rhcloud.com
Presented by Eric Brewer in 2000, essentially states for a distributed system, Consistency, Availability and Partition-tolerance cannot be "achieved" all at the same time.
This is not the same as "pick 2", since in distributed systems we will have to deal with partitions.Across all nodes in the system, the data is consistent (they see the same state of the data).
All operations on the data store eventually return something. It's "available" for writes, etc, for non-failing nodes.
Despite some communication failures, or node crashes, service still performs as expected.
Networks fail sometimes, we still want systems that can withstand those failures. Same applies to individual nodes (from the system's view, a node failure is no different than a network failure)
In an asynchronous network, with a distributed system, it is impossible to implement a "read/write" data object that guarantees the following properties:
Availability in all normal situations Atomic Consistency in all normal situations in which no messages are lost*. It's easy to drop the message until the system regains connectivityvar Db = require('mongodb').Db, MongoClient = require('mongodb').MongoClient, Server = require('mongodb').Server, ReplSetServers = require('mongodb').ReplSetServers, ObjectID = require('mongodb').ObjectID, Binary = require('mongodb').Binary, GridStore = require('mongodb').GridStore, Grid = require('mongodb').Grid, Code = require('mongodb').Code, BSON = require('mongodb').pure().BSON, assert = require('assert'); var db = new Db('test', new Server('locahost', 27017)); db.open(function(err, db) { // Fetch a collection to insert document into var collection = db.collection("simple_document_insert_with_function_safe"); // Insert a single document collection.insert({hello:'world' , func:function() {}}, {w:1, serializeFunctions:true}, function(err, result) { assert.equal(null, err); // Fetch the document collection.findOne({hello:'world'}, function(err, item) { assert.equal(null, err); assert.ok("function() {}", item.code); db.close(); }) }); });w, {Number/String, > -1 || ‘majority’ || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = ‘majority’ or tag acknowledges the write ~ http://mongodb.github.io/node-mongodb-native/api-generated/collection.html
On writes, attempt is made to write the row for all replicas responsible for that row.
If those replica nodes are not available (partitions, etc), then a "hint" is stored on one node that instructs it to update the replicas when they come back up.
SELECT purchases FROM SALES USING CONSISTENCY QUORUM WHERE customer_id = 7
Consistency is decided on each read and write, it's not a system/global setting. You decide the level of consistency per action.
As engineers, we must decide the level of consistency and availability we need.
Not all "NoSQL" systems are the same, each must be evaluated for each requirement/need.
There is no free lunch, but you can minimize the symptoms with careful decisions and configurations.