Showing posts with label Performance. Show all posts
Showing posts with label Performance. Show all posts

Saturday, May 18, 2013

Amazon EC2 AMI Copy Feature - Performance, Tips and How To


An Amazon Machine Image (AMI) is a pre-configured operating system image that is used to create an EC2 instance within the Amazon cloud environment.  AMI’s are unique per region and they not span across multiple regions, But AMI’s can be migrated across regions using the EC2 AMI copy function available as part of AWS Console, API and CLI.  This feature helps customers to maintain consistent Amazon EC2 Multi region deployments and achieve higher availability. Since user-created AMIs are assigned a unique AMI ID within the region, when you configure Auto Scaling Launch configuration or AWS CloudFormation templates in target Amazon EC2 region, it is recommended to update the AMI ID references in these configurations/templates to match the ones that exist in the target region. 

Following table illustrates the time it takes to copy EC2 AMI from Different Source and Destination Amazon EC2 regions. Data used was a 50 GB compressed file. Since AWS keeps improving their infrastructure every day, the time taken may vary in coming months/years. But the figures mentioned below can used as an reference to plan your Recovery time objectives and migrations:

EC2 AMI Copy for Different Amazon EC2 Regions Matrix:
Source Region
Destination region
Size
Time Taken
USA-East
Singapore
50 GB 
1 hr 21 min
USA-East
US-West (Oregon)
50 GB
27 min
USA-East
Europe (Ireland)
50 GB 
41 min



Important points to note while implementing this are:
  • Permissions and user-defined tags applied to the AMI in source region will not be copied to the target region during the AMI copy process. You will have to apply the permissions and tags in the target region after the copy process is completed.
  • Imagine you have stored the database connection strings, ElastiCache End points, external IP address and other Integration end points in the AMI of the source region. When you migrate this AMI to the target region these end points might not exist. Worst scenario, if these source end points are accessible over internet like S3, CloudSearch assets etc, you will end up accessing resources from target region itself. This will cause latency issues, performance problems and cost leakage.  
  • Some best practices to be followed are:
    • Prior to copying an AMI from Source region, you must manually ensure that the contents of the source AMI are updated to support running in a different region. It is recommended to add this step as part of your operation process during Cross region migration activities to avoid problems
    • Automate the download of configuration information to EC2 from S3 using user data and other scripts in the respective regions. This way when the migration happens to target region, the configuration files and scripts can be downloaded to EC2 instance from the S3 of the target region. This mechanism keeps the end points in tune with respective regions.
    • If you are running Java based environment, use NetFlix Archaius to dynamically source properties from multiple configuration stores inside an Amazon EC2 region. Archaius includes a set of java configuration management APIs and is primarily implemented as an extension of Apache's Commons Configuration Library.  Refer https://github.com/Netflix/archaius/wiki/Overview
How to use EC2 AMI Copy feature between Amazon EC2 Regions ?

Step 1) Login to the AWS Console at https://console.aws.amazon.com/ec2/
In the navigation pane, click the AMI menu under the Images section

Step 2) Select the AMI ID to copy from the source Amazon EC2 region, click Actions Button and select Copy action.

Step 3) In the EC2 AMI Copy page > Mention the destination region, Name of the AMI and Description and then click Copy
Destination Region: The Target region to which the AMI should be copied. In this case we are copying to Amazon EC2 Asia Pacific (Singapore).
Name: Name of the New Target AMI
Description: Description about the AMI. By default below description will be available for use


Step 4) When the Copy process is initiated a new AMI ID will be provided in the screen. Once noted, Click Done button

Step 5)  To check the progress of the copy process, Choose the EC2 Console of the Asia-Pacific(Destination) region and view the new AMI.
  


In the above figure we can see that Copy Status is pending. Once the copy process is completed the status will be changed to "available" from "pending".

Step 6) If you wish to cancel the copy process you can right click on the New AMI in the Source Region and select Deregister option. This will stop the AMI copy process.





Monday, April 8, 2013

Part 10: Performance Tuning Amazon Elastic Block Store - IO Block Size


The IOPS rate you get usually depends on the I/O size of your applications’ reads and writes. It is very important to know the I/O size your application operates and accordingly expect the performance from EBS Volumes. Provisioned IOPS volumes process your applications’ reads and writes in I/O sizes of 16KB blocks or less. Every increase in I/O size above 16KB will linearly increase the resources you need to achieve the same IOPS rate. For example, if you have provisioned a volume with 2000 IOPS, that means that it can handle 2000 16KB writes per second, or 1000 32KB writes per second, or 500 64KB writes per second, and so on. You can use Amazon CloudWatch to monitor your EBS Volumes throughput and I/O size for a while and decide what best suits for your case. 

Since PIOPS is especially designed for Database context, let us explore how it pans out in Amazon RDS. 

Following are some of the important points to note on PIOPS + RDS context.
P1) The theoretical maximum IOPS rate is also a function of database I/O page size and available channel bandwidth. Each page read or write constitutes one I/O operation. Database operations that read or write more than a single page will use multiple I/O operations for each database operation. For example, for a page size of 16 KB, if a read operation requires 32 KB, you would need 2000 IOPS to achieve 1000 read operations per second.
P2) If you provision an IOPS rate that is higher than the maximum or that is higher than your realized IOPS rate, you may still benefit from reduced latency and improvements in overall throughput.
Applicability of the following points and IOPS rates are based on the m2.4xlarge instance class with full duplex (1000 Mbit/second) and a workload that is perfectly balanced between reads and writes.
·         MySQL uses a page size of 16 KB and can do 12,500 IOPS. On a DB instance with a full duplex I/O channel bandwidth of 1000 megabits per second (Mbps), the maximum IOPS for page I/O is about 6,250 IOPS in each direction for 16 KB I/O. This is for a workload consisting of 50% reads and 50% writes and could reach 12,500 IOPS with 16 KB I/O.
·         Oracle uses a page size of 8KB and can do 25,000 IOPS. On a DB instance with a full duplex I/O channel bandwidth of 1000 megabits per second (Mbps), the maximum IOPS for page I/O is about 12,500 IOPS in each direction for 8 KB I/O. This is for a workload consisting of 50% reads and 50% writes and could reach 25,000 IOPS with 8 KB I/O.
·         SQL Server uses a page size of 8KB and can do 10,000 IOPS. On a DB instance with a full duplex I/O channel bandwidth of 1000 megabits per second (Mbps), the maximum IOPS for page I/O is about 5,000 IOPS in each direction for 8 KB I/O. This is for a workload consisting of 50% reads and 50% writes and could reach 10,000 IOPS with 8 KB I/O.


Part 9: Performance Tuning Amazon Elastic Block Store - EBS Striping


Software RAID systems takes number of EBS Volumes and present them as one volume to the user. A RAID 0 (known as a striped volume) splits data evenly across two or more volumes (striped) without parity information. Example: The chunks of data from the same file are distributed across the disks that form the RAID array as illustrated in the below diagram (coming soon)
By writing data in small chunks across several EBS volumes, the performance of those volumes can be aggregated. Since I/O is distributed across the volumes in a stripe manner, if you add a volume in the array, you get the straight addition of throughput as well (most times). For example, where a single PIOPS volume is restricted to its individual I/O performance and disk RPM’s, a write to an array made up of several volumes combines the I/O of all those PIOPS Volumes. So, a stripe made up of six PIOPS volumes with a throughput of 1800 IOPS each would together have a total I/O performance of up to 10800 IOPS. You can create EBS stripes on both Standard and PIOPS EBS Volumes.  Note: Performance of the stripe is limited to the worst performing volume in the set. Usually EBS Striping is chosen in cases where I/O performance is more important than fault tolerance (such as a heavily used database, Search engine servers) and where data replication is already set up separately.
To create a six-volume stripe set on Linux, use a command like the following.
$ sudo mdadm --create /dev/md0 --level=0 --chunk=64 --raid-devices=6 /dev/sdf /dev/sdg /dev/sdh /dev/sdi /dev/sdj /dev/sdk

Why 64 KB RAID chunk size?
The RAID chunk size should suit the I/O characteristics of the data you are working with. Important factor here is the size of the average I/O request you're going to place on the RAID Volume; as general rule; if you want big I/O requests, you should opt for smaller RAID chunk sizes, and if I/O will be small, you should go for larger chunks sizes.
Let me illustrate the chunk sizing with following scenarios:
Scenario 1:  Let us imagine your application works with lots of video or large image files, which means, you will need to spread data across individual volumes as much as possible. For this scenario use smaller RAID chunk sizes (for example, Block size 512 bytes-> 8 KB) because you want to take data from one volume while the others seek the next chunks to be read.
Scenario 2: Let us imagine you are running a database in which the amount of data read on each operation is small (4KB ->16KB). Here you want a single I/O to deal with one volume (drive) with one seek rather than the action is split between more than one volume and multiple seeks. So, for use cases such as databases and exchange servers, you should go for a bigger RAID chunk size say 64 KB or larger.



EBS Article Series (continued..)

Part 1: Understanding Amazon Elastic Block Store
Part 2: Understanding Standard EBS Volumes
Part 3: Understanding EBS PIOPS Volumes
Part 4: Understanding EBS-Optimized Instances
Part 5: Understanding Latency in EBS
Part 7: 10% of your provisioned IOPS 99.9% of the time
Part 8: Performance Tuning - Pre Warming the EBS volume
Part 9: Performance Tuning - EBS Striping
Part 10: Performance Tuning - IO Block Size
Part 11: Understanding Amazon EBS Snapshots
Part 12: Securing Amazon EBS volumes - EBS Encryption using SecureCloud 
Part 13: Amazon EBS Security Best practices and tips

Part 8: Performance Tuning Amazon Elastic Block Store - Pre Warming the EBS volume


New EBS Volumes always experience a “First Use Penalty” in AWS; means there will be a performance hit on the first write to an unused block on the EBS Volume and will perform slower than subsequent writes. During this time you can experience spike in volume metrics like service times, I/O latency and then subsequently leading to normalization. It is observed that 5 to 50 percent reduction in IOPS when you first access the data on a volume. Performance is restored after the data is accessed once. Therefore, it is recommended that you read or write to all the blocks on your volume before you use it.
$ dd if=/dev/md0 of=/dev/null
In Linux, the above command reads from all blocks on a volume and pre-warms the volume. On Windows, formatting the new EBS volume pre-warms it.
“dd” is not verbose by default so download and use the following script from the github, it shows the status of the pre warming of EBS Volumes, URL:  https://gist.github.com/muhqu/3293988

#!/bin/bash
if [ -z "$1" ];
  echo "Usage: sudo $0 /dev/sdh1"
  exit 1;
fi
 dd if=$1 of=/dev/null & pid=$!
while true; do
  ps -p$pid --no-heading || break;
  echo "-- $(date) ------------------";
  kill -USR1 $pid;
  sleep 60s;
done
echo "-- $(date) ------------------";
echo "DONE \o/"


Part 7: Understanding Amazon Elastic Block Store Performance: 10% of your provisioned IOPS 99.9% of the time


Understanding the 10% statement of PIOPS
“Provisioned IOPS volumes are designed to deliver within 10% of your provisioned IOPS 99.9% of the time”. In simpler terms, it means for a volume provisioned with 2000 IOPS, your volume should deliver at least 1800 IOPS 99.9% of the time. (This is measured based on one minute intervals). When you design EBS Striping (RAID 0) with 6 disks (example 1 TB each with 2000 IOPS) you need to factor 6 X 1800 = 10800 IOPS as the bottom line and not 12000 IOPS.


EBS Article Series (continued..)

Part 1: Understanding Amazon Elastic Block Store
Part 2: Understanding Standard EBS Volumes
Part 3: Understanding EBS PIOPS Volumes
Part 4: Understanding EBS-Optimized Instances
Part 5: Understanding Latency in EBS
Part 7: 10% of your provisioned IOPS 99.9% of the time
Part 8: Performance Tuning - Pre Warming the EBS volume
Part 9: Performance Tuning - EBS Striping
Part 10: Performance Tuning - IO Block Size
Part 11: Understanding Amazon EBS Snapshots
Part 12: Securing Amazon EBS volumes - EBS Encryption using SecureCloud 
Part 13: Amazon EBS Security Best practices and tips

Part 5: Understanding Amazon Elastic Block Store Performance: Latency


Understanding the latencies
In general, it is impossible for a storage system to sustain the same peak IOPS number when presented with different I/O types and latency requirements.  Only IOPS numbers alone are meaningless without considering additional metrics such as latency, read/write % and I/O block size etc.
Latency is a measure of how long it takes for a single I/O request to happen from the apps perspective. High Latency and variance is not preferred when it comes to database applications. Database makes variety of requests and ideally IO latency needs to be under 10ms and write especially under 5ms. Example: In Oracle DB with for heavy writes, the redo log under 1ms is preferred. On the other hand, applications doing sequential, throughput-driven I/O (like backup or archival) typically don’t need high IOPS, but rather need high MB/s.
PIOPS Volumes delivers consistent level of latency and performance than standard EBS Volumes on random reads and random read/writes.  In the benchmark conducted by parse, PIOPS showed latency between 0-0.6 seconds and Standard EBS volumes showed 0.0 to 2.5 seconds. Refer URL:

Part 4: Understanding Amazon Elastic Block Store Performance: EBS-Optimized Instances


Performance tuning Amazon EBS

The performance of a block storage device is commonly measured and quoted in a unit called IOPS, short for Input/Output Operations per Second (IOPS).
To put the numbers in this post into perspective, a disk drive spinning at 7,200 RPM can perform at 75 to 100 IOPS whereas a drive spinning at 15,000 RPM will deliver 175 to 210. The exact number will depend on a number of factors including the access pattern (random or sequential) and the amount of data transferred per read or write operation etc
Some of the key factors that affect EBS QoS are:
  • Bandwidth – The rate of data throughput available
  • Latency – The time delay for a read/write operation to execute
  • Queue depth – The number of outstanding operations waiting to execute to the underlying disks (Traditional or SSD).

Now let us explore those factors and some solutions for the same.

Bandwidth: Use EBS Optimized Instances:
Usually the Network traffic and EBS traffic is shared in the Amazon EC2 instance, which means consistent EBS performance depends on amount of non-EBS related network you send to and from your instance.  Since you cannot predict this there will be contention between EBS and internet traffic and at times, traffic to EBS can suffer a lot. To solve this problem and improve the performance, AWS introduced EBS-optimized instances.  It is an optimized configuration stack that provides additional and dedicated capacity between EC2 and EBS IO. This optimization minimizes the contention between EBS I/O and other traffic from your Amazon EC2 instance and thereby gives you best and consistent performance. EBS-optimized instances deliver dedicated throughput to EBS, with options between 500 Mbps and 1,000 Mbps, depending on the instance type you use and enables you to effectively use PIOPS volumes (if attached). This is additional throughput, and doesn't affect other general purpose network throughput already available on the instance. EBS-Optimized instances can be used with both standard and PIOPS volumes.
Standard EBS Volumes + EBS-OPT Instances:  Scaling throughput from a number of volume stripes where I/O performance consistency isn't critical.
PIOPS Volumes + EBS-OPT Instances: Performance-sensitive production databases that require dedicated EBS traffic and high IOPS performance. It is recommended to always use PIOPS with EBS-Optimized instances to get the full performance benefits.
Things to note:
  • Not all Amazon EC2 instances are EBS-Optimized.  Only the following list is currently supported, please refer AWS documentation for the latest supported types. High-CPU Extra Large (c1.xlarge) ,M1 Large (m1.large), M1 Extra Large (m1.xlarge), High-Memory Double Extra Large (m2.2xlarge), High-Memory Quadruple Extra Large (m2.4xlarge), M3 Extra Large (m3.xlarge) ,M3 Double Extra Large (m3.2xlarge).
  • Provisioned IOPS volumes may not be available in every AZ inside a Region where EBS-OPT is available (currently). AWS will sort this going forward. In mean time, you can use an EBS-Optimized instance with Standard EBS volumes as well to get dedicated throughput between your instance and volumes(in such AZ).

EBS Article Series (continued..)

Part 1: Understanding Amazon Elastic Block Store
Part 2: Understanding Standard EBS Volumes
Part 3: Understanding EBS PIOPS Volumes
Part 4: Understanding EBS-Optimized Instances
Part 5: Understanding Latency in EBS
Part 7: 10% of your provisioned IOPS 99.9% of the time
Part 8: Performance Tuning - Pre Warming the EBS volume
Part 9: Performance Tuning - EBS Striping
Part 10: Performance Tuning - IO Block Size
Part 11: Understanding Amazon EBS Snapshots
Part 12: Securing Amazon EBS volumes - EBS Encryption using SecureCloud 
Part 13: Amazon EBS Security Best practices and tips




Part 3: Understanding Amazon Elastic Block Store - EBS PIOPS Volumes


Provisioned IOPS Volumes
Provisioned IOPS Volumes is the latest type of EBS volumes introduced by AWS. They are also multi- tenant with Availability zone scope, but the major difference is that they offer consistent IO performance.  It is particularly designed for IO intensive applications with random Read/Write pattern requiring up to 10,000 IOPS or more with consistency.  Example OLTP relational database workloads are best candidates for PIOPS Volumes. They follow random r/w IO pattern and require consistent IOPS. Depending upon the size of the volume you can chose the IOPS you require for that volume and Provisioned IOPS volume will guarantee that throughput to you. Since the IOPS is provisioned and dedicated you can expect a consistent IO throughput when you use these volumes. The least size of a provisioned IOPS volume is 10 GB and maximum throughput currently you can extract from a 1 TB EBS Volume is 4000 IOPS (Refer AWS site for the latest value). The ratio of IOPS provisioned to the volume size requested can be a maximum of 10:1. For example, a volume with 1000 IOPS must be at least 100 GB. As best practice it is always recommended to combine Provisioned IOPS volumes with EBS optimized instances when you are architecting a performance sensitive production database. Usually high performance databases have minimal variability in workloads and require dedicated EC2->EBS traffic with High IOPS performance. The EBS optimized+ Provisioned IOPS proves to be an ideal combination for these needs. 



EBS Article Series (continued..)

Part 1: Understanding Amazon Elastic Block Store
Part 2: Understanding Standard EBS Volumes
Part 3: Understanding EBS PIOPS Volumes
Part 4: Understanding EBS-Optimized Instances
Part 5: Understanding Latency in EBS
Part 7: 10% of your provisioned IOPS 99.9% of the time
Part 8: Performance Tuning - Pre Warming the EBS volume
Part 9: Performance Tuning - EBS Striping
Part 10: Performance Tuning - IO Block Size
Part 11: Understanding Amazon EBS Snapshots
Part 12: Securing Amazon EBS volumes - EBS Encryption using SecureCloud 
Part 13: Amazon EBS Security Best practices and tips

Part 2: Understanding Amazon Elastic Block Store - Standard EBS Volumes


Types of EBS Volumes:

EBS volumes can currently be classified into two types namely: Standard EBS Volumes & Provisioned IOPS Volumes

Standard EBS Volumes
Standard EBS Volumes were the first generation of block storage volumes introduced by AWS couple of years back. They operate in a typical AWS Multi-tenant model, where multiple clients mount volumes from a shared SAN backend in Availability Zone scope. Essentially when I mean shared there are two important things to note here, one is the connectivity (NW bandwidth) between EC2 instance and EBS and second is the IOPS on the disk. In a shared resource model a busy client can slow down other clients that share the same EBS backend.  In case there are no noisy neighbors you are lucky to enjoy very good IOPS at very low cost in this standard volumes model. The Standard EBS volumes are internally copied to multiple disks and you will get higher throughput (at times with higher variance in measurements). Standard volumes deliver approximately 100 IOPS on average with burst capability on a best effort basis up to hundreds of IOPS (depending upon disk size provisioned and your noisy neighbors). One common performance technique followed by experienced AWS Cloud architects is to allocate a 1TB volume (max size) which reduces the amount of multi-tenant sharing between the clients and gives you a better consistency with EBS. When you combine this 1 TB volume logic with High IO Capacity EC2 instances (Example Quadruple or High IO/CPU EC2 etc) you get better NW bandwidth between EC2 and EBS as well. This is not an always guaranteed technique, but I have observed better performance most of the times using this approach in many Amazon EC2 regions. On the negative side you might not need 1 TB capacity and could be wasting space and there by usage cost.  Standard EBS volumes are usually suitable for applications only with moderate or bursty I/O requirements.  AWS customers had been using them for RDBMS, NoSQL etc till sometime back because of limited options available and many are still using now because lack of knowledge in AWS infra. Some guidelines/best practices for standard EBS Volumes users are:
  • All layers of the application stack will not demand heavy and consistent IO in a larger web scale application; Secondly EBS PIOPS is costlier than standard EBS volumes. Taking both the points into consideration, I usually recommended to mix-match your tiers with standard EBS volumes and other storage options to get better overall cost efficiency and performance.
  • Standard volumes are also well suited for use as boot volumes, where the burst I/O capability provides fast instance start-up times
  • Standard EBS volumes are better performers in comparison to PIOPS volumes for sequential operations. Workloads like OLAP databases, Reporting stores or Hadoop processing which are more sequential, bursty and follows batch-oriented pattern are a better fit
  • Understanding of storage, blocks, IOPS, Caching, Latency, Bandwidth etc is complicated subject when combined with cloud for developers. I recommend proper benchmarking of your setup with tools like sysbench, FIO, SQLIO etc and frequent observation of the setup for a period of time, till it satisfies your performance.



Wednesday, November 7, 2012

Caching architectures using Memcached & Amazon ElastiCache


Applications can be often made to perform better and run faster by caching critical pieces of data in memory.  Frequently accessed data, layers of HTML fragments, results of time-consuming/expensive database queries, search results, sessions, results of complex calculations and processes are usually very good candidates for cache storage. In general not all application architectures will benefit from having a caching solution in their system, example applications that are read intensive, will usually have better performance gains using cache whereas write intensive applications may not get much benefit.
There are various ways in which caching layer can be designed in AWS infra. The most popular model is distributed caching using Memcached.
Memcached is a high-performance, in-memory key-value store with distributed memory object caching system.

Anatomy of a Memcached system

  • A memcached client which is given a list of available memcached servers in the farm
  • A memcached client-based hashing algorithm which decides (GET/PUT) a server based on the "key" input.
  • Memcached server instances which stores your values with their keys into an internal hash table

Memcached uses memory and NW heavily followed by CPU. Memcached supports TCP and UDP protocols in binary and text format for communication. Memcached supports client libraries for popular programming languages like Java, .Net, PHP, Python, Ruby etc.
In this article let us explore and analyze some popular memcached/ElastiCache deployment architectures in AWS.

Architecture 1: Apache + Memcached shared in same EC2 (Distributed Cache)


Memcached is shared with Apache in the same Amazon EC2 instance. Imagine m1.large EC2 instance where 7 GB RAM and 2 CPU Cores are shared between OS, Apache and memcached. Since Amazon ElastiCache runs on a separate tier it will not fit this shared approach. The Apache-A can contact any memcached-A/memcached-B or memcached-X node depending upon the Key/Value hash. Since the unused memory is shared with memcached and no dedicated EC2 instances are launched for caching tier this model is usually cost effective. We have seen some implementations using this approach in production but in my opinion it is not suitable for applications which demands heavy scaling and clear service separation. This model can be scaled up and but not scaled out optimally, ie based on your traffic demand you can Scale up the shared EC2 instance to bigger capacities like Xlarge, Quadruple, High IO ,M3 class etc. but not easily add new instances of this type. Some negatives that this approach brings to the table are:
Maintenance: Since the Apache and memcached are shared in the same EC2 it is strictly advised not to Auto Scale this layer. Only Manual Scaling is possible in this layer which might add heavy configuration burden to IT team during traffic peaks and valleys.
Auto Scaling: Using Amazon Auto Scaling we can add new web/app EC2 instances dynamically depending upon the traffic demands. But when web/app Server instance also contains memcached running in it, it brings in cascading complexity into the architecture. Imagine there are 2 m1.large Apache + memcached EC2 instances running and a third one is launched by Amazon Auto Scaling based on the traffic. Now the load balancer splits the 1/3rd of the web traffic to this Apache EC2 instance. Since the cache is empty 1/3rd of the requests will now hit the backend database heavily. Now imagine instead of 1 EC2 you are auto scaling out by 2 Apache EC2 during peak, this will increase Database load to 50% more because of un warmed memcached. Secondly, the new memcached endpoint has to be propagated and configured on other memcached clients, which adds another complexity and devops engineering into the architecture. Finally, Amazon Auto Scaling will pull out an Apache EC2 instance when the load decreases, now if you are pulling out an Apache + memcached that is properly warmed it will again increase the DB load because of the cache miss.  
Note:  We can still try to address this problem by adding more complexity of designing/engineering with progressive weighted EC2 balancing + Scaling out and internal Cache Warming techniques etc, but if you deeply ask a question is it worth it, it is not many times. Alternatively, we can altogether avoid this complexity by simplifying the overall architecture of the system, which we will see as the article progresses.
Sharing: We observed earlier that sharing Apache+ memcached on same EC2 saves cost. On the other hand, this sharing also causes problems if one is not aware of the environment. In our case Apache + memcached are shared and Apache-A can talk to memcached in same EC2 or other Apache EC2 instance as well depending upon KV hash. Based on this flow let us explore some problems in sharing approach.
  • ·         Apache is usually heavy on Memory and CPU. Memcached is low on CPU, high on memory and network depending upon the average size of your items.
  • ·         If the memcached is not configured with Memory limits it can crash your Apache and OS. If the Website is heavily loaded and built to be cache dependent there will be heavy CPU contention between Apache and memcached.
  • ·         If the request/response of Apache and memcached are bigger in size there will be bigger contention on the shared network layer. Overall request throughput can reduce because of heavy buffering and NW contention.
  • ·         Apache EC2 instance will now have bigger headache of handling all the TCP sockets flowing between Internet, Database, Internal NW and memcached.  Some of them address the last point marginally by using UDP protocol for memcached communication and reduce the TCP socket temporary exhaustion. Overall this is a stitch and not a proper solution.  


Architecture 2: Apache + Memcached shared in same EC2 (like Local Cache)


This approach has a slight difference from the above one.  Apache/NginX and memcached are shared in the same EC2 instance, but the Web (Apache or NginX) process will strictly and only call the local memcached and will not call the remote memcached. Basically, memcached is used here as a local instance cache and not as a distributed cache. Every Apache/NginX will cache items in memcached and use it as extended memory. Since the items are coming from the same EC2 instance, the throughput and latency are better for cached entries. Though this approach has lesser configuration headache than the previous approach, it still inherits lots of problems from the previous one. Session sticky algorithm is preferred on the Load balancing tier to optimally reuse the cache items and reduce the DB load because RR algorithm can heavily exercise the DB during initial cache warming phase.   Rapid scaling out and scaling down should be avoided on smaller deployments because it transfers the load on the DB immediately. If already there is a large fleet (100’s) of NginX + memcached running then rapidly adding few (5-10) EC2’s of this kind will not have huge problems on the DB. Proper architecture guidance is recommended before fitting the above architecture into the use case.
As we observed  in detail, the above approaches might be cost effective for smaller deployments , but as the site gets popular, traffic increases and it demands scalability it will become complex to handle. Usually in architecture if complexity arises because of improper designs, it will be followed by heavy maintenance and management cost.

Now that we have understood the impacts sharing memcached with web/app server, a simple solution is to split the memcached into separate EC2 instance. Recently introduced M3 class instance types are good candidates for designing separate memcached tier. But the question is, whether we really need to manage and maintain a separate additional memcached layer. The answer is NO, USE AMAZON ELASTICACHE.

Amazon ElastiCache is a web service that is protocol-compliant with Memcached, a widely adopted memory object caching system, so code, applications, and popular tools that you use today with existing Memcached environments will work seamlessly with the service.

Architecture 3: Apache + Amazon ElastiCache in separate tier


Apache and Caching runs on clearly separated tiers in this approach.  Since the tiers are separated Apache EC2 can be easily scaled out using Amazon Auto Scaling or custom scaling. Dynamically launching/terminating Apache instances will not swamp database because the warmed cache is separated and still accessible by all the Apache EC2 instances. It is also easy to roll out configuration changes, add new nodes in caching layer and propagate the changes to the cache clients. The clear separation also enables us to isolate and address issues creeping up in Apache and Caching layer individually.
ElastiCache nodes are grouped inside an ElastiCache cluster.  An ElastiCache cluster is a collection of one or more cache nodes, each running an instance of the memcached service. The word cluster in this context should be related to “grouping” and not “data synchronization” because ElastiCache nodes will not talk to each other or exchange information between them inside the cluster. Most of the operations like configuration, security and parameter changes will be performed at the cache cluster level and not at individual cache node level. This enables easy maintenance and management of the caching tier on whole. Since ElastiCache is also protocol compliant with memcached, programs written in Java, PHP, and Python on Apache can still use their respective memcached clients and perform SET/GET operations seamlessly. The ElastiCache Node end points (like“ecache1a.sqjbuo.0001.use1.cache.amazonaws.com:11211") needs to be configured on the memcached clients of the Apache EC2. “ecache1a” is the cluster name, “0001” is the node number and 11211 is the port in the above mentioned URL endpoint. Whenever a new node is added into this “ecache1a” cluster, a sequence of numbers like “0002, 0003” will be assigned in end point URL to the nodes. This predictive pattern helps us to automate the detection of cache node endpoints in client side of scalable environments. Since a single ElastiCache cluster can currently span only in a single Amazon Availability zone, it is advised to keep both Apache EC2 and ElastiCache Instances in same Availability zone for improved latencies. Inside Single AZ a single SET/GET operation between Apache and ElastiCache will take around ~1-5 milliseconds using AWS High Memory Quadruple Instance types. This latency measurement also depends upon parameters like Apache EC2 instance type, ElastiCache Instance type, size of the SET/GET requests, Single or Bulk operations etc. Imagine you use m1.large for Apache and ElastiCache instance and every SET/GET is around 1 MB size. Then if the available NW bandwidth between Apache EC2 to ElastiCache is only 15 MB at that instant of time, only 15-20 requests can be performed concurrently at that instant. You may find the CPU under-utilized and max connection well set in ElastiCache, but still the throughput is less because of the above reason. This is not the problem of ElastiCache performance, but rather a bad understanding of the architecture components behaviors. If the web app is cache dependent, it is advised to spread the items in multiple cache nodes. Imagine you have close to 20 GB Cache size requirement. You can distribute it in either 2 m1.xlarge ElastiCache nodes or 4 m1.large ElastiCache nodes. The cache data will be distributed by the memcached client to multiple nodes based on the KV hash. In case one cache node goes down then 50% of the cache load will now hit the backend data stores in m1.xlarge approach whereas 25% of the cache load will only hit the data stores in m1.large approach.  Also since it is currently not possible to have multiple cache node instance types inside a single ElastiCache cluster, I advise you to do proper capacity planning taking into consideration the cache dependency and capacities of backend DB to take direct requests before planning the cache node numbers, size and consolidation levels.
Amazon ElastiCache as the name suggests you can automatically/manually add or remove cache nodes from the existing ElastiCache cluster making the whole tier elastic and flexible for customers. This is one of the important features of Amazon ElastiCache and this feature eventually falls in line on any growing websites roadmap.  Now let us try to understand the remapping implications while adding or removing cache nodes from the cache cluster.
With a normal hashing algorithm, changing the number of servers can cause many keys to be remapped to different servers resulting in huge sets of cache misses. Imagine you have 10 ElastiCache Nodes in your cache Cluster, adding an eleventh server may cause 40%+ of your keys to suddenly point to different servers than normal. This activity is undesirable, may cause cache misses and eventually swamping your backend DB with requests. To minimize this remapping it is recommended to follow consistent Hashing model in your cache clients. Consistent Hashing is a model that allows for more stable distribution of keys given addition or removal of servers. Consistent Hashing describes methods for mapping keys to a list of servers, where adding or removing servers causes a very minimal shift in where keys map to. Using this approach, adding an eleventh server should cause less than 10% of your keys to be reassigned. This % may vary in production but it is far more efficient in such elastic scenarios compared to normal hash algorithms.  It is also advised to keep memcached server ordering and number of servers same in all the client configurations while using consistent Hashing. Java Applications can use “Ketama library” through spymemcached to integrate this algorithm into their systems. More information on consistent hashing can be found at http://www.last.fm/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients



Deep dive into Amazon ElastiCache and understand the internals like connection overheads, memory allocations, Elasticity implications in this article:  http://harish11g.blogspot.in/2013/01/amazon-elasticache-memcached-internals_8.html




Architecture 4: Apache + Amazon ElastiCache in Multiple Availability Zones



This is an extension of the previous approach, for better availability the cache nodes are distributed among multiple Availability zones of an Amazon EC2 region. Most of the points discussed on the above approach will be applicable on this architecture as well. Since the ElastiCache cluster currently cannot span across multiple AZ’s you can create multiple ElastiCache clusters in Multiple AZ’s. Example: you can create ElastiCache cluster “ecache1a” in Amazon AZ - 1A and have a node launched with endpoint “ecache1a.sqjbuo.0001.use1.cache.amazonaws.com:11211”. In the same way you can create another ElastiCache cluster “ecache1b” in Amazon AZ – 1B and have a node launched with endpoint “ecache1b.sqjbuo.0001.use1.cache.amazonaws.com:11211”. Both the cache nodes endpoint should be configured in memcached clients.  Since the AZ concept is built transparently by AWS, the memcached clients in Apache EC2 can distribute data seamlessly and easily to both the cache nodes distributed across AZ’s.  You can manage the cache clusters separately as well you can distribute the data across AZ in this approach. In case an entire AZ is affected still the cache nodes in the other alternate AZ will be still accessible and functional.  Instead of DB getting swamped by 100% cache misses now you are reducing it to ~50% with AZ distribution in this approach. This % can be reduced much more if data is distributed among 2 or more AZ’s with more cache nodes inside them.
ElastiCache Maintenance Window allows you to specify the time range (UTC) during which any scheduled maintenance activities such as software patching or pending cache cluster modifications you requested would occur. Scheduled maintenance activities occur infrequently (generally once every few months) and will be announced on the AWS forum two weeks prior to being scheduled. After maintenance window our cache nodes may lose all the data stored in it memory and needs to be warmed again. Imagine having a single ElastiCache cluster with 10 cache nodes and all of them needing the cache warming phase after maintenance period, It puts heavy burden on your DB and other backend data stores during this refresh phase and sometimes even brings down your system to knees on heavy cache dependent architectures. Since AWS is very elastic and flexible, either you can plan to increase your backend capacity on demand for few hours to few days till the cache layer is adequately warmed or leverage the multi-AZ ElastiCache approach. Imagine you have 4 ElastiCache clusters distributed in 4 Availability zones inside an Amazon EC2 region. You can configure maintenance windows spanning multiple days for multiple cache clusters. Example ecache1a can have maintenance on Monday, ecache1b on Tuesday so forth. This distribution of ElastiCache Maintenance windows may give you enough time to warm cache nodes in phases and also helps you avoid cache swamping your backend with requests simultaneously.
This architecture approach is not suitable for smaller deployments running in single AZ’s. I suggest this for only larger deployments where Apache EC2’s are auto scaled, Apache and ElastiCache clusters are well distributed across multiple AZ’s so that overall cache item SET/GET latencies are in acceptable levels.  



Launch Amazon ElastiCache in 3 Easy Steps:  http://harish11g.blogspot.in/2012/11/configuring-amazon-elasticache-launch.html


Architecture 5: Apache + Amazon ElastiCache + Redundancy



This is a slightly different approach built with availability and redundancy. Apache and ElastiCache are deployed in separate tiers. Apache EC2 can be individually auto scaled across multiple AZ’s.  Multiple ElastiCache clusters are created spreading across multiple availability zones inside Amazon EC2 region (till now very similar to previous approach).  Certain items are redundantly cached in two cache nodes in multiple AZ- ElastiCache clusters for better availability in this approach. Results of time consuming and expensive data base queries, results of complex calculations etc are good candidates for this approach. Imagine an expensive query that pounds the database for ~250 or more milliseconds, if the data does not change quite frequently in this case it can be redundantly stored in 2 ElastiCache nodes.  If cache node 1 is down or throws connection error or if cache item miss occurs then the redundant cache node 2 can be requested for the same item. If the item is not present in cache node 2 also then as last resort the DB is queried and latest result is stored in both the cache nodes redundantly. Imagine it takes around 2-5ms for single ElastiCache node to return a value hitting 2 cache nodes redundantly still gives the results in ~10ms, which is far better compared to pounding and getting the result from DB. This approach is not suitable for frequently changing data flows because it may result in fetching stale data from the cache, for such scenarios ElastiCache-> DB fallback approach is better. Also it is not necessary to have redundancy built for all the cache nodes and cache clusters totally, you should build redundancy only for specific cache nodes in the system. This feature is not pre built on the memcached API’s currently and it has to be manually implemented in the application code by crudely making multiple calls to multiple sets of cache nodes. Though it reduces the overall GET time for complex requests, your SET times will marginally increase because of multiple requests made to cache nodes.
 It is costlier and complex compared to other architecture approaches mentioned above. But for some use cases it can save on your database HW capacity cost heavily and provide immense infra cost savings overall. It is suggested to carefully analyze the fitment of this approach based on your use case, cost and maintenance needs.


Related Articles
Part 1: Understanding Amazon ElastiCache Internals : Connection overhead
Part 2: Understanding Amazon ElastiCache Internals : Elasticity Implication and Solutions
Part 3: Understanding Amazon ElastiCache Internals : Auto Discovery
Part 4: Understanding Amazon ElastiCache Internals : Economics of Choosing Cache Node Type
Launching Amazon ElastiCache in 3 Easy Steps
Caching architectures using Memcached & Amazon ElastiCache
Web Session Synchronization patterns in AWS

Need Consulting help ?

Name

Email *

Message *

DISCLAIMER
All posts, comments, views expressed in this blog are my own and does not represent the positions or views of my past, present or future employers. The intention of this blog is to share my experience and views. Content is subject to change without any notice. While I would do my best to quote the original author or copyright owners wherever I reference them, if you find any of the content / images violating copyright, please let me know and I will act upon it immediately. Lastly, I encourage you to share the content of this blog in general with other online communities for non-commercial and educational purposes.

Followers