How can I connect to Riak from Erlang?

Go back to Table of Contents

In order to connect to Riak from Erlang I assume that you have first successfully managed to install Riak on your local machine from one of the installation guides I have written and that you have Riak running on your local machine. On my Mac Pro I have Riak installed in:


/opt/local/bin/riak


: and I have a node in the rel directory. So if I do the following:



cd /opt/local/bin/riak
cd rel/riak
bin/riak-admin test

: then I get :

Node is not running!






: So this means that my node is not running. I start it with:


bin/riak start


: and then I test the connection again with:







bin/riak-admin test

: and I get:



=INFO REPORT==== 10-Feb-2010::16:02:34 ===
Successfully completed 1 read/write cycle to 'riak@192.168.1.3'






: Good! So now we have Erlang running locally.

Since Riak itself is written in Erlang you need to understand a bit about how Erlang works. Erlang is very similar to the Java Virtual machine, or JVM as you may know it. A JVM runs programs by executing .class files. These class files have usually been written in Java from where they are compiled to .class files. The Erlang VM is very similar in that Erlang code is compiled to Beam files, and these Beam files are run by the Erlang VM.

So, since Riak is written in Erlang this means that an Erlang VM must execute Riak Beam files to run Riak. We know this is the case as when we start Riak we issue the command:

bin/riak start

If you dig down a bit into what this actually does by opening bin/riak in a text editor you will see that it ends up calling the following command from the shell:

start) ...
$ERTS_PATH/run_erl ...

: the command run_erl starts up an Erlang Virtual Machine and runs the Riak code. Ok, granted, you did not need to know this level of detail but it is just to show you that Riak does start an Erlang VM, or "node" as it is often referred to.



So, this article is about how to connect to Riak from Erlang. Heres where it gets a bit strange, as in Erlang you can have several Erlang nodes make up a cluster, which is essentially a single system image. In Erlang all nodes which are part of the same cluster have to share just one thing, known as a cookie. This is nothing to do with your web browser cookies, or the type your grandmother made you, this is simply a way to say which Erlang nodes can talk to which other Erlang nodes.


So we need to know what the cookie is of the Riak node. This information, along with all the other information about an Erlang node is kept in the etc directory. So type:


ls etc


:and you should see something like:



app.config
vm.args






: and then type:


more etc/vm.args


: and you should get something like (this is my local Mac Pro configuration):



## Name of the riak node
-name riak@192.168.1.3


## Cookie for distributed erlang
-setcookie riak


## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive
## (Disabled by default..use with caution!)
##-heart


## Enable kernel poll and a few async threads
+K true
+A 5


## Increase number of concurrent ports/sockets
-env ERL_MAX_PORTS 4096


## Tweak GC to run more often 
-env ERL_FULLSWEEP_AFTER 10





: and so looking at the above file you can see that the cookie is set to riak. Also notice that -name is set to riak@192.168.1.3. This is the name of the Erlang node Riak is running on, and will probably be different on your own machine, maybe it will just be riak@127.0.0.1 for you. So first lets try to connect to Riak by starting a new Erlang node with the wrong cookie (riak2):


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

This will start a new Erlang shell (in a new Erlang node). Then try:

{ok, C} = riak:client_connect('riak@192.168.1.3').
:and you will see something like:

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

:and just to confirm that this node cannot see the Erlang node type:


nodes( ).


: and you should get back :


[ ]
: which means that the Erlang node you created is not attached to any other Erlang nodes. Then exit the Erlang shell by typing:


q( ).
: Now try starting an Erlang node with the correct cookie (riak) :

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

This will start a new Erlang shell again. Then try again:

{ok, C} = riak:client_connect('riak@192.168.1.3').
:and you will see something like:

{ok,{riak_client,'riak@192.168.1.3',<<4,22,140,118>>}}
: This shows that Riak is now connected. And just to confirm that this node can now see the Erlang node type:


nodes( ).

: and you should get back :

['riak@192.168.1.3']


: This shows that we can now see the Riak Erlang node.

You may have noticed that we used the erts (Erlang Run Time System) that comes with Riak. We could have started erlang using the Erlang we installed with ports as long as we include the Riak client libraries, like this:

erl -name riaktest -setcookie riak -pa /opt/local/bin/riak/apps/riak/ebin


: where the -pa option points to the Riak Erlang libraries. This path will differ depending on where you installed Riak. You can usuall find it as it contains many .beam files. But hang on on a minute! You may have noticed that we now have two copies of Erlang installed from earlier, one was where you installed Erlang, and the other copy was contained within the Riak folder, and you ran the run_erl command from here when you performed bin/riak start. You may wonder whether we needed to install the first version of Erlang at all since Riak installs its own copy. This is a good question, but you must do this as when you install Riak using make it requires Erlang to already be installed on your system. I don't know whether this is a good thing, but just rest assured that you can connect to Riak from Erlang from either of the Erlang installations, from the Riak one or the "ports" installation.

So a bit of explanation about what is happening here is probably needed. In erlang several nodes (Erlang VMS) can group together to form a cluster. These nodes do not have to be on the same machine either. However, each node must be given a unique name. When the Riak Erlang node is started on a local machine it is started with the following Erlang node name:

riak@192.168.1.3
: So to connect to Riak we need to start an Erlang VM which can talk to the Riak Erlang node. To create an Erlang cluster of nodes we need to associate them with each other in some way. In Erlang this is done by means of a cookie, which is set to the same value for all Erlang VMs in a cluster. Riak starts with the cookie called riak, and as performed in the example above, when we tried to connect to Riak from a VM with the cookie riak2 it didn't work, only when the cookie was set to riak did it work.

To further illustrate the point that the Riak node is in the same cluster as the new Erlang node then when in the erlang shell type:

net_adm:ping( 'riak@192.168.1.3' ).

: If you receive pong as a response then the Erlang shell is running in a node in the same cluster as Riak. If the Erlang shell receives a responses of pang then it is not in the same cluster as Riak. In this case try to restart the erl interpreter with setcookie riak.

To further show which nodes this Erlang node can talk to type:

nodes().

: and Erlang should show something like:

['riak@127.0.0.1']
Anyway, I hope this gives a good introduction to how to connect to Riak from Erlang.

No comments:

Post a Comment