Tuesday, November 8, 2011

Installing MongoDB with Replication on Ubuntu

Here I describe how to install MongoDB on Ubuntu, with replication. I am using a replica set with 3 nodes (2 DB servers, and 1 arbiter).
This is incredibly easy, but I figured I'd put it here in case someone else finds it useful. We are going to set up MongoDB on 3 servers for our replica set. 2 of these will actually have databases, and the third one will just be an arbiter. The DB servers will have full replication between them, the arbiter just votes on the server(s) it can see, and makes it so we don't have two servers fighting to be primary. The arbiter doesn't have to do much, so you can just toss it on any server you have in your rack. I am using Ubuntu 11.10 (Oneiric Ocelot) for my DB nodes and Ubuntu 10.04 (Lucid Lynx) for my arbiter, but these instructions should be good for any releases in between (10.10 - Maverick Meerkat, 11.04 - Natty Narwhal)

These first steps must be done on all three servers which I will refer to as dbserver1, dbserver2 and arbserver.

First we will need to add the repos. The versions of MongoDB in the official Ubuntu repos are too old to be useful. Lets create our .list file:
sudo nano /etc/apt/sources.list.d/mongodb.list

Now put this one line our new .list file:
deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen

We now need to add 10 Gen's GPG key:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10

Now, we can install:
sudo apt-get update
sudo apt-get install mongodb-10gen

We now need to edit /etc/mongodb.conf on each server, to add our replica set info.
sudo nano /etc/mongodb.conf

Add these lines to turn on REST (so we can see the status of our replica set, amongst other things) anywhere in the config.
# enable rest
rest = true

At the bottom of the config, we need to uncomment the replSet option and define our replica set name(use whatever you want), like so:
replSet = myset

Restart the MongoDB service on each server.
sudo service mongodb restart

Now on dbserver1, we will set up the actual set, like so:
$ mongo --host 127.0.0.1
> rs.initiate()
{
    "info2" : "no configuration explicitly specified -- making one",
    "me" : "dbserver1:27017",
    "info" : "Config now saved locally.  Should come online in about a minute.",
    "ok" : 1
}
> rs.add("dbserver2")
{ "ok" : 1 }
PRIMARY> rs.addArb("arbserver")
{ "down" : [ "arbserver:27017" ], "ok" : 1 }
> exit

And that's it. You can check the status on the replica set from a web browser, http://dbserver1:28017/_replSet

You can also set one server with a higher priority, so it will always be primary when all servers are up (another server will become primary if it is down). To do that simply connect to your primary server again (dbserver1).
mongo --host 127.0.0.1

Now we will double-check the id:
PRIMARY> rs.conf()
{
        "_id" : "rdset",
        "version" : 4,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "dbserver1:27017",
                        "priority" : 2
                },
                {
                        "_id" : 1,
                        "host" : "dbserver2:27017"
                },
                {
                        "_id" : 2,
                        "host" : "arbserver:27017",
                        "arbiterOnly" : true
                }
        ]
}
Now use that ID in the following command:
PRIMARY> cfg.members[0].priority = 2
2
PRIMARY> rs.reconfig(cfg)
{ "ok" : 1 }

PRIMARY> exit

Now you can check the status again by going to http://dbserver1:28017/_replSet. After setting up a new priority, my arbiter was having issues connecting. I think you may just have to wait a few minutes for it to come back up, because after ~5-10 minutes, it showed as connected again. If not, you may have to restart the service on the server that is not connecting:
sudo service mongodb restart

2 comments:

  1. On Ubuntu 11.10 you need to specify cfg var before updating priority

    cfg = rs.conf()

    ReplyDelete