Skip to content
seancribbs edited this page Apr 25, 2012 · 6 revisions

Connecting To Riak

At the end of this guide, you should be familiar with:

  • Connecting to the default local Riak node
  • Choosing a protocol backend/transport
  • Configuring non-default ports and hosts
  • Configuring connections to clusters

This and the other guides in this wiki assume you have Riak installed locally. If you don't have Riak already, please read and follow how to install Riak and then come back to this guide. If you haven't yet installed the client library, please do so before starting this guide.

Connect to the default local node

For ease in development and experimentation with the API, riak-client assumes that when you don't give it any configuration, it should connect to Riak on the local machine using the default ports. Let's try that out (you can enter these commands using irb or bundle console).

require 'riak'
client = Riak::Client.new
puts client.ping
# => true

ping is an operation you can use to see if the connection to Riak is working. Let's take a closer look at the client object.

puts client.inspect
# => #<Riak::Client [<#Node 127.0.0.1:8098:8087>]>

You'll see that the client connects to one node by default, using the host 127.0.0.1 (a.k.a. localhost) and ports 8098 (HTTP) and 8087 (Protocol Buffers, sometimes called "PBC").

Protocols

Riak supports two protocols: HTTP (with optional SSL), and a custom binary protocol that uses Google's Protocol Buffers as serialization format. Both protocols are supported by the Ruby client, and you can choose which one you prefer the client uses. The HTTP protocol is more feature-complete and familiar to developers and sysadmins, so the Ruby client defaults to using HTTP. Note that some client operations are ONLY executed over HTTP, even if you choose Protocol Buffers as the primary.

To change the preferred protocol, use the :protocol configuration option:

# Valid values are 'http', 'https', 'pbc'.  Use 'pbc' for Protocol Buffers.
Riak::Client.new(:protocol => 'pbc')

If you have configured SSL (HTTPS) on the Riak node, you can either specify the protocol to be 'https', or set the :ssl option to true.

Riak::Client.new(:protocol => 'https')
# or
Riak::Client.new(:ssl => true)

This will set the client to use the VERIFY_NONE SSL option when negotiating a secure connection. Generally you should change this option so as to avoid man-in-the-middle attacks over SSL, like so:

Riak::Client.new(:ssl => {:verify_mode => "peer"})

This will use your system's defaults to find certificate authority information. To be more specific, if I use a client certificate in ~/riak-client.pem and my certificate authority path is /usr/share/ca-certificates, I can change those like so:

Riak::Client.new(:ssl => {:pem => '~/riak-client.pem',
                          :ca_path => '/usr/share/ca-certificates'})

Whenever you specify a client PEM or CA information, VERIFY_PEER mode is enabled.

Backends

Internally, the Ruby client uses classes called "Backends" to translate generic client operations like "store this value under this key" or "get me the bucket properties" into messages in the appropriate protocol. There are currently three backend classes, two for HTTP and one for Protocol Buffers, and you can choose which one you use to meet your application's needs:

  • NetHTTPBackend: this uses the Net::HTTP library from the Ruby standard library, and is the default HTTP backend.
  • ExconBackend: This uses the fast Excon HTTP client by Wesley Beary.
  • BeefcakeProtobuffsBackend: This implements Riak's Protocol Buffers-based protocol in pure Ruby, using Blake Mizerany's Beefcake library for serialization.

Let's see what backends are used by default:

client = Riak::Client.new
puts client.http_backend
# => NetHTTP
puts client.protobuffs_backend
# => Beefcake

Since we want better performance out of HTTP, let's switch to the Excon-based backend:

client = Riak::Client.new(:http_backend => :Excon)
client.ping
# => true

If you don't have Excon properly installed, you'll get an exception:

RuntimeError: The Excon HTTP backend cannot be used. Please check its requirements.

Configuring non-default hosts and ports

When you deploy your application that uses Riak, you likely won't be running it on the same machine, so naturally you'd like to tell the client what other host to connect to. This might also be useful if you put some kind of load-balancer between your application and Riak. To set the hostname, use the :host configuration key:

Riak::Client.new(:host => "prod06-riak.basho.com")

This will still connect to the default ports however, so we can set those using :http_port and :pb_port, assuming our ops team changed them:

Riak::Client.new(:host => "prod06-riak.basho.com",
                 :http_port => 18098,
                 :pb_port => 28087)

Connecting to clusters

Riak's biggest strength is the ability to scale out linearly as you need more capacity, so why should your client be limited to connecting to a single node? Luckily, all the examples above are just a convenience for defining a client that connects to a single Riak node. What actually happens is that it connects to a list of nodes, but that list only happens to have one. All of the host/port configuration we saw above can be applied across multiple nodes as well.

Let's connect to a cluster of machines, all running on the default ports:

Riak::Client.new(:nodes => [
                   {:host => "prod01-riak.basho.com"},
                   {:host => "prod02-riak.basho.com"},
                   {:host => "prod03-riak.basho.com"}
                 ])

Now the client will manage connections to all three node we configured, and balance requests between them. Furthermore, if a single node goes down, requests that fail for transport-related reasons can be retried on another host, which makes your application lots more resilient to outages.

The balancing logic tracks an exponentially decaying success score for each node, so while the node is down, it will be less likely to be chosen. If the node comes back, that same decaying score will cause it to eventually start receiving requests again.

HTTP and Protocol Buffers ports can also be changed per node:

Riak::Client.new(:nodes => [
                   {:host => "prod01-riak.basho.com", :http_port => 8091, :pb_port => 8081},
                   {:host => "prod02-riak.basho.com", :http_port => 8091, :pb_port => 8081},
                   {:host => "prod03-riak.basho.com", :http_port => 8091, :pb_port => 8081}
                 ])

Protocol and backend choice are global per client, so you cannot specify different HTTP backends for different nodes.

Riak::Client.new(:http_backend => :Excon, :protocol => "https", :nodes => nodelist)

Still confusing? Try watching this video about the multi-node connections feature.

What to do next

Congratulations, you finished the "Connecting to Riak" guide! Now that you can connect to clusters of Riak nodes, you should start storing some data.