Apply configuration to worker role instances from web role - azure

Good day,
I would like to ask a conceptual question that has been tearing my mind for a while. There is no right or wrong answer here, probably, but I hope to get better understanding of my options.
Situation:
I have a Windows Azure Application. It consists of ONE Web Role with ONE instance and ONE worker role with TWO instances.
The main focus is on the worker role. It implements Quartz.NET scheduler to perform a task of getting information from a CRM system, making a table out of it and uploading to FTP server, say, every 8 hours. Very simple, nothing fancy.
The web role is used for manually triggering the job if someone needs it to run between 8 hour intervals. Simple user interface with pretty much one button.
However I would like to have a possibility to make it possible to change some configuration options of the worker role from the web role. For example credentials of destination FTP server and schedule of the job e.g. make it run hourly instead of 8 hours. The configuration DOES NOT need to persist if role goes offline. At the moment config is one in a static class.
This wouldn't seem a problem if I was running one worker role instance: I would send a message from web role via queue and change some static variables in the worker role, for example. But what confuses me is the message queues can be only picked up by one role instance, not both at the same time. So I will end up having the job run every 8 hours in one instance and every hour on another.
Is there any way to notify both instances that configuration needs to change?

There are several ways you could accomplish this. Let me offer two, aside from what #Gaurav suggested:
Windows Azure configuration settings. If you store your ftp server name and time interval as configuration settings, and then change the configuration, each role instance can capture and handle the RoleEnvironment.Changing event, and take action based on new settings.
Service bus pub/sub. You can have each role instance subscribe to a configuration change topic. Then, whenever you have a change, publish the change to the topic, and each instance, being subscribers, will receive the message and act accordingly.

One possibility would be to do a "PEEK" at message by your worker role instances instead of "GET" message. That way the message will remain visible to all the instances. Obviously the challenge there would be when to delete the message. Other alternative would be create a separate queue for each worker role instance (you can name the queues so that each worker role instance would actually GET the message from the queue intended for that instance e.g. if your worker role instances are say WorkerRole1_IN_0, WorkerRole1_IN_1, you could name your queues like workerrole1-in-0, worker-in-1 and so on). Just thinking out loud :)

Related

Manage Scaling of Worker Role Programmatically

I'm looking into restructuring the application that I'm working on to find a way that will cut costs and give us a lot more room for scalability. In essence, the application is currently hosted on Azure as one large web app which users can log into, do some computationally expensive work on data stored in memory on the web app, and then eventually log off.
When looking into another way to scale this, one idea was to use Worker Roles. Instead of doing the processing on the web app, which currently requires us to use a fairly expensive pricing tier, we could use Service Bus to pass messages with the relevant data to a Worker Role instance, which would do this processing and send back the results.
The most cost-effective way to do this it seems, would be to create a small instance of a Worker Role for each user that logs on, which would deal exclusively with their requests (using, for example, a queue named after the user's ID) and then be destroyed when the user's session ends.
I have the code to determine when to spin up an instance, how to pass these messages back and forth and when to shut an instance down, but I'm having difficulty finding documentation for any methods or API calls that would allow me to do this easily. The closest I can find for deleting an instance is described here, but I can't find anything for creating them.
What is the best way to spin instances up and down on Azure? What alternatives are available to me? I'm also happy to hear alternative proposals on how to architect this.
The most cost-effective way to do this it seems, would be to create a
small instance of a Worker Role for each user that logs on, which
would deal exclusively with their requests (using, for example, a
queue named after the user's ID) and then be destroyed when the user's
session ends.
I would not recommend this approach. Here are my reasons:
The number of Virtual Machine cores are limited in a subscription. Imagine a scenario that you get 1000s of users logged in into your application. Creating 1000s of Worker Role instances would not be allowed by Azure. You would need to take special permission from Microsoft to do that.
Spinning up a VM takes time. When you create a new Worker Role deployment for your user, it is not instantaneous. Depending on the complexity of your role, it may take anywhere from 5 - 10 minutes to start a new Worker Role instance.
It's not an effective approach. Your basic idea is to create a new Worker Role instance when a user logs in is based on the assumption that user will do some compute intensive task. What if the user doesn't want to perform this intensive task (I may be wrong here because I don't know much about your application). Then in that case, you have created a VM instance which is of no use. Again your assumption is that user will always log out. What if the user simply closes the browser? How will you detect that user has left your application and you would need to terminate the worker role instance you created for that user.
It's not an efficient approach. The whole premise of Cloud Computing is built around shared resources. Having a VM dedicated for a user does not sound like an efficient approach.
Possible Solution
Instead of spinning of new worker role instances, may I suggest you take a look at scaling options. Basically the idea is to start with a shared pool of Worker Role instances. When a user logs in and start a task, web role writes a message in Service Bus queue which gets dequeued by a worker role instance which does the work and return the result. Set a maximum number of tasks a worker role could process. If you exceed that count, spin off a new instance of worker role. You can take a look at auto-scaling feature available in Azure Management Portal or look at some 3rd party services which can do this scaling for you.
Using dedicated instances for each user is not a good idea. Utilization will be low, costs will be high and each subscription has a cap of 20 CPU cores by default, so you'll have to first ask support to increase the quota.
A better approach would be to combine the web and worker role into one - once more load comes in you just scale it out. You can still use whatever is convenient for you to store the user requests - a queue or whatever else. So IIS of the role will be pushing data there and the "infinite loop" part (role enrty point Run()) will be processing the data and storing the results and then the web server will fetch the results and feed them back to users.

Azure service bus subscriptions for auto-scaled web sites

I'm using the Azure service bus topic in a publish/subscription pattern. I've got one topic and two subscriptions. One for the web site and one for a webjob. This works fine when only running one web site instance.
When Azure scales up to two instances the two webjob instances still use the same subscription so any single message is only handled by one of them which is exactly what I want.
But the same is true for the web sites which is not what I want. Both web site instances need to receive all messages and therefor need their own subscription.
Is there a way to get an "instance" name for the web sites and making the subscription dynamically (and remove the subscription again when the web site is scaled back)?
I could create a subscription called %HOSTNAME%-web or something similar. But how do I remove them afterwards when no longer needed?
If you want all instances to receive a copy of the message, then as you state you will need to refactor so that each instance creates its own subscription.
To implement a "volatile" queue, look to the QueueDescription parameter " AutoDeleteOnIdle". http://msdn.microsoft.com/en-us/library/windowsazure/microsoft.servicebus.messaging.queuedescription.autodeleteonidle.aspx This should give you close to what you're looking for, just be careful to set the TimeSpan to a duration that will ensure you don't miss messages.
Alternative, if you only foresee scaling up to a few instances, you can just set the time to life on your messages appropriately and leave the queues in place to be reused the next time you "scale up" (although using a host name for this likely wouldn't be a good idea). Depending on message volume, the cost might be small compared to the cost of time required to develop an alternative approach.

Can we have a worker Role and a web role in a single instance of Azure Cloud Services

I am just about to move my website, database and a background scheduler onto the Azure platform.
I've to use cloud services with web & worker role. Now my question is that do I need separate instances for each type of role, or one instance is capable of hosting multiple types of role ?
You cannot have a combined web and worker role instance. It can be one or the other. However, it is possible to have the web role do background processing, so it can host the background workload.
See this SO question for a couple of options
Azure WebRole Scheduled Task Every Morning
That talks about running a task each morning. Obviously you can do it more frequently, as appropriate for your application.
Be aware of the scalability limitations of this though. Once your traffic ramps up, it will make sense to break it out into separate web and worker roles.
In fact, even if your background workload is light, it might still make more sense for you to go for a separate architecture from the start and use XS instances for the background processing.
Technically you can't have a role of both types. Yet a web role is just the same as a worker role, it just has IIS configured. So you can merge them into one web role - IIS will run in a separate process and role entry point Run() will run some endless loop for "backend" processing. See this similar question.
This will make scaling more complicated. The whole idea of separate roles (remember you can have not only one web role and one worker role, you can have for example four worker roles and two web roles if that's appropriate for your solution) is that you can scale them separately.
It looks like once you merge two roles into one you no longer can fine scale them. This is not true most of the time - you just have to change metrics.
For example, you wanted to run one web role instance for each thousand HTTP requests per minute and one worker role instance for each ten requests in the backend queue. Okay, this means that each thousand HTTP requests needs the same amount of processing power as ten items in the backend queue. So you craft a new metric that takes both parameters and deduces a number of instances. Like you have five thousand requests per minute and twenty requests in the backend queue - you need seven instances of am merged role.
This won't work for all applications, but most of them will use this approach just fine. The bonus is that you avoid cases when either of the roles in idling because the current load gets onto another role.

Windows Azure Inter-Role communication

I want to create an Azure application which does the following:
User is presented with a MVC 4 website (web role) which shows a list of commands.
When the user selects a command, it is broadcast to all worker roles.
Worker roles process the task, store the results and notify web role
Web role displays the combined results of the worker roles
From what I've been reading there seem to be two ways of doing this: the Windows Azure Service Bus or using Queues. Each worker role also stores the results in the database.
The Service Bus seems more appropriate with its publish/subscribe model, so all worker roles would get the same command and roughly the same time. Queues seem easier to use though.
Can the service bus be used locally with the emulator when developing? I am using a free trial and cannot keep the application constantly whilst still developing. Also, when using queues how can you notify the web role that processing is complete?
I agree. ServiceBus is a better choice for this messaging requirement. You could, with some effort, do the same with queues. But, you'll be writing a lot of code to implement things that the ServiceBus already gives you.
There is not a local emulator for ServiceBus like there is for the Azure Strorage service (queues/tables/blobs). However, you could still use the ServiceBus for messaging between roles while they are running locally in your development environment.
As for your last question about notifying the web role that processing is complete, there are a several ways to go here. Just a few thoughts (not exhaustive list)...
Table storage where the web role can periodically check the status of the unit of work.
Another ServiceBus Queue/topic for completed work.
Internal endpoints. You'll have to have logic to know if it's just an update from worker role N or if it is indicating a completed unit of work for all worker roles.
I agree with Rick's answer, but would also add the following things to think about:
If you choose the Service Bus Topic approach then as each worker role comes online it would need to generate a subscription to the topic. You'll need to think about subscription maintenance of when one of the workers has a failure and is recycled, or any number of reasons why a subscription may be out there.
Telling the web role that all the workers are complete is interesting. The options Rick provides are good ones, but you'll need to think about some things here. It means that the web role needs to know just how many workers are out there or some other mechanism to decide when all have reported done. You could have the situation of five worker roles receieving a message and start working, then one of them starts to repeatedly fail processing. The other four report their completion but now the web role is waiting on the fifth. How long do you wait for a reply? Can you continue? What if you just told the system to scale down and while the web role thinks there are 5 there is now only 4. These are things you'll need to to think about and they all depend on your requirements.
Based on your question, you could use either queue service and get good results. But each of them are going to have different challenges to overcome as well as advantages.
Some advantages of service bus queues is that it provides blocking receipt with a persistent connection (up to 100 connections), it can monitor messages for completion, and it can send larger messages (256KB).
Some advantages of storage queues over the service bus solution is that it's slightly faster (if 15 ms matters to you), you can use a single storage system (since you'll probably be using Storage for blob and table services anyways), and simple auto-scaling. If you need to auto-scale your worker roles based on the load, passing the the requests through a storage queue makes auto-scaling trivial -- you just setup auto-scaling in the Azure Cloud Service UI under the scale tab.
A more in-depth comparison of the two azure queue services can be found here: http://msdn.microsoft.com/en-us/library/hh767287.aspx
Also, when using queues how can you notify the web role that processing is complete?
For the Azure Storage Queues solution, I've written a library that can help: https://github.com/brentrossen/AzureDistributedService.
It provides a proxy layer that facilitates RPC style communication from web roles to worker roles and back through Storage Queues.

Should I assign all my back end processing to a worker role?

Fairly new to Azure and the whole worker role concept, previously if I wanted some back end work done I would just create a windows forms application and have it as a scheduled task.
With my new site I have created a windows form application which I have running every hour which reads in XML feeds and does all the processing an inserts the information into sql azure.
There is also image links that I want to store in azure blob storage and possibly resize them , which I had trouble doing from my vb.net application.
My question is should I move all the processing from my windows form application to the worker role or should I set up a worker role to just process the image to blob storage?
How much compute time does a worker role use? I have seen examples of where there is a sleep timer but is it possible to run it every hour on the hour?
You can easily set up a timer to trigger every hour on the hour. Where you run your code this depends on your application architecture. If you have a web role, you can place this in your web role instead of a dedicated worker role unless you really need the extra processing power of a separate instance and are willing to pay for it. Also, the number of instances of each role (web/worker) will add complications to the solution.
A detailed outline of your architecture would provide a better frame of reference for the answer you seek.
Worker role is designed for doing all sort of background activities. so you can move all of processing logic from windows application to workerrole. It is simply a class library with an entry point class.
You can not schedule any work automatically in worker role. You will have to right a logic for your self. worker role is executing a piece of code in an infinite loop. You will be charged for the no. of hours you have used in worker role (compute), it does not matter your worker role is idle or processing something. plus if you are using blob and queue, you will also be charged for accessing them and for storing data in them.

Resources