Deploying MongoDB on Google Compute Engine

This solution discusses factors to consider when designing, deploying, and maintaining a MongoDB deployment, and describes ways in which you can integrate your deployment with various Google Cloud Platform services.

Designing a MongoDB deployment architecture

This section walks through MongoDB's key architectural features and provides example architectures for deploying to Cloud Platform.

Key concepts

Replica sets

MongoDB supports replication of data across multiple servers with the creation of replica sets. A replica set contains the following members:

  • A single primary instance, or primary, which contains the master copy of the data set. When a client writes new data to MongoDB, it writes that data to the primary.
  • One or more secondary instances, or secondaries, which maintain additional copies of the primary's data set. Secondaries are eventually consistent with the primary.

The primary instance is elected by voting members of the replica set. Replica sets must have an odd number of voting members. If you have an even number of primaries and secondaries, you can add a lightweight voting member, an arbiter, to help elect a primary. Unlike a primary or secondary, an arbiter is a voting-only member and doesn't store a copy of the data set.

You can configure secondaries in several ways to support your specific use case. Possible configurations include:

  • Priority zero members: A secondary can be set with priority 0, such that it never becomes the primary. Such a server can be used for reporting or to distribute read load.
  • Hidden members: A secondary can be hidden from application servers, so only dedicated clients connect to it. Such a server can be used for reporting.
  • Delayed members: A secondary can be designated to receive updates on a delayed interval. Such a server can be used to remedy user error by returning MongoDB to a point in time.

Sharding

You must be careful when using secondaries for distributed reads. Because secondaries are only eventually consistent with the primary, they can deliver stale results. Handling stale results typically increases application complexity and can be impossible for some applications. Instead, consider sharding your data across servers.

Sharding is a database partitioning approach used by MongoDB to store data across multiple machines. By horizontally scaling your data across many servers, you are no longer limited by the read/write throughput and storage capacity of a single server. By creating separate shards, MongoDB can provide a strictly consistent view of your data while distributing read and write load over multiple servers. You can then combine sharding with replication to achieve increased write throughput while maintaining high availability.

Example architectures

Replication across regions

The following diagram demonstrates a MongoDB replica set that is distributed across multiple Compute Engine regions. In the diagram, the purple arrows designate the flow of replicated data from the MongoDB primary to the secondaries. The green arrows designate the flow of data writes from the application servers to the MongoDB primary, as well as the flow of data reads from MongoDB servers to clients.

In this example architecture, the regions are configured as follows:

  • Region 1 is the Compute Engine region where production servers reside. The majority of end-user traffic arrives at the application servers in this region. Barring a catastrophic outage, the MongoDB primary server should always be in this region.
  • Region 2 is a Compute Engine region that is geographically close to a small-but-significant portion of the user base.

In each region, the MongoDB servers are configured with replica set tags. These tags allow clients to specify their desired servers by role rather than by name.

In Region 1, the primary and secondaries each run a MongoDB server and are sized and configured identically, as either could be elected the primary. The read load from the production application servers always goes to the primary MongoDB server in the region.

In this example, an arbiter is deployed in the same zone as the other replica set members as a lower-cost voting member. As this instance contains no replica-set data and handles no end-user traffic, it is configured without a data disk and it uses the g1-small machine type.

The secondaries in Region 2 are sized and configured identically to the MongoDB instances in Region 1 to ensure they can handle the working set size and application load. Given its geographic distance from production application servers, the MongoDB instance tagged with production should never be elected primary if the instances in Region 1 are healthy. This production instance should be configured with a low priority to make it unlikely—or, using priority 0, impossible—to be elected primary.

The application servers in Region 2 are configured to read from the nearest production secondary server. This configuration improves responsiveness for applications because MongoDB queries don't have to travel across regions; however, this approach should be undertaken with great caution. Because MongoDB writes always go to the primary server, the application server software in this example must be coded appropriately to deal with reading eventually consistent data.

The secondary tagged with reporting is used to report workloads from dedicated reporting applications. This instance is configured as a hidden member with priority 0, as only reporting applications will connect to this instance.

Sharding across regions

The following diagram demonstrates a MongoDB architecture that shards data across multiple Compute Engine regions. In the diagram, the purple and blue arrows designate the flow of replicated data from the MongoDB primaries to the secondaries. The green arrows designate the flow of data writes from application servers to the MongoDB primaries, as well as the flow of data reads from MongoDB servers to clients.

In this example architecture, the regions are configured as follows:

  • Region 1 is the Compute Engine region where production servers reside. The majority of end-user traffic arrives at the application servers in this region.
  • Region 2 is a Compute Engine region which is geographically close to a small-but-significant portion of the user base.

This example assumes that the data most frequently accessed by the users in Region 1 is different than the users in Region 2. By creating two shards and using tag-aware sharding, the architecture ensures that the data that is most frequently accessed by users in Region 1 is stored in Region 1, and that the data most frequently accessed by users in Region 2 is stored in Region 2.

The MongoDB Query Router transparently routes incoming queries to the appropriate primary servers. Because the production application never reads data from a secondary server, the application never needs to handle the complexity of stale reads and eventual consistency.

The primary and secondaries each run a MongoDB server and are sized and configured identically, as either could be elected the primary for Shard A. The read load from the production application servers always goes to the primary MongoDB servers. The bulk of the client-server traffic is expected to stay within the region.

In this example, an arbiter is deployed in the same zone as the other replica set members as a lower-cost voting member. As this instance contains no replica set data and handles no end- user traffic, it is configured without a data disk and it uses the g1-small machine type.

The primary, secondaries, and arbiter for Shard B are configured identically to those in Shard A. An additional secondary is configured for both Shard A and Shard B for reporting workloads. This reporting secondary is equipped with more memory than any of the production instances. This instance is configured as a hidden member with priority 0, as only reporting applications will connect to the instance.

Deploying MongoDB to Google Cloud Platform

Choosing a machine type

Compute Engine offers multiple classes of virtual machine types for running database workloads. For MongoDB deployments, standard machine types provide a good balance of CPU and memory resources, while high-memory machine types are ideal for workloads that require more memory relative to CPUs. Compute Engine also offers custom machine types, which allow for independently scaling CPU or memory resources.

Different applications will have different demands, but adding more memory is usually a more cost-effective way to improve performance than adding more vCPU cores. MongoDB servers perform best when disk access can be minimized. To minimize disk access, size your MongoDB server instances such that the active working data set can be kept in memory.

If your deployment includes MongoDB arbiter servers, consider using g1-small instances. Arbiter instances are mostly idle, exchanging heartbeat information with other MongoDB servers and only becoming significantly active for a short period when a new primary needs to be elected. Using a shared-core instance such as g1-small is an inexpensive way to reserve critical CPU cycles which are needed infrequently.

Configuring persistent disks

Persistent disks offer high-performing and consistent block storage for Compute Engine instances. Disk performance scales with the size of the disk up to the maximum capacity of its associated virtual machine.

Compute Engine persistent disks are available as either standard hard disk drives (HDD) or solid-state drives (SSD). Standard persistent disks are useful for sequential read/write workloads but are not optimal for random read/write workloads. For MongoDB deployments, SSD persistent disks are the best choice as they provide the best ratio of price to performance and can support high rates of random input/output operations per second (IOPS).

Compute Engine disks have built-in redundancy to protect data against failures and to ensure data availability through maintenance events. Data is also automatically encrypted before being written to disk, removing the need to encrypt files before writing.

When sizing disks for your MongoDB data:

  • Compute the size you need for your data.
  • Check if this disk size gives the performance you will need for writing data, journal files, and logs. If not, select a larger size that gives the performance you will need.

If the disk performance limits of your Compute Engine machine type are not sufficient for your needs, you will need to select a larger instance or shard your data.

Deploying MongoDB

You can deploy MongoDB on Cloud Platform in a few different ways:

  • Cloud Launcher for MongoDB provides the simplest entry point for deploying MongoDB, allowing you to quickly deploy a replica set through a web interface.
  • MongoDB Cloud Manager supports more complex deployments than the Cloud Launcher, such as complex replica sets or sharded clusters. However, you must provision and configure your Compute Engine instances and deploy software agents manually.
  • Google Cloud Deployment Manager lets you automate the setup of MongoDB Cloud Manager, including the resource provisioning and configuration steps that you would otherwise need to do manually.

Using Cloud Launcher for MongoDB

Google Cloud Launcher lets you quickly deploy functional software packages that run on Cloud Platform. The service allows you to easily deploy software packages in predefined configurations without having to manually configure the software, virtual machines, storage, or network settings.

Cloud Launcher for MongoDB lets you quickly deploy a replica set with up to seven virtual machines and simplifies the initial configuration steps.

By default, Cloud Launcher deploys a MongoDB replica set with a primary, secondary, and arbiter, but you can alter the configuration to fit your use case. In addition, you can choose your preferred machine types and disk types based on your desired configuration. After the replica set has been deployed, you can update the cluster configuration as needed.

Setting up MongoDB Cloud Manager

MongoDB Cloud Manager is a hosted software-as-a-service (SaaS) application that unifies MongoDB management tasks into a single interface. MongoDB Cloud Manager integrates MongoDB's configuration, query optimization, monitoring, and backup capabilities.

MongoDB Cloud Manager allows you to deploy and configure MongoDB replica sets and sharded clusters, and upgrade or downgrade clusters on demand. It also includes comprehensive monitoring that allows you to view over one hundred MongoDB metrics, complete with custom alerting and integration with other application performance monitoring solutions. MongoDB Cloud Manager also provides a fully-managed backup solution for MongoDB deployments with ongoing, incremental backups and point-in-time recovery.

To use MongoDB Cloud Manager with Google Cloud Platform:

  1. Create a MongoDB Cloud Manager account and copy the "mmsGroupId" and "mmsApiKey".
  2. Provision Compute Engine instances and persistent disks for your MongoDB cluster.
  3. Attach and configure persistent disks to each Compute Engine instance.
  4. Install and configure the MongoDB Cloud Manager Automation agent.
  5. Return to the MongoDB Cloud Manager interface and complete the cluster setup.

Bootstrapping MongoDB Cloud Manager using Deployment Manager

As an alternative to manually performing all of the steps in Setting up MongoDB Cloud Manager, you can use Cloud Deployment Manager templates to automate the provisioning and configuration of the Compute Engine instances.

Deployment Manager allows you to specify all of the resources needed for your MongoDB deployment in a declarative format. In addition, you can parameterize your templates, which allows them to take different input values and makes them more flexible and reusable. Deployment Manager templates are organized into declarative configurations comprised of resource definitions and runtime properties.

For deployments using MongoDB Cloud Manager, you can use the sample Deployment Manager templates available on Github. These templates allow you to quickly provision and configure multiple Compute Engine instances, each with a persistent SSD for data storage, and automatically install and configure the MongoDB Cloud Manager Automation Agent.

To use the Deployment Manager templates to bootstrap MongoDB Cloud Manager:

  1. Create a MongoDB Cloud Manager account and copy the "mmsGroupId" and "mmsApiKey".
  2. Clone the mongodb-cloud-manager GitHub repo.
  3. Deploy the configuration using the values you copied earlier, as described in the mongodb-cloud-manager README file.
  4. Return to the MongoDB Cloud Manager interface and complete the cluster setup.

Tuning your MongoDB deployment

To tune the performance of your MongoDB deployment on Compute Engine, start by tuning the performance of your MongoDB software. No amount of well-configured hardware can make up for an inefficient database design and insufficient or ineffective indexing. See Optimization Strategies for MongoDB for tips and best practices.

After you've settled on an appropriate MongoDB architecture that is optimized for your expected query patterns, try the following suggestions to optimize your MongoDB deployment on Google Compute Engine.

Put your MongoDB journal files and data files on the same disk

MongoDB recommends separating components onto different storage devices. However, Compute Engine's persistent disks already stripe data across a very large number of volumes, eliminating the need for you to do so manually.

MongoDB journal data is small. If you put it on its own disk, you'll either end up creating a small disk with insufficient write performance or a large disk that goes mostly unused. Put your MongoDB journal files on the same disk as your data.

Increase the maximum number of open files

Each operating system tracks open disk files and open network connections, collectively treating them as as open files. This task can require significant system resources, so the operating system enforces configurable limits on how many files can be open at a given time.

Typically, the default limits for open files are in the low thousands. However, a server running MongoDB often needs to maintain tens of thousands of open files. To increase performance, consider increasing the maximum number of open files for your MongoDB server's host operating system.

For more information, see UNIX ulimit Settings.

Decrease your TCP keepalive time

Operating systems have a heartbeat mechanism such that either end of a network connection knows that the other is still connected. How long one end can go without hearing from the other is called the keepalive. When one end of the connection has not heard from the other for a sufficient period of time, the connection will be considered dead and will be cleaned up.

A MongoDB server with a high inbound connection rate can run into a problem where the network stack has kept dead connections around too long. To prevent this, consider decreasing the TCP keepalive time from its default.

For more information, see the MongoDB Diagnostics FAQ.

Decrease your readahead cache values

When an application requests that part of a file be read from disk, the operating system typically reads more than the requested amount and caches it with the assumption that the application will soon request more of the file. This mechanism is called readahead.

Typically, MongoDB access to data on disk is random rather than sequential. This means that a large readahead is more likely to hinder performance than help it, wasting memory, CPU, and network resources on unnecessary readahead.

To avoid this unnecessary performance hit, consider decreasing the readahead values on your MongoDB data volume.

For more information, see the MongoDB Production Notes.

Shard your data early

MongoDB can shard data while continuing to service requests, and prioritizes processing end-user traffic over processing sharding requests. As such, you do not need to take your database down in order to shard.

However, sharding does use network, memory, and CPU resources. As your system grows, you end up with more data needing to be sharded using fewer resources. Depending on the size of your database and the available compute resources for your cluster, sharding can take hours or days.

With Compute Engine, you can add new virtual machine instances as you need them, and you have many choices in the amount of CPU and memory for your deployments. By monitoring your MongoDB infrastructure and configuring smaller shards over larger ones, you can keep your deployments nimble and stay on top of your resource needs.

Maintaining your MongoDB deployment

Upgrading and downgrading VM instances

Compute Engine persistent disks are independent of the instances to which they are attached, which means that you can delete a virtual machine instance, choose not to delete its associated persistent disks, and start a new instance with the same disks at a later time. In this process, the virtual machine type of the new instance need not be the same as the original instance. This can allow you to upgrade and downgrade your hardware quickly and easily.

The ability to quickly change your virtual machine type, along with MongoDB replication, means that you can easily change the virtual machine type for an entire replica set with minimal impact to production traffic. Consider the following sequence of operations:

For each secondary server:

  1. Delete the server instance, making sure to retain the attached disks.
  2. Start a new server instance with the following attributes:

    • New virtual machine type.
    • Same name, disks, network, tags, and so on.

When replication to secondary instances has caught up, perform the following tasks:

  1. Delete the primary server instance, making sure to retain the attached disks.
  2. Start a new server instance with the following attributes:

    • New virtual machine type.
    • Same name, disks, network, tags, and so on.

When the primary server is deleted, your replica set will elect a new primary from one of the secondaries whose hardware has already been upgraded or downgraded. After the original primary is restarted, it will join the replica set as a secondary.

When a MongoDB server restarts, data will not initially be in memory and will be loaded into memory on demand. This initial load can significantly impact performance. When upgrading or downgrading your VM instances by using the methods described in this section, use the touch command to explicitly bring data from storage into memory. This action improves secondary warm-up and reduces the amount of time required to complete the maintenance process.

Recovering from late sharding

As discussed in the Shard your data early section, waiting too long to shard can create a real problem for a production cluster. However, if you find yourself in this situation, you still might be able to complete sharding without impacting production traffic.

If your MongoDB servers are not already running on the largest available Compute Engine instances, try the following steps:

  1. Upgrade the virtual machines in your replica set. For example, if your instances are CPU-bound, upgrade them from the n1-standard-4 machine type to n1-standard-8. If your instances are memory-bound, upgrade them from n1-standard-4 to n1-highmem-4.
  2. Create a new replica set, and then configure MongoDB to shard to the new replica set.
  3. Downgrade the hardware for your original replica set after sharding is complete.

Assuming that upgrading your machines alleviates your immediate resource shortfall, you should have the capacity to shard with limited impact to production traffic.

Integrating MongoDB with Cloud Platform services

Integrating with Cloud Storage

You can easily export your MongoDB data to Google Cloud Storage, which offers durable and highly available object storage. Cloud Storage provides several storage classes to cover a variety of use cases:

  • Standard offers the highest level of durability, availability and performance.
  • DRA provides high durability and performance at reduced cost, but with reduced availability.
  • Nearline offers low-cost, highly durable storage for archiving, backup, and disaster recovery.

For backup and archiving, you should use Standard and Nearline respectively, exporting the data locally from a MongoDB secondary using mongodump and then uploading the data to Cloud Storage. For more information, refer to the Backup and Restore with MongoDB Tools documentation.

For analytics, use Standard, exporting the data locally from a MongoDB secondary with mongoexport as either JSON or CSV , and then uploading the flat files to Cloud Storage. After you have uploaded the exported data, you can use it with a range of additional Cloud Platform tools, including BigQuery, Cloud Dataflow, and Cloud Dataproc.

Integrating with BigQuery

BigQuery is a fully managed, petabyte-scale data warehouse that is a good choice for large-scale data analytics. You can import exported MongoDB JSON or CSV data into BigQuery and combine it with other data sources to drive ad-hoc analytics and reporting. BigQuery supports JSON natively, which means that MongoDB documents with nested objects can be stored and queried using standard SQL.

Integrating with Cloud Dataflow

Cloud Dataflow is a unified programming model and managed service for developing and executing a wide variety of data processing patterns. With Cloud Dataflow, you can create ETL or batch computation data processing pipelines and execute them using a fully managed service which dynamically provisions resources on an as-needed basis. The Cloud Dataflow programming model supports many built-in data transformations, such as statistical/mathematical aggregations, and map/shuffle/reduce-style algorithms, such as group-by and join. The programming model also supports custom and composite transformations for more complex data processing tasks. Cloud Dataflow pipelines can read input data from Cloud Storage and output processed data back to Cloud Storage, or directly into BigQuery or Cloud Bigtable.

Integrating with Cloud Dataproc

For Hadoop and Spark workloads, Cloud Dataproc provides the ability to quickly deploy clusters, resize them at any time, and delete the cluster once processing has been completed. You can launch Hadoop and Spark clusters in 90 seconds. If your job requires less than 24 hours of processing time, you can also use Compute Engine preemptible VMs in your clusters to minimize cost. Hadoop and Spark jobs can read exported MongoDB data either from Cloud Storage (BSON, JSON, or CSV) or from running MongoDB deployments directly by using the MongoDB Connector for Hadoop.

What's next?

Try out other Google Cloud Platform features for yourself. Have a look at our tutorials.

Send feedback about...