Sunday, September 26, 2010

Combining Roles on Windows Azure

Now why would you want to do that? Azure provides a nice separation of roles in web role and a worker role – why do you want to combine those you’ll ask. Multiple reasons – saving cost being the primary. The most requested feature on the Windows Azure feature voting forum is “Make it less expensive to run my very small service on Windows Azure.” and rightly so. If you wish to host your “small service” on the cloud it makes sense to minimize the cost. Even for large scale services this can help to maximize the use of resources. Let’s crunch some numbers to see this in action.

Assume that your “simple service” consists of a simple website that provides the UI to the users. There is also a background worker for sending registration emails, sending newsletters and does some nightly batch processing of your data. Let’s say you don’t need a full blown SQL server and are happy with the semi structured data storage that Windows Azure table storage provides. These assumptions are not unrealistic for a large number of  simple websites, in fact most startup websites will start with this model and then scale out as the traffic increases and that’s exactly what Windows Azure enables you to do. So with these very realistic scenario let’s examine what will it cost to host such a service on Windows Azure. We will only focus on the compute cost as that’s what you will save on (& is the biggest cost for a small service) when you combine roles so we can safely ignore the storage, bandwidth and other costs of hosting on Azure as they are all usage based.

Here’s what the compute instances cost on Windows Azure.

  • Small instance (default): $0.12 per hour
  • Medium instance: $0.24 per hour
  • Large instance: $0.48 per hour
  • Extra large instance: $0.96 per hour

Let’s say you will use the small instances for both your roles. So your monthly cost comes out to be,

30 (days in a month) * 24 (hours in a day) * 0.12 (cost per hour) * 2 (number of instances)
= $172.80 per month

Now you are wondering the worker role is just sitting there doing nothing for most of those hours. Shouldn’t you only count the “compute hours” in which the role is actually is alive and doing work instead of the full 24 hours for a day. Well, that’s not how Windows Azure billing work. It’s pay as you go alright but not at that granularity so you end up paying as long as your have reserved the VM, even in the suspended state. May be some day Azure will be able to provide that level of billing granularity – may be we should request that feature on the forum :-) But till then the only way to save cost here will be - if we just got rid of one role entirely and still do all the work with just one role. Turns out it’s very easy to do that on Windows Azure.

To understand how to do that we first need to understand how web and worker role differs in Windows Azure. One obvious difference  is the web role will have an IIS installed on the VM and the work role will not. What else? Well, turns out that’s about it. In every other sense as far as Window Azure is concerned those roles are pretty much the same. You could potentially have your worker role listen on port 8080 and receive web traffic and your web role have a Run()method that does the background work. When you create a Cloud project in Visual studio, by default in the webrole.cs the template does not add a Run() method like it does in your worker role but there is nothing that stops you from doing that either because the WebRole class also derives from the same RoleEntryPoint which workers derive from as well.

public class WebRole : RoleEntryPoint
{
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("WorkerRole1 entry point called", "Information");

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

As simple as that. Once your web role gets provisioned Azure fabric will start start IIS and deploy your application as well as start a worker which you can use to do some background processing. The thing to note that both of these processes are running on the same VM and will share the resources so this technique should not be used where a consistently high throughput is required at all the times by either your website or your background worker. But if you are able to use this technique you end up cutting your compute cost in half for your small service.

Hope that helps.