If you’re just starting, check out Part 1 and Part 2 to get up to speed on your guide to the top 5 performance challenges you might come across managing an AWS Elastic Compute Cloud (EC2), and how to best address them. We kicked off with the ins and outs of running your virtual machines in Amazon’s cloud, and how to navigate your way through a multi-tenancy environment along with managing different storage options. This week, we’ll discuss identifying the right applications run on EC2 instances for your unique workloads.
The Wrong Tool for the Job
It is quite common to see EC2 deployments that start simple and eventually evolve into mission critical components of the business. While companies often want to move into the cloud, they tend do so cautiously. This means initially creating sandbox deployments and moving non-critical applications to the cloud. The danger, however, is that as this sandbox environment grows into something more substantial that initial decisions for things like base AMIs and EC2 instance types are not re-evaluated and maintained over time. As a result, applications with certain characteristics may be running on EC2 instances not necessarily best for their workload.
Amazon has defined a host of different EC2 instance types and it is important to choose the right one for your application’s use case. Amazon has defined instance types that provide different combinations of CPU, memory, disk, and network capabilities and are categorized as follows:
- General Purpose
- Compute Optimized
- Memory Optimized
- Storage Optimized
General purpose instances are good starting points that provide a balance of compute, memory, and network resources. They come in two flavors: fixed performance and burstable performance. Fixed performance instances (M3 and M4) guarantee you specific performance capacity and are good for applications and services that require consistent capacity, such as small and mid-sized databases, data processing tasks, and backend services. Burstable performance instances (T2) provide a baseline level of CPU performance with the ability to burst above that baseline for a period of time. These instances are good for applications that vary in their compute requirements, such as development environments, build servers, code repositories, low traffic websites and web applications, microservices, early production experiments, and small databases.
Compute optimized instances (C3 and C4) provide high-powered CPUs and favor compute capacity over memory and network resources; they provide the best compute/cost value. They are best for applications that require a lot of computational power, such as high-performance front-end applications, web servers, batch processes, distributed analytics, high-performance science and engineering applications, ad serving, MMO gaming, and video encoding.
Memory optimized instances (R3) are optimized for memory-intensive applications and provide the best memory (GB) / cost value. The best use cases are high-performance databases, distributed memory caches, in-memory analytics, genome assembly and analysis, larger deployments of SAP, Microsoft SharePoint, and other enterprise applications.
GPU instances (G2) are optimized for graphics and general purpose GPU computing applications and best for 3D streaming, machine learning, video encoding, and other server-side graphics or GPU compute workloads.
Storage optimized instances come in two flavors: High I/O instances (I2) and Dense-storage instances (D2). High I/O instances provide very fast SSD-backed instance storage and are optimized for very high random I/O performance; they are best for applications like NoSQL databases (Cassandra and MongoDB), scale-out transactional databases, data warehouses, Hadoop, and cluster file systems. Dense-storage instances deliver high disk throughput and provide the best disk throughput performance; they are best for Massively Parallel Processing (MPP) data warehousing, MapReduce and Hadoop distributed computing, distributed file systems, network file systems, log, or data-processing applications.
The best strategy for selecting the best instance type is to choose the closest matching category (instance type family) from the list above, select an instance from that family, and then load test your application. Monitoring the performance of your application under load will reveal if your application is compute-bound, memory-bound, or network-bound so, if you have selected the wrong instance type family then adjust accordingly. Finally, load test results will help you choose the right sized instance within that instance family.