If your Cloud Service is composed of many Web Roles, Worker Roles or Virtual Machines, then you may be looking to cut your operational costs. When designing a Windows Azure solution, details like the way you consume Windows Azure services, are especially important. Using too many resources can generate surprising monthly bills! Consequently, it greatly influences whether the application survives its infancy.
Web & Worker Role Definitions
web role: A web role provides a dedicated Internet Information Services (IIS) web-server used for hosting front-end web applications.
worker role: Applications hosted within worker roles can run asynchronous, long-running or perpetual tasks independent of user interaction or input.
Utilizing The Full Potential of Your Cloud Services
In this example, data flows from an input queue, to converter Worker Roles that put messages on a persistence queue. The persistence Worker Role then reads from the persistence queue and inserts the data into a Windows Azure SQL Database.
Since the number of converter Worker Roles varies from 1 to 10, the persistence Worker Role has been put in place to protect the system from being throttled by the Windows Azure SQL Database Service.
Initial architecture (blue arrows show the data flow)
Using this architecture satisfied most of my requirements. But I had a small problem, I wasn’t using my Roles to their full potential and I wasting precious cycles. The converter Worker Roles used 60% of their CPUs and the persistence Worker Role used 15% of its CPU.
Speeding up the conversion process meant adding more instances of the converter Worker Role. Doing so, also meant paying more and I had to asked myself if it was really worth the extra money? I mean, I had plenty of unused cycles…
At this point I took a closer look at the conversion processes, and found that many parts of it weren’t bound to the converter Worker Role. So I subdivided the conversion process into tasks and deployed the necessary code to the persistence Worker Role. Then setup a new queue that would be consumed by all the Worker Roles.
Each Worker Role is then configured to contribute according to its available resources. In my case, the converter Worker Role was configured to process 10 messages from the distributed queue. The persistence Worker Role, being less utilized, was configured to processes 25 messages in parallel. Both roles, had extra work and were now contributing to the throughput of the entire Windows Azure solution.
Redesigned architecture (blue arrows show the data flow)
The new architecture gave me surprising results. It cut the processing time in half and prevented me from having to pay for additional instances. The CPUs from all the Worker Roles now operated at a steady 87%.
Using a distributed queue, allowed all the instances to contribute to the global processing. It allowed me to exploit unused cycles from my Worker Roles. Consequently, when the input queue is empty, the converter Worker Roles contribute 100% of their resources to processing messages from the distributed queue.
For this strategy to work, you will need to consider the following:
- The number of messages – keep a close eye on the number of messages added to the distributed queue. This is can be a potential bottleneck.
- Fatty VS Chatty – find the right balance between too many messages and messages that are too big or take too long to process.
- Identify parts of you process that can be distributed to other Roles for processing
- Be sure not to stress your Roles. Too many threads will result in an ineffective use of precious CPU cycles.
- Ultimately, the goal is to find the right balance between processing work from the Worker Role’s dedicated queue and from the distributed queue.