This is the 35th in our series of guest posts by Microsoft Most Valued Professionals (MVPs). You can click the “MVPs” tag in the right column of our blog to see all the articles.

Since the early 1990s, Microsoft has recognized technology champions around the world with the MVP Award. MVPs freely share their knowledge, real-world experience, and impartial and objective feedback to help people enhance the way they use technology. Of the millions of individuals who participate in technology communities, around 4,000 are recognized as Microsoft MVPs. You can read more original MVP-authored content on the Microsoft MVP Award Program Blog.

This post is by Windows Azure MVP Michael Collier. Thanks, Michael!

And don’t forget: a week of free online Windows Azure training began today. Information and registration links are here. It’s not too late to register for the Tuesday, Wednesday, Thursday, and/or Friday sessions.

Hello, Michael here. Today I would like to share with you one way to improve the robustness of the applications you host in Windows Azure. Just putting the application in “the cloud” doesn’t mean we automatically have a highly scalable, highly available application. Sadly, “the cloud” just isn’t that magical yet.

As load increases on a web application, we will often take a series of steps to help improve site performance. Initially, we might put our web application behind a load balancer and add more web instances to better serve the incoming requests. With Windows Azure Web Sites and Cloud Services, adding more instances is as easy a turning a knob to the number of desired instances. The Windows Azure load balancer automatically adjusts to handle the additional instances.

Our next step might be to add more, or perhaps even larger, application servers to our middle / business logic tier. But as traffic continues to increase, the load on our database typically starts to increase as well. Soon the database may become the performance bottleneck. The database responses can get slower and slower. As pressure increases, the database may begin to throttle or connections may timeout. The end result for our users – errors and a poor experience.

A logical step to remedy this problem is to implement a cache tier. The cache tier would reside between the business tier and the database tier. The cache tier takes some of the pressure off the database as data requests can be served by the cache instead of always needing to query the database (a potentially expensive operation).

clip_image002

What Are the Options?

For Windows Azure hosted applications, there are several options available for caching data. This is a good thing! Let’s take a look at the Windows Azure In-Role Cache and the new Windows Azure Cache Service in more detail.

In-Role Cache

Windows Azure In-Role Cache is an in-memory, distributed cache solution for Cloud Services (web and worker roles) only. There are two options for using In-Role Cache: co-located and dedicated.

Co-Located Cache

With a co-located cache configuration, a dedicated percentage of memory on each role instance is set aside for cache usage. The role instances are joined together to form a distributed cache. For example, if 300 MB on each instance is reserved for cache data, and there are 4 instances of the role, there is now effectively 1.2GB of distributed cache available for the application to use.

clip_image004

There is no extra charge to use this cache. The cost is included as part of simply running that number of role instances. Since there are no additional instances involved there is no extra cost. Free is good!

It’s important to keep in mind that enough memory still needs to be available to serve the application. Have a look at the Microsoft provided Windows Azure Caching Capacity Planner worksheet to help you plan for the right size cache to use for your application.

Dedicated Cache

In a dedicated cache configuration, additional cache specific worker role instances are deployed within the Cloud Service. The purpose of the cache worker role is to serve as a distributed cache available to other roles within the Cloud Service.

For example, let’s take a Cloud Service which consists of one web role and one worker role. In this example, assume there are 4 instances of the web role. To handle the dedicated cache, two worker roles instances are dedicated to that function. Each worker role instance could have 12 GB of memory available for cache usage (available memory depends on the size of the role). This effectively creates 24GB of distributed cache available for the web role instances. If more cache is needed, perhaps the site comes under additional load (like if Oprah or Scott Guthrie mentions your site), the number of worker role instances can quickly (typically within a few minutes) be increased. Each new instance adds an additional 12 GB to the distributed cache.

clip_image006

Configuring In-Role Cache, either co-located or dedicated, for a Cloud Service requires only a few steps:

1. Create a new Windows Azure Cloud Service project (or use an existing one if available).

2. Within Visual Studio, open the properties window for the selected role by right-clicking on the role and then selecting Properties.

3. Within the Caching tab, check the Enable Caching checkbox.

4. Select the percentage of memory that should be available for the cache.

5. Select the Windows Azure storage account to use for maintaining the cache’s runtime state.

6. Optional: Add additional named caches or set options such as High Availability, Notifications, Eviction Policy, Expiration Time, and Time to Live. Learn more about additional cache features on MSDN.

clip_image002

That is all that is needed to configure the role to support caching. Now there is some code that needs to be added to put items into the cache and get items from the cache. The first thing that will be needed is to add the Windows Azure Cache assemblies to the project. The assemblies will be added to the source project (e.g. the ASP.NET MVC project if creating a web application) – not the Windows Azure Cloud Service project. This can be done by using NuGet.

clip_image003

By adding the assemblies via NuGet, the application’s web/app .config file will be automatically updated to include the necessary elements. One area of particular interest is the dataCacheClient/autoDiscover element. To use the In-Role Cache, set the identifier attribute value to the name of the role that will host the cache.

<dataCacheClients>

  <dataCacheClient name="default">

    <autoDiscover isEnabled="true" identifier="[My_Role_Name]" />

  </dataCacheClient>

</dataCacheClients>

NOTE: NuGet will also add the necessary ASP.NET session state and page out caching providers to the web/app .config. Uncommented the desired provider should you need to use it.

All that remains now is to add items to the cache, and get items from the cache.

public IEnumerable<Score> GetTopScores()
{
     DataCache cache = new DataCache();
 
     // Attempt to get item from the cache
     var topScores = cache.Get("top-scores") as Score[];
 
     if (topScores == null)
     {
         // Get data from the database and put into the cache
         topScores = GetScoreData();
         cache.Put("top-scores", topScores);
     }
     return topScores;
} 

NOTE: Windows Azure In-Role Cache features diagnostics that can be helpful in troubleshooting. Diagnostic levels can be configured to collect various data points. This data is persisted to Windows Azure storage. Please see http://aka.ms/CacheDiagnostics for detailed information.

Cache Service

While the In-Role Cache option is available only within a Cloud Service, the new Windows Azure Cache Service is available to all web Sites, Virtual Machines, and Cloud Services. The Cache Service is a highly scalable, resilient, Microsoft-managed “Cache-as-a-Service” that can easily be added to your Windows Azure applications.

clip_image007

At the time of this writing, Windows Azure Cache Service is available as a Preview offering.

To get started, you will create a new Cache from the Windows Azure management portal. You will create a name for the cache (a unique endpoint for the service), a cache offering, and region. Naturally you’ll want the cache to be located in the same region as the applications using it so that access to the data in the cache is as fast as possible (no need to hop across the internet to access “cached” data). There are three different offerings for the cache service: Basic, Standard, and Premium.

Basic

Standard

Premium

Cache Size (per unit)

128 MB

1 GB

5 GB

Scale

Up to 8 units

Up to 10 units

Up to 30 units

Named Caches

1

10

10

High Availability

N/A

N/A

Yes

Notifications

N/A

Yes

Yes

NOTE: Want to know more about named caches, high available, notifications and other useful cache features? Those are all important topics to understand. Sadly there just isn’t enough room in this article to discuss all the cool things available with Windows Azure Cache. Check out this article on MSDN for more detailed information.

With the cache created, it is now time to use the cache from the application. Fortunately, the process for using the Cache Service is nearly the same as it is for using In-Role Cache (as discussed earlier). The difference is that with the Cache Service, there is no need to configure the role itself for caching. The same NuGet package is used to bring in the necessary assemblies and updates to the web/app. config file. The same code can be used as well (awesome . . . I know). The only change that will be needed is to update the web/app .config file to use the service instead of the role. Instead of the role name as an identifier, we would use the cache service endpoint. We will also need to (uncomment if commented out) update the <securityProperties> section to include the authorization key for the cache service. We can get the key from the Windows Azure management portal.

<dataCacheClients>
  <dataCacheClient name="default">
    <autoDiscover isEnabled="true"
                  identifier="[My_Cache_Name].cache.windows.net" />
    <securityProperties mode="Message" sslEnabled="false">
      <messageSecurity authorizationInfo="[My_Security_Key]" />
    </securityProperties>
  </dataCacheClient>
</dataCacheClients> 

Once using the cache, usage can easily be tracked via the Monitor section of the desired cache in the Windows Azure management portal. There you can monitor metrics such as Memory Used % and Cache Miss %. Should you notice the need to add more cache, go to the Scale tab to scale out, or up, the cache. There you can scale up to a larger offering (e.g. Basic to Standard or Premium), or scale out to add more cache units (additional blocks of cache memory). You can scale out without incurring any loss of cached data, but scaling up (to a larger offering) will result in any cached data being lost. Windows Azure will prepare the new cache offering, and when ready, switch clients over to the new cache offering.

Like the capacity planning worksheet for In-Role Cache, Microsoft also provides a capacity planning worksheet for the Cache Service. This worksheet will aide in determining which cache offering (Basic, Standard, or Premium) is suitable for your scenario.

NOTE: There is another legacy cache option – the Shared Cache service. Shared Cache will be deprecated in September 2014. If you have a solution using the Shared Cache service, you are encouraged to migrate to another solution. Do it . . . now, please! See http://aka.ms/MigrateFromSharedCaching for additional guidance.

Which Cache to Use?

As mentioned previously, the choice on which cache offering to use will vary based on several factors. Personally, I like to at least start with the Cache Service. It reduces the infrastructure needed (when compared to an In-Role dedicated cache), and enables the cache to live outside of a Cloud Service and thus the cached data is accessible from other applications. Also, for many workloads, the Cache Service is often cheaper than creating a separate cache worker role.

  • 2 Medium worker role Instances – (3.5GB per instance X 2 instances) x 30% memory for cache is approximately 2.1GB for cache. The total cost is approximately $238/month
  • 2 GB Standard Cache Service – 2, 1 GB units (2GB total) is $100/month

However, for relatively large cache amounts, having dedicated cache worker role instance can be significantly cheaper.

  • 3 A7 dedicated cache worker roles – 56GB/instance is approximately 168GB. The total cost is approximately $3,147/month.
  • 150GB Premium Cache – 30, 5GB units (150GB total) is $6,000

NOTE: If you’re looking for a good, reusable cache wrapper, do yourself a favor and consider the Cloud Service Fundamentals (CSF) project from the Windows Azure CAT team. CSF contains many great components. The cache logic in CSF demonstrates, amongst several other nice techniques, using a custom binary serializer that leverages protobuf-net. This provides a very fast and compact way of serializing/deserializing data that is stored in the cache.

Summary

Windows Azure provides caching solutions for Cloud Services, Virtual Machines, and Web Sites. If you’re looking to add a fast, scalable, cost efficient cache for your Cloud Service web and/or worker roles, then Windows Azure In-Role Cache is a great option. It can be free to add if co-located with the role, or pay just for the cache specific instances needed when using the dedicated configuration. Should you need a robust, fully managed “Cache-as-a-Service” that is available for all your Cloud Services, Virtual Machines, and Web Sites, then the Windows Azure Cache Service provides an attractive solution. The fast, secure, dedicated Cache Service allows you to easily scale your caching tier – all without predefined quotas on bandwidth or connections. Whatever option you chose, the end result is that you can spend more time focusing on what makes your application great.

There are options . . . and that’s a good thing!