Storing things in Riak using Erlang

Go back to Table of Contents

This article describes how to perform basic operations on Riak 0.7.1 from the Erlang client. It assumes you have installed and connected to Riak successfully from your local machine. This article also requires a basic knowledge of Erlang.

First, start up Erlang on your local machine:

erts-5.7.4/bin/erl -name riaktest -setcookie riak

Which should take you to the Erlang prompt. Then conenct to Riak:

{ok, RiakClient} = riak:client_connect('riak@192.168.1.4').

: if successful you should get back something like :

{ok,{riak_client,'riak@192.168.1.4',<<4,124,119,42>>}}

So, lets start with the basics. A Riak datastore consists of a series of buckets. So imagine that Riak is a person walking along, carrying two empty buckets, each one in each arm. So lets put something in the first bucket. First we have to tell it what the thing is, and which bucket it belong in:

Water = riak_object:new(<<"left_hand_bucket">>, <<"Water">>, "I am made of H2O" ).

: to which we get the rather ugly response :

{r_object,<<"left_hand_bucket">>,<<"Water">>,
[{r_content,{dict,0,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],[],...},
{{[],[],[],[],[],[],[],[],[],[],[],[],...}}},
"I am made of H2O"}],
[],
{dict,1,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],...},
{{[],[],[],[],[],[],[],[],[],[],[],[],[],...}}},
undefined}

: and then we put the item into the bucket with :

RiakClient:put( Water , 1).

: which returns the rather more sensible :

ok

: So now we have put something into one of the buckets. When I first saw this I did think it was a bit strange how an item in Riak was defined with its bucket, and then put into Riak, as intuitively I would have defined just water first, and then used RiakClient:put("water", "left_hand_bucket"). Also, notice that you do not create buckets indivisually first. Buckets are created automatically with the objects they contain. Anyway, lets continue. So our poor guy is walking along with one bucket heavier than the other. But how can we confirm this? Simple enter:

RiakClient:list_buckets( ).

to which I get the response:

{ok,[<<"left_hand_bucket">>
]}

: it is possible that if you have a new Riak installtion you may see :

{ok,[<<"left_hand_bucket">>,
<<"__riak_client_test__">>]}

This is because the "__riak_client_test__" bucket is created when you test Riak with bin/riak-admin test during the installation of Riak.

Ok, so now lets check to see what is in the left hand bucket.

RiakClient:list_keys(<<"left_hand_bucket">>).

: to which you should see

{ok,[<<"Water">>]}

Great, so we have successfully added something to Riak.

Now lets add the right hand bucket with:

Sand = riak_object:new(<<"right_hand_bucket">>, <<"Sand">>, "I am made of SiO2" ).

RiakClient:put( Sand , 1).

and now lets check to see the contents of Riak.

RiakClient:list_buckets( ).

to which you should see:


{ok,[<<"right_hand_bucket">>,
<<"left_hand_bucket">>
]}

And finally, to check what is in the right hand bucket:

RiakClient:list_keys(<<"right_hand_bucket">>).

to which you should see

{ok,[<<"Sand">>]}

Ok, so now our guy is happily walking along with two full buckets!


So, you have learnt the basic Riak comamnds now, which are:
  • {ok, RiakClient} = riak:client_connect('riak@192.168.1.4').
  • Water = riak_object:new(<<"left_hand_bucket">>, <<"Water">>, "I am made of H2O" ).
  • RiakClient:put( Water , 1).
  • RiakClient:list_buckets( ).
  • RiakClient:list_keys(<<"right_hand_bucket">>).
: So lets look a bit more closely at each of these:

{ok, RiakClient} = riak:client_connect('riak@192.168.1.4').

The riak:client_connect command is used to make a connection to a running Riak instance. On success you are returned RiakClient, which is an Erlang modularised parameter (look it up, uses the new keyword). If the connection fails then Erlang throws an error exception, something like:

** exception error: no match of right hand side value {error,{could_not_reach_node,'riak@192.168.1.4'}}

If you get this exception then check that the Riak node is running, and the node name and other things.



Water = riak_object:new(<<"left_hand_bucket">>, <<"Water">>, "I am made of H2O" ).
Object = riak_object:new( Bucket, Key, Value).

riak_object:new creates a new object in Erlang, but does not store it in Riak until a put command is issued. Anyway, the thing to note here is that the bucket name and key name must be stored in binary using the Erlang <<" ">> syntax. In actualt fact the Key is a combination of the bucket name and the key name, and it is assocaited with the Value. We have not yet looked at how to access the Value but will do in a future article.


RiakClient:put( Water , 1).

This tells Riak to store the item Water on 1 node. This goes back to the CAP theorem. If you want redundancy on a cluster then change the 1 to a 2 or higher, but the system will take longer to save the object.


RiakClient:list_buckets( ).

Lists all the buckets in a Riak data store.


RiakClient:list_keys(<<"right_hand_bucket">>). 

Lists all the keys in a particular bucket


So I hope this article has given you a good start to understanding how to connect to Riak from Erlang.

No comments:

Post a Comment