First Look: Scaling with the Windows Azure Autoscaling Block

A little more than a week ago, Microsoft’s Patterns & Practices team released the first preview of the new Windows Azure Autoscaling Block (WASABi).  I have been exploring some of the features recently, and I must say I’m quite impressed.  The block contains some very welcome functionality.  It’ll be nice to see how the team continues to flush out the block’s features.  Developing an intelligent scaling solution is not as easy as it sounds.  There are a lot of aspects to consider, and so far it looks like WASABi is striving to address those.

As a little disclaimer, I’m not a big user fo the Enterprise Library blocks that are currently available.  To be perfectly honest, I haven’t used them probably since their v1 or v2 days.  So for me getting started with WASABi I felt like there was some ramp-up time to just get up to speed on how to configure the block and the patterns for doing so.  After spending some time with the Enterprise Library to learn about the new Autoscaling block, it’s obvious I need to give these new blocks another deep look.  Sure looks like there is some really nice, helpful utilities there.

To get started, let’s set up WASABi to have a very simple rule – increase the number of instances on a web role during peak business hours.  In this scenario, the web role should have at least two instances at all times, and increase to 8 instances from 7am – 7pm ET.  Naturally, after peak hours the count should decrease to the minimum again – 2 instances.

WASABi needs a host to run.  In this walkthrough, a Windows Azure worker role will serve as the host for WASABi, the “scaler”.  It will be the responsiblity of this scaler role to monitor the web role, adjusting the instance counts according to the configured rules.

If you don’t already have WASABi, now would be a good time to get it from NuGet.  Also, I would encourage you to watch the Channel 9 video walkthrough.  The video does a pretty good job of getting you going.  The initial preview release does not include much in the way of developer documentation.  I know the team is working on this and I’d imagine the final bits would ship with nice, detailed documentation.  In the sections that follow I’m hoping to clear up something areas that I found a little confusing getting started.

Creating a Worker Role

The worker role logic itself is actually pretty simple.  The real magic (a.k.a. “work”) happens in configuration.  We just need to instantiate a new Autoscaler instance and then start it.  The worker role code can be as simple as:

public override void Run()
{
	try
	{
		this.autoscaler = EnterpriseLibraryContainer.Current.GetInstance();
		this.autoscaler.Start();

		while (true)
		{
			Thread.Sleep(10000);
			Trace.WriteLine("Working", "Information");
		}
	}
	catch (Exception ex)
	{
		Trace.Write(ex);
	}
}

With the basic code in place, now we need to configure the Autoscaler.  The configuration sets up where the Autoscaler will look for rule and service information.  This configuration lives in the web role’s app.config file.  It is easiest to get started with setting up the configuration by using the Enterprise Library Configuration extenstion in Visual Studio.  The video walkthrough does a pretty good job of showing this, so I’ll let you watch that.  Go ahead . . . I’ll wait.  In my opinion, the tool is not the easiest thing to use, but it does get you going.  I would assume the configuration tool will improve prior to the final bits shipping.  Like I said, it’s a starting point.  A few things to note about the configuration:

  • The default logger is the LoggingBlockLogger.  For some reason, I couldn’t get this to log all the log messages I expected related to when new rules where evaluated and when the scaler would trigger a scaling action.  I changed to use the SourceLogger.  I also copied the logging configuration (listeners, category sources, and special sources) from the app.config included with the ConsoleAutoscaler sample application included in the NuGet feed for the WASABi source.  That said, I’m not sure if the logging problems I experienced were related to the logger itself, or a misconfiguration on my part (probably me).
  • I created two XML configuration files for rules and services, rules.xml and services.xml (more on those below).  You can easily set those as the blob name when configurating the rule and service information store elements in the app.config.
<rulesStores>
     <add name="Blob Rules Store" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.Rules.Configuration.BlobXmlFileRulesStore, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling" blobContainerName="autoscaling-container" blobName="rules.xml"
           storageAccount="RulesStoreStorageAccount" monitorPeriod="30" />
</rulesStores>
<serviceInformationStores>
     <add name="Blob Service Information Store" type="Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.ServiceModel.Configuration.BlobXmlFileServiceInformationStore, Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling" blobContainerName="autoscaling-container" blobName="services.xml"
           storageAccount="RulesStoreStorageAccount" monitorPeriod="30" />
</serviceInformationStores>

Creating the Rules

The rule configuration file contains the, well, rules for under what conditions the scaler should scale a hosted service.  There are two types of rules available – constraint rules and reactive rules (see the announcement for more details on the rules).  Let’s take a look at a simple rule configuration.

<?xml version="1.0" encoding="utf-8" ?>
<rules xmlns="http://schemas.microsoft.com/practices/2011/entlib/autoscaling/rules">
     <constraintRules>
	<rule name="default" description="test test" enabled="true" rank="1">
		<actions>
                     <!--'MvcWebRole1' is the name of the web role. -->
		     <range target="MvcWebRole1" min="2" max="2"/>
		</actions>
	</rule>

	<rule name="business hours" description="scale out during business hours" rank="100" enabled="true">
		<timetable startTime="07:00:00" duration="12:00:00" startDate="2011-09-15" utcOffset="-04:00">
			<weekly days="Monday Tuesday Wednesday Thursday Friday"/>
		</timetable>
		<actions>
			<range target="MvcWebRole1" min="8" max="8"/>
		</actions>
	</rule>
     </constraintRules>
</rules>

It should be noted that the ‘startTime’ is your local time (e.g. EDT).  Also, make sure you have the correct UTC offset (e.g. EDT vs. EST).  If not, the scaler may not scale when you think it should (yes – happened to me).  The scaler uses the ‘utcOffset’ value to convert the configured time to UTC time (which is the time Windows Azure uses).  The video walkthrough mentions this as well. :)

Creating the Service Information

The service configuration “tells” the scaler which Windows Azure subscriptions and hosted service(s) to monitor. Let’s take a look at a sample service configuration file.

<?xml version="1.0" encoding="utf-8" ?>
<serviceModel xmlns="http://schemas.microsoft.com/practices/2011/entlib/autoscaling/serviceModel">
	<subscriptions>
		<subscription name="something"
					subscriptionId="b5fb8dfb-3e0b-xxxx-xxxx-xxxxxxxxxxxx"
					certificateStoreLocation="LocalMachine"
					certificateStoreName="My"
					certificateThumbprint="FE5EB4279BC6354xxxxxxxxxxxxxxxxxxxxxxxxx">
			<services>
				<service name="myHostedServiceName" slot="Staging">
					<roles>
						<role name="MvcWebRole1"
                                                            roleName="MvcWebRole1"
						      wadStorageAccountName="wadStorageAccount"/>
					</roles>
				</service>
			</services>
			<storageAccounts>
				<storageAccount name="wadStorageAccount" connectionString="DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=123xxxxxxxxx">
				</storageAccount>
			</storageAccounts>
		</subscription>
	</subscriptions>
</serviceModel>

A few things to note about the service configuration:

  • The subscription name can be pretty much whatever you want.
  • The service name should be the name of your hosted service.  This is the DNS prefix for the production slot.
  • You will need to make sure to configure the worker role (the “scaler”) to contain the certificate thumbprint.  This is done in the service definition file.
  • One of the things that needs to be set up in order for WASABi to scale a Windows Azure application is both a management and service certificate.  These certificates are necessary in order for WASABi to query characteristics of a service and to create, or shut down, instances of a service.  For more information on Windows Azure management and service certificates, please go here.

I hope you found this brief walkthrough helpful.  As I continue to explore WASABi, I’ll be sure to post more here about my experiences.  In the meantime, be sure to check out the following list of resources: