Monday, June 24, 2013

Riak CAP Tuning and F#

Riak provides the ability to tune CAP. CAP, which stands for Consistency, Availability, and Partition tolerance, does not seem like controls that are tunable. These terms seem evoke images of binary choices, as in either you have it or you don't. CAP terms by itself is ambiguous in their definitions. I'm not the only one who feels that way as can be seen in Daniel Abadi's blog post. For me, it was more helpful for me to think of tradeoffs as consistency latency (time needed to achieve eventual consistency), performance (read/write latency), and node failure tolerance (how many nodes can fail and still have a working cluster).

Riak exposes their CAP tuning controls via the named variables N, R, and W. These variables are defined as follows:

Number of nodes to replicated a piece of data
Number of nodes to read data to be considered success (read failure tolerance)
Number of nodes to write data to be considered write complete (write fault tolerance)

In addition, Riak exposes these additional tuning controls:

Number of primary, non-fallback nodes that must return results for a successful read
Number of primary, non-fallback nodes that must accept a write
Number of nodes which have received an acknowledgement of the write from the storage backend

Bucket Level CAP Controls in Riak

Here's an example on how to set bucket level CAP settings in Riak with CorrugatedIron:

// Get existing bucket properties
let properties = ciClient.GetBucketProperties("animals",true).Value

// Set # of nodes a write must ultimately replicate to
// This should be set at the creation of the bucket

// Set number of nodes that must successfully written before successful write response

// Set # of nodes required to read a value succesfully

// Set primary read value

// Set primary write value

// Set durable write value

// Change bucket properties with these new CAP control values

Per Request CAP Controls in Riak

Riak allows you to tune CAP controls at per request level:

// Setting W & DW on puts
let options = new RiakPutOptions()
let data = new RiakObject("animals","toto",{nickname="Toto"; breed="Cairn Terrier"; score=5})

// Get item with R value set to 2

// Specify quorum
let getOptions = new RiakGetOptions()

// Need to convert IRiakClient to RiakClient in order to set RiakGetOptions
let client = ciClient :?> RiakClient

No comments: