9

Looking down the road at sharding, we would like to be able to have multiple mongos instances. The recommendation seems to be to put mongos on each application server. I was thinking I'd just load balance them on their own servers, but this article http://craiggwilson.com/2013/10/21/load-balanced-mongos/ indicates that there are issue with this.

So I'm back to having it on the application servers. However, we are using Elastic Beanstalk. I could install Mongo on this as a package install. But, this creates an issue with Mongos. I have not been able to find out how to get a mongos startup going using the mongodb.conf file. For replicated servers, or config servers, additional entries in the conf file can cause it to start up the way I want. But I can't do that with Mongos. If I install Mongo, it actually starts up as mongodb. I need to kill that behaviour, and get it to start as Mongos, pointed at my config servers.

All I can think of is:

Kill the mongodb startup script, that autostarts the database in 'normal' mode. Create a new upstart script that starts up mongos, pointed at the config servers.

Any thoughts on this? Or does anyone know if I'm just being obtuse, and I can copy a new mongodb.conf file into place on beanstalk that will start up the server as mongos?

We are not planning on doing this right off the bat, but we need to prepare somewhat, as if I don't have the pieces in place, I'll need to completely rebuild my beanstalk servers after the fact. I'd rather deploy ready to go, with all the software installed.

CargoMeister
  • 4,199
  • 6
  • 27
  • 44
  • 2
    Late addition: I'm just learning, but MongoDb have a presentation which looks as though it may have useful information: http://www.mongodb.com/presentations/mongodb-and-aws-integrations (eg around slide 23 the presenter talks about load balancing) – ChrisV Oct 22 '14 at 07:43

2 Answers2

29

I created a folder called ".ebextensions" and a file called "aws.config". The contents of this file is as follows: -

files: 
  "/etc/yum.repos.d/mongodb.repo":
    mode: "000644"
    content: |
      [MongoDB]
      name=MongoDB Repository
      baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
      gpgcheck=0
      enabled=1
container_commands:
  01_enable_rootaccess:
    command: echo Defaults:root \!requiretty >> /etc/sudoers
  02_install_mongo:
    command: yum install -y mongo-10gen-server
    ignoreErrors: true
  03_turn_mongod_off:
    command: sudo chkconfig mongod off
  04_create_mongos_startup_script:
    command: sudo sh -c "echo '/usr/bin/mongos -configdb $MONGO_CONFIG_IPS -fork -logpath /var/log/mongo/mongos.log --logappend' > /etc/init.d/mongos.sh"
  05_update_mongos_startup_permissions:
    command: sudo chmod +x /etc/init.d/mongos.sh
  06_start_mongos:
    command: sudo bash /etc/init.d/mongos.sh

What this file does is: -

Runs 4 container commands (these are run after the server is created but before the WAR is deployed. These are: -

  1. Enable root access - this is required for "sudo" commands afaik.
  2. Install Mongo - install mongo as a service using the yum command. We only need "mongos" but this has not been separated yet from the mongo server. This may change in future.
  3. Change config for mongod to "off" - this means if the server restarts the mongod program isn't run if the server restarts.
  4. Create script to run mongos. Note the $MONGO_CONFIG_IPS in step 4, you can pass these in using the configuration page in Elastic Beanstalk. This will run on a server reboot.
  5. Set permissions to execute. These reason I did 4/5 as opposed to putting into into a files: section is that it did not create the IP addresses from the environment variable.
  6. Run script created in step 4.

This works for me. My WAR file simply connects to localhost and all the traffic goes through the router. I stumbled about for a couple of days on this as the documentation is fairly slim in both Amazon AWS and MongoDB.

http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html


UPDATE: - If you are having problems with my old answer, please try the following - it works for version 3 of Mongo and is currently being used in our production MongoDB cluster.

This version is more advanced in that it uses internal DNS (via AWS Route53) - note the mongo-cfg1.internal .... This is recommended best practices and well worth setting up your private zone using Route53. This means if there's an issue with one of the MongoDB Config instances you can replace the broken instance and update the private IP address in Route53 - no updates required in each elastic beanstalk which is really cool. However, if you don't want to create a zone you can simply insert the IP addresses in configDB attribute (like my first example).

files: 
  "/etc/yum.repos.d/mongodb.repo":
    mode: "000644"
    content: |
      [mongodb-org-3.0]
      name=MongoDB Repository
      baseurl=http://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/3.0/x86_64/
      gpgcheck=0
      enabled=1
  "/opt/mongos.conf":
    mode: "000755"
    content: |
      net:
        port: 27017
      operationProfiling: {}
      processManagement:
        fork: "true"
      sharding:
        configDB: mongo-cfg1.internal.company.com:27019,mongo-cfg2.internal.company.com:27019,mongo-cfg3.internal.company.com:27019
      systemLog:
        destination: file
        path: /var/log/mongos.log
container_commands:
  01_install_mongo:
    command: yum install -y mongodb-org-mongos-3.0.2
    ignoreErrors: true
  02_start_mongos:
    command: "/usr/bin/mongos -f /opt/mongos.conf > /dev/null 2>&1 &"
bobmarksie
  • 3,282
  • 1
  • 41
  • 54
  • Beautiful. Thanks, Bob. I knew there had to be a way to do this. I'll do some experimenting. One question I do have - you are starting Mongos from the command line. If the server is rebooted, how is it getting restarted? I'm wondering if you could use upstart? – CargoMeister Nov 14 '13 at 22:42
  • 2
    Well spotted CargoMeister, I've updated step 4 (and created another steps 5 and 6) so it creates a new script file in the init.d folder (slighly hacky). An alternative may be to use rc.local. – bobmarksie Nov 15 '13 at 14:24
  • This solution is not working. It is stopping the instance after completion. – Kundu Jul 07 '14 at 12:06
  • Are you sure it's not working? I have auto-scaling multiple Tomcat nodes (min 2 to max 20) for almost a year successfully using this exact script ... Check your logs, especially /var/log/cfn-init.log ... – bobmarksie Jul 08 '14 at 21:33
  • I am getting the following error : 2014-07-10 12:27:06 ERROR [Instance: i-79b42072 Module: AWSEBAutoScalingGroup ConfigSet: null] Command failed on instance. Return code: 1 Output: Error occurred during build: Command 06_start_mongos failed . 2014-07-10 12:27:06 INFO Command execution completed. Summary: [Successful: 0, Failed: 1]. – Kundu Jul 10 '14 at 07:01
  • 1
    OK, so step 4 creates the mongos.sh script which is created from the MONGO_CONFIG_IPS which you create in via the elastic search configuration. It's worth trying to run this script manually and seeing the error that way (it might not have saved the correct config ip addresses). – bobmarksie Jul 10 '14 at 15:33
  • 1
    Thanks @bobmarksie, your answer is much appreciated. However, I can't seem to get this working. It fails on Step6. At first, it was because there was no mongos file to run in /usr/bin/. I added 'mongodb-org-mongos' to the yum install and that fixed that. It still failed on Step6 though. Though can't figure out why now. [Image of relevant log file](http://i.imgur.com/Sg81Nk0.png). Also - could you give more detail on how we figure out what value(s) MONGO_CONFIG_IPS should be? If it's any debug help, the log file path caused issues also - I had to touch /var/log/mongo/mongos.log to avoid Error. – isTravis Aug 19 '14 at 21:28
  • I had a look at your logs. It mentioned you only had 1 config server set - try setting 3 - that's what a production mongo requires - see docs.mongodb.org/manual/core/sharded-cluster-architectures-production/ – bobmarksie Aug 22 '14 at 19:44
  • if you get ` /usr/bin/mongos: No such file or directory.` see [here](http://stackoverflow.com/questions/30391868/im-getting-an-error-while-deploying-node-js-app-with-mongodb-on-elastic-beansta?rq=1) – ErichBSchulz Oct 31 '15 at 06:07
6

I couldn't get @bobmarksie's solution to work, but thanks to anowak and avinci here for this .ebextensions/aws.config file:

files:
  "/home/ec2-user/install_mongo.sh" :
    mode: "0007555"
    owner: root
    group: root
    content: |
      #!/bin/bash
      echo "[MongoDB]
      name=MongoDB Repository
      baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
      gpgcheck=0
      enabled=1" | tee -a /etc/yum.repos.d/mongodb.repo
      yum -y update
      yum -y install mongodb-org-server mongodb-org-shell mongodb-org-tools

commands:
  01install_mongo:
    command: ./install_mongo.sh
    cwd: /home/ec2-user
    test: '[ ! -f /usr/bin/mongo ] && echo "MongoDB not installed"'

services:
  sysvinit:
    mongod:
      enabled: true
      ensureRunning: true
      commands: ['01install_mongo']
ErichBSchulz
  • 15,047
  • 5
  • 57
  • 61
  • I've updated my solution to allow for MongoDB 3.0. I'm looking at this solution and it seems to be installing an actual MongoDB server (not the MongoDB router). The problem with this solution is that elastic beanstalk is for auto-scaling i.e. if you have 3 servers, you'll have 3 separate (and temporary) MongoDB servers running on each. My solution was for a `mongo` (mongo router) which takes to a sharded cluster (via 3 config servers). See https://docs.mongodb.org/manual/core/sharded-cluster-architectures-production/ – bobmarksie Oct 31 '15 at 11:43
  • hey @bobmarksie - I'm sure you are right - I am looking at a dev system so just wanted "simplest possible solution" for the problem as stated. – ErichBSchulz Oct 31 '15 at 11:50