
:orphan:

.. _amazon-ec2:

==========
Amazon EC2
==========

.. default-domain:: mongodb

.. contents:: On this page
   :local:
   :backlinks: none
   :depth: 2
   :class: singlecol

To deploy MongoDB on `Amazon EC2 <http://aws.amazon.com/ec2/>`_, you
can either:

- Set up a new cluster on `MongoDB Atlas
  <https://www.mongodb.com/cloud/atlas?utm_source=amazon-ec2&utm_campaign=20-docs-in-20-days&utm_medium=docs>`_
  or live migrate an existing MongoDB deployment using the `Atlas Live
  Migration Service
  <https://www.mongodb.com/cloud/atlas/migrate?utm_source=amazon-ec2&utm_campaign=20-docs-in-20-days-migrations&utm_medium=docs>`_.

- :ref:`Set up a new instance manually install MongoDB <deploy-mongodb-ec2>`.

Deploy MongoDB on EC2 with MongoDB Atlas
----------------------------------------

`MongoDB Atlas`_ is a hosted
database as a service from the team that engineers the database. Atlas
deploys MongoDB on AWS EC2 instances. The MongoDB Atlas GUI allows you:

- Set up and manage your clusters

- Scale up or out with automated sharding

- Monitor your MongoDB deployments running in MongoDB Atlas

- Configure security controls

- Manage automated backups and failure recovery

.. image:: /figures/ec2-atlas.png
   :width: 697px

.. _deploy-mongodb-ec2:

Manually Deploy MongoDB on EC2
------------------------------

.. admonition:: Installation
   :class: Warning

   To install MongoDB on Amazon Linux, refer to the :manual:`installation
   instructions in the MongoDB manual </tutorial/install-mongodb-on-amazon>`.

.. _storage-considerations:

Storage Considerations
~~~~~~~~~~~~~~~~~~~~~~

EC2 instances can be configured with either ephemeral storage or
persistent storage using the Elastic Block Store (EBS). Ephemeral
storage is lost when instances are terminated, so it is generally not
recommended unless you understand the data loss implications.

For almost all deployments EBS will be the better choice. For
production systems we recommend using

* EBS-optimized EC2 instances
* Provisioned IOPS (PIOPS) EBS volumes

Storage configuration needs vary among deployments, but for best
performance we recommend separate volumes for *data files*, the
*journal*, and the *log*. Each has different write behavior, and
placing them on separate volumes reduces I/O contention.

.. note::

   Using different storage devices will affect your ability to create
   snapshot-style backups of your data, since the files will be on
   different devices and volumes.

For optimal performance in terms of the storage layer, use disks
backed by RAID-10. RAID-5 and RAID-6 do not typically provide
sufficient performance to support a MongoDB deployment.

Avoid RAID-0 with MongoDB deployments. While RAID-0 provides good write
performance, it also provides limited availability and can lead to
reduced performance on read operations, particularly when using
Amazon’s EBS volumes.

Backup, Restore, Verify
~~~~~~~~~~~~~~~~~~~~~~~

Depending upon the configuration of your EC2 instances, there are a
number of ways to conduct regular backups of your data. For specific
instructions on backing up, restoring and verifying refer to
:ref:`ec2-backup-and-restore`.

Instance Types
~~~~~~~~~~~~~~

MongoDB works on most 64-bit EC2 types including Linux and Windows.
Refer to the :manual:`Supported Platforms </installation>` documentation
to ensure your selected platform is compatible with your version
of MongoDB.

Running MongoDB
~~~~~~~~~~~~~~~

Before starting a :program:`mongod` instance, decide where to put your
data files.  Run :program:`df -h` to see a list of available
volumes. On some images, :file:`/mnt` will be the locally-attached
storage volume. Alternatively, you may want to use `Elastic Block Store
<http://aws.amazon.com/ebs/>`_ which will have a different mount
point.

Mounting the filesystem with the ``mount -o noatime`` option can
improve disk performance. For example, the following is an example
of an ``/etc/fstab`` stanza with this option:

.. code::

   /dev/mapper/my_vol /var/lib/mongodb xfs noatime,noexec 0 0

Create the mongodb data file directory in the desired location and then
start the :program:`mongod` server:

.. code-block:: sh

   mkdir /mnt/db
   ./mongod --fork --logpath ~/mongod.log --dbpath /mnt/db/


Operating System
~~~~~~~~~~~~~~~~

Refer to the MongoDB on Virtual Environments section of the
:manual:`Production Notes </administration/production-notes>` for
configuration recommendations.

Networking
~~~~~~~~~~

Port Management
```````````````

By default, the :program:`mongod` listens on port ``27017``. To change
the default port, use the :setting:`net.port` setting or
:option:`--port <mongod.--port>` option.

Keepalive
`````````

Change the default TCP keepalive time to 300 seconds. See our
:manual:`troubleshooting </faq/diagnostics>` page for details.

Enhanced Networking on Supported Instance Types
```````````````````````````````````````````````

When available, enable AWS's :aws-docs:`Enhanced Networking
<AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking>`
for your instance. Not all instance types support Enhanced Networking.
Refer to the :aws-docs:`AWS documentation
<AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking>`
for more information.

Secure Instances
~~~~~~~~~~~~~~~~~~

Restrict access to your instances by using the Security Groups feature
within AWS. A Security Group is a set of firewall rules for incoming
packets that can apply to TCP, UDP or ICMP.

A common approach is to create a MongoDB security group that contains
the nodes of your cluster (replica set members or sharded cluster
members), followed by the creation of a separate security group for your
app servers or clients.

Create a rule in your MongoDB security group with the "source" field set
to the Security Group name containing your app servers and the port set
to ``27017`` (or whatever port you use for your MongoDB). This will ensure
that only your app servers have permission to connect to your MongoDB
instances.

Remember that Security Groups only control ingress traffic.

Communication Across Regions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Every EC2 instance will have a private IP address that can be used to
communicate within the EC2 network. It is also possible to assign a
public "elastic" IP to communicate with the servers from another
network. If using different EC2 regions, servers can only communicate
via public IPs.

To set up a cluster of servers that spans multiple regions, it is
recommended to name the server hostname to the "public dns name"
provided by EC2. This will ensure that servers from a different network
use the public IP, while the local servers use the private IP, thereby
saving costs. This is required since EC2 security groups are local to a
region.

To control communications between instances in different regions (for
example, if you have two members of a replica set in one region and a
third member in another), it is possible to use a built-in firewall
(such as IPtables on Linux) to restrict allowed traffic to certain
(elastic) IP addresses or ports.

For example one solution is following, on each server:

* set the hostname of the server

.. code-block:: sh

   sudo hostname server1

* install "bind", it will serve as local resolver

* add a zone for your domain, say "myorg.com", and add the CNAMEs for all your servers

.. code::

   server1          IN     CNAME   ec2-50-19-237-42.compute-1.amazonaws.com.
   server2          IN     CNAME   ec2-50-18-157-87.us-west-1.compute.amazonaws.com.

* restart bind and modify /etc/resolv.conf to use the local bind

.. code::

   search myorg.conf
   nameserver 127.0.0.1

Then:

* verify that you can properly resolve server1, server2, ... using a
  tool like dig.

* when running mongod, :method:`db.serverStatus()` should show the
  correct hostname, e.g. "server1:27017".

* you can then set up replica sets or shards using the simple
  hostname. For example connect to server1 and run
  :samp:`rs.initiate()`, then :samp:`rs.add('server2:27017')`.
