Windows Azure: Cloud service development best practices	Sriram Krishnan	Program Manager	Microsoft Corporation       sriramk@microsoft.com
				1980
void quicksort(int* array, int left, int right){if(left >= right)return;int index = partition(array, left, right);quicksort(array, left, index - 1);quicksort(array, index + 1, right);}
				simplicity
Act IArchitecture
Networks are unreliable
Hardware fails
A few design choices
Big, reliable, expensive machine
Several commodity machines
Lots and lots of commodity machines
A few challenges
What do you do about that pesky thing called state?
Go horizontalGo stateless
Store state in Windows Azure storage
And it is the default out of the box!
Session state provider<system.web>...	<sessionStatemode="Custom"customProvider="TableStorageSessionStateProvider">            <providers>                <addname="TableStorageSessionStateProvider“       		type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"                     applicationName=“Foo” />            </providers>	</sessionState></system.web>
How do you deal with unreliable components?
Be loosely coupled
Use Windows Azure queues for separation of work
Default.aspx(Input + Making Coffee)LB
Tight coupling : Default.aspx.cspublicpartialclass_Default : System.Web.UI.Page    {                 protectedvoid Button1_Click(objectsender,EventArgs e)        {            var order = txtOrder.Text;            ProcessOrder(order);        }	 protectedvoidProcessOrder(string order)        { 		//Make some coffee! ...        }     }
LBDefault.aspx(Input)Worker.cs(Make Coffee)Windows Azure Queues
Loose coupling : Default.aspx.cspublicpartialclass_Default : System.Web.UI.Page    {                 protectedvoid Button1_Click(objectsender,EventArgs e)        {            var order = txtOrder.Text;            QueueStorageqStore = QueueStorage.Create(_account);            MessageQueueorderQ = qStore.GetQueue("OrderQueue");            orderQ.PutMessage(newMessage(order));       	 }     }
Loose coupling : WorkerRole.cspublic class WorkerRole : RoleEntryPoint    {        public override void Start()        {            QueueStorageqStore = QueueStorage.Create(_account);            MessageQueueorderQ = qStore.GetQueue("OrderQueue");            while (true)            {               Message msg=orderQ.GetMessage();if( msg != null)                	ProcessOrder(msg.ContentAsString());            }        }               protected void ProcessOrder(string order)        {//Make some coffee! ...        }
How do you deal with varying load?
Build a thermostat for your service
How do you deal with failures?
Use Windows Azure storage for valuable data
Be prepared to reconstruct local state…
…since it can disappear any time
Retry on transient failuresBut…
Be idempotent
Don’t launch a DoS attack on yourself
Be predictable
Avoid shutdown code
Know when to throttle and shed load
 Case study: SmugMug and SkyNet
 When is ‘good enough’ good enough?
The resiliency of email
 Do all apps need the same guarantees?
It's a knob
Stateless front-endsLoose couplingBuilding a thermostatRetrying on failuresLoosening consistencyRecap
End of Act I
Act IIUpdates
Updates are hard
Hard to ‘undo’ a failed deployment
Need to deal with both code and schema changes
Code + dataUpdate only one at a time
Code vNData vN
Code vN +1 Data vNCode vN
Data vN+1Code vNData vN
Be compatible
If it looks like a duck and walks like a duck…http://www.flickr.com/photos/gaetanlee/298160415/
Use version numbers in schema
                                  }Schema without versioning  classEmployee : TableStorageEntity    {        public Employee(stringfirstName, stringlastName) :            base(firstName, lastName) //partition key, row key        {}         publicstringJobTitle        {             get;             set;         }     }  ...       varqResult = fromempinsvc.CreateQuery<Employee>(EmployeeDataServiceContext.EmployeeTable)       whereemp.PartitionKey == "Steve" && emp.RowKey == "Marx              selectemp;
                                  }Schema *with* versioning  classEmployee : TableStorageEntity    {        public Employee(stringfirstName, stringlastName) :            base(firstName, lastName)        {}         publicstringJobTitle        {             get; set;         }         publicint Version        {            get; set;        }     }  ...       varqResult = fromempinsvc.CreateQuery<Employee>(EmployeeDataServiceContext.EmployeeTable)       whereemp.PartitionKey == "Steve" && emp.RowKey == "Marx   	&& emp.Version == 1              selectemp;
How do you do upgrades without downtime?
Windows Azure’s rolling upgrades
Stage DeploymentProduction DeploymentSwap for zero downtime upgrade
+Stop + start for big changes or if downtime isn’t an issue
Future: Precise control
When is the best time to update a service?
Use the Pacific Ocean
 Case study: Windows Live ID
Update code or dataMaintain compatVersioning in schemasRolling upgradesRecap
End of Act II
 December 4th, 1996
Oh Oh!
Trace logs
Trickiest patch ever
Act IIIWhen things go wrong…
How do I debug?
Use the Windows Azure SDK and debug locally to find bugs
Separate code and config
           Configuration files ServiceDefinition.csdef<ServiceDefinitionname="DemoService">  <WebRolename="WebRole">       <ConfigurationSettings>      <Setting name="Color"/>    </ConfigurationSettings>  </WebRole></ServiceDefinition>ServiceConfiguration.cscfg<ServiceConfigurationserviceName="DemoService">  <Rolename="WebRole">    <ConfigurationSettings>      <Setting name ="Color" value ="Red"/>    </ConfigurationSettings>  </Role></ServiceConfiguration>
Windows Azure’s configuration update mechanism
How do I debug the cloud?
Logging
           Configurable logging  <?xmlversion="1.0"?><ServiceConfigurationserviceName=“DemoService”>  <Rolename="WebRole">    <Instancescount="1"/>    <ConfigurationSettings>      <Settingname ="LogLevel"value ="Verbose"/>    </ConfigurationSettings>  </Role></ServiceConfiguration>...if (RoleManager.GetConfigurationSetting("LogLevel") == "Verbose")       RoleManager.WriteToLog("Information", "Some log message");
{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}Tag data with unique ID to track across the system
How do I get notified when something bad happens?
!Windows Azure’s alerts
!Email / IM / Phone
The Big Red Button
Use the SDKSeparate code and configConfigurable loggingAlertsThe Big Red ButtonRecap
End of Act III
Credits & Acknowledgements James Hamilton http://research.microsoft.com/~jamesrh/Emre Kicimanhttp://research.microsoft.com/~emrek/Pat Hellandhttp://blogs.msdn.com/pathelland/What really happened on Mars http://research.microsoft.com/~mbj/mars_pathfinder/Flickr blog post http://code.flickr.com/blog/2008/09/26/flickr-engineers-do-it-offline/Don MacAskillhttp://blogs.smugmug.com/don/
One final story
    William of Ockhamc. 1288 - c. 1348
Numquamponendaestpluralitas sine necessitatePlurality ought never be posited without necessity
KISS
simplicity
sriramk@microsoft.comwww.sriramkrishnan.com
© 2008 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation.  Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation.   MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Windows Azure - Cloud Service Development Best Practices