Skip to content
Luke Bakken edited this page Feb 23, 2015 · 4 revisions

In the section on basic query operations we briefly touched on n, r, and w configuration parameters. Just to recap:

  • n is the number of virtual nodes in the Riak cluster that will store data
  • r is the number of nodes that must respond to a read request before data is returned to the client
  • w is the number of nodes that must respond to a write request before the record can be safely considered to be written

Every request accepts a value for these parameters, but if the parameters aren't present RIak will make some assumptions about how it should behave. By default, Riak assumes that n, r, and w are set to 2 (technically it defaults to (n/2) + 1, but who's checking?). You can change this behavior at the Riak cluster level by modifying the default_bucket_props section of riak_core_settings in app.config or on a per bucket basis.

Changing Bucket Behavior

Not only can bucket properties change n, r, and w semantics, but they can also be used to set pre and post commit hooks, enable Riak Search, and change sibling semantics.

Available Bucket Properties

A number of properties are available at the bucket level:

  • LastWriteWins - When set to true, riak will ignore vector clocks and cheerfully overwrite data. When LastWriteWins is false, siblings may be created if conflicts exist within Riak. LastWriteWins defaults to false and should only be used for write-once, immutable data.
  • AllowMultiple - If this is true, it's possible for siblings to be created by concurrent updates. AllowMultiple defaults to false.
  • Search - Setting this to true will enable Riak Search for a single bucket, but it won't index the contents of the bucket. Refer to Riak Search - Indexing for details. Riak Search is disabled by default.
  • NotFoundOk - When set to true, an object not being found on a Riak node will count towards the r count. NotFoundOk defaults to true.
  • BasicQuorum - This tells Riak to return early in certain failure conditions. E.g. if r = 1 and Riak returns two errors and a success, having BasicQuorum set to true would return an error.
  • Backend - If you've configured riak to use the riak_kv_multi_backend setting, it's possible to change the backend on a bucket by bucket basis. Backends are covered in [Choosing a Backend][basho_backends].
  • PreCommitHooks and PostCommitHooks - Commit hooks are loosely analagous to triggers in a relational database. They can be used to perform data validation or to take action after data has been saved.

Reading Bucket Properties

Only some properties can be loaded through the Protocol Buffers interface. The Riak .NET Client was built with speed in mind, but will default to an HTTP interface when necessary. Retrieving all bucket properties requires an HTTP request, so make sure you set the extended flag to true when you attempt to read bucket properties. If you don't the client will return null in place of the current value.

var result = Client.GetBucketProperties(bucket, true);

Setting Bucket Properties

As in any other operation in Riak, it's best to retrieve data first, verify that you aren't overwriting existing parameters, and then save the data back to Riak. To make life easier, RiakBucketProperties provides a fluent interface.

// We're making sure to grab extended properties by passing in true
var result = Client.GetBucketProperties(theBucket, true);

// Just a friendly reminder that you should always check your results
if (!result.IsSuccess)
{
	throw new Exception("Ummm... couldn't read the properties.");
}

var properties = result.Value;

properties.SetNVal(5)
		  .SetAllowMultiple(true)
		  .SetRVal("quorum")
		  .SetWVal("all");

var setResult = Client.SetBucketProperties(theBucket, properties);

if (!setResult.IsSuccess)
{
	throw new Exception("Ummm... couldn't set the properties.");
}

You'd assume that r and w need to be set to a numeric value. That's only partially true. r and w can also be set to a string so long as that string is either "all", "quorum", or "one". The default is "quorum".

There are several other bucket properties that we haven't discussed DwVal and RwVal.

DWVal is the durable write parameter. A durable write is a write that has been acknowledged as being fully written to disk - as opposed to in the operating system's file cache. Users who are particularly concerned about data durability will want to set the DwVal. By default, Riak does not wait for a durable write to be committed and, instead, trusts the operating system and the resilience provided by having multiple copies of the data on multiple servers.

RwVal is used for deletes. This is the number of replicas that must return before a delete is considered complete.

Retrieval - RiakGetOptions

The RiakGetOptions class provides a convenient way to create a set of querying options. Through RiakGetOptions it's possible to modify the behavior of the following properties:

  • r
  • pr
  • Basic Quorum
  • NotFound OK

In addition, the RiakGetOptions allow you to specify different behavior for a single Get request.

  • Head - The Head option is particularly useful if you only need to inspect the metadata of a large object. When Head is true, Riak will only return object metadata.
  • DeletedVclock - Returns an object's delete tombstone vclock, if applicable.
  • IfModified - The IfModified option allows a user to specify a single vector clock as an array of bytes. If the value stored in Riak has a different vector clock, an object will be returned. This can be useful in polling applications where you don't want to ship a large object back to the client for comparison.

Storage - RiakPutOptions

The RiakPutOptions class facilitates controlling how data is persisted in Riak.

Although it isn't documented here, users should always supply a vector clock when updating an object. This will ensure that siblings are not created. For developers, this means that a get should always precede a write, even if the get only uses the head parameter Of course, leaving the vector clock blank is a good way to deliberately create a sibling.

Through RiakPutOptions it is possible to modify the behavior of the following properties:

  • w

  • dw

  • pw

  • ReturnBody

  • ReturnHead

  • IfNotModified

  • IfNoneMatch

  • w - How many replicas must successfully acknowledge the write request before the request is deemed a success. A higher w equates to strong consistency, but slower performance.

  • dw - The dw parameter is the paranoid version of w. dw represents the number of replicas that must acknowledge that data was successfully written to durable storage (as opposed to file system cache).

  • pw - The number of primary nodes that must acknowledge a write as being successful. Both w and dw allow hinted hand off to occur and still mark a write as successful. By setting pw, the configured number primary nodes for a particular key must be online and accepting writes in order for the write to be successful.

  • ReturnBody - If ReturnBody is set to true, Riak will return the contents of the stored object. This defaults to false.

  • ReturnHead - When ReturnHead is set to true, the value for the object will be blank, but all header information will be returned to the client. This can be useful when you want to hold the vector clock of an object in memory without having to query Riak directly after saving data.

  • IfNotModified - Setting IfNotModified to true ensures that Riak will only update the data if the vector clock on disk matches the vector clock on the supplied object. This can help prevent siblings and other strange data anomalies.

  • IfNoneMatch - The object will be stored if no other bucket/key combination exists.

Clone this wiki locally