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:
- N
- Number of nodes to replicated a piece of data
- R
- Number of nodes to read data to be considered success (read failure tolerance)
- W
- Number of nodes to write data to be considered write complete (write fault tolerance)
- PR
- Number of primary, non-fallback nodes that must return results for a successful read
- PW
- Number of primary, non-fallback nodes that must accept a write
- DW
- Number of nodes which have received an acknowledgement of the write from the storage backend
In addition, Riak exposes these additional tuning controls:
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 properties.SetNVal(3u) // Set number of nodes that must successfully written before successful write response properties.SetWVal(2u) // Set # of nodes required to read a value succesfully properties.SetRVal(1u) // Set primary read value properties.SetPrVal(1u) // Set primary write value properties.SetPwVal(1u) // Set durable write value properties.SetDwVal(1u) // Change bucket properties with these new CAP control values ciClient.SetBucketProperties("animals",properties)
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() options.SetW(3u).SetDw(1u) let data = new RiakObject("animals","toto",{nickname="Toto"; breed="Cairn Terrier"; score=5}) ciClient.Put(data,options) // Get item with R value set to 2 ciClient.Get("animals","toto",1u).Value.GetObject<Animal>() // Specify quorum let getOptions = new RiakGetOptions() getOptions.SetR("quorum") // Need to convert IRiakClient to RiakClient in order to set RiakGetOptions let client = ciClient :?> RiakClient client.Get("animals","toto",getOptions).Value.GetObject<Animal>()