<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Brian Swan</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/brian_swan/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/brian_swan/feed.xml</link>
    <description>Insights on HDInsight</description>
    <lastBuildDate>Thu, 23 Jul 2015 01:58:07 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Analyzing Windows Azure Storage Logs</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/analyzing-windows-azure-storage-logs</link>
      <pubDate>Thu, 30 Jan 2014 12:05:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2014/01/30/analyzing-windows-azure-storage-logs/</guid>
      <description><![CDATA[A few weeks ago, I wrote a post that described how to maximize throughput between HDInsight clusters...]]></description>
      <content:encoded><![CDATA[<p>A few weeks ago, I wrote a post that described how to <a href="https://blogs.msdn.com/b/brian_swan/archive/2013/11/25/maximizing-hdinsight-throughput-to-azure-blob-storage.aspx">maximize throughput between HDInsight clusters and Windows Azure Storage</a>. One of the suggestions I made was to adjust your HDInsight cluster&rsquo;s self-throttling mechanism - i.e. tune the <span style="font-family: courier new;">fs.azure.selfthrottling.read/write.factor</span> parameters. I also suggested that the best way to find the optimal parameter values was ultimately to turn on <a href="https://www.windowsazure.com/en-us/manage/services/storage/how-to-monitor-a-storage-account/#configurelogging">storage account logging</a> and analyze the logs after you had run a job or two. This post describes how to use a new command-line tool (available as part of the <a href="https://hadoopsdk.codeplex.com/">.NET SDK for Hadoop</a>) that makes analysis of storage account logs easy.</p>
<p>Here is a summary of the steps to follow for analyzing your storage logs:</p>
<ol>
<li>Install the <a href="https://hadoopsdk.codeplex.com/releases/view/117906">Windows Azure HDInsight Log Analysis Toolkit</a>.</li>
<li>Turn on <a href="https://www.windowsazure.com/en-us/manage/services/storage/how-to-monitor-a-storage-account/#configurelogging">logging for your storage account</a>.</li>
<li>Run a Hadoop job. (I&rsquo;ll run the <a href="https://www.windowsazure.com/en-us/manage/services/hdinsight/howto-run-samples/sample-10gb-graysort/">10GB GraySort sample</a> in my example below.)</li>
<li>Download your storage logs using the Log Analysis Tool (LAT).</li>
<li>Analyze your storage logs using the LAT.</li>
</ol>
<p>Read on for details about each step&hellip;</p>
<h1>Install the Log Analysis Tool (LAT)</h1>
<p>Download and run the .msi installer here: <a href="https://hadoopsdk.codeplex.com/releases/view/117906">Windows Azure HDInsight Log Analysis Toolkit</a>. The .msi will install the toolkit in the C:\Program Files (x86)\Windows Azure HDInsight Log Analysis Toolkit\ directory. The lat.exe will not be added to your Path environment variable by default.</p>
<h1>Turn on Storage Account Logging</h1>
<p>You can get detailed information about successful and failed requests to your storage account by turning on storage account logging. To do this, follow the instructions <a href="https://www.windowsazure.com/en-us/manage/services/storage/how-to-monitor-a-storage-account/#configurelogging">here</a>. (For general information about storage analytics, see About <a href="https://msdn.microsoft.com/en-us/library/windowsazure/hh343262.aspx">Storage Analytics Logging</a>.)</p>
<h1>Run a job</h1>
<p>For example purposes, I&rsquo;ll run the 10GB GraySort sample. The jars for this sample are already in place when you <a href="https://www.windowsazure.com/en-us/manage/services/hdinsight/get-started-hdinsight/#provision">provision an HDInsight cluster</a>. The instructions for running this sample are here: <a href="https://www.windowsazure.com/en-us/manage/services/hdinsight/howto-run-samples/sample-10gb-graysort/">The 10GB GraySort Sample</a>. The PowerShell code I used to submit the job is below. A few things to note:</p>
<ul>
<li>As one of the arguments for the &ldquo;teragen&rdquo; job, I have &ldquo;1000000000&rdquo; instead of &ldquo;100000000&rdquo; as is used in the documentation. This is to increase the amount of data generated, sorted, and validated. This is a more realistic example.</li>
<li>I submitted this job to a 16-node HDInsight cluster. Clusters with fewer nodes are not likely to run into throttling by Windows Azure Storage as they simply cannot produce enough throughput to go beyond the storage throttling limits.</li>
<li>I am manually setting the cluster&rsquo;s self-throttling factors to &ldquo;1.0&rdquo;, which essentially turns self-throttling off. My intention is to produce some level of throttling by Azure Storage for the purposes of this blog post.</li>
</ul>
<blockquote>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$clusterName = <span style="color: #006080;">"bswandemo"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">#-----------TERAGEN------------------</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">$teragenJob = New-AzureHDInsightMapReduceJobDefinition `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -JobName <span style="color: #006080;">"teragenJob"</span> `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -JarFile <span style="color: #006080;">"wasb:///example/jars/hadoop-examples.jar"</span> `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -ClassName <span style="color: #006080;">"teragen"</span> `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    &ndash;Arguments <span style="color: #006080;">"-Dmapred.map.tasks=50"</span>, <span style="color: #006080;">"1000000000"</span>, <span style="color: #006080;">"wasb:///example/data/10GB-sort-input"</span> `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -Defines @{<span style="color: #006080;">"fs.azure.selfthrottling.write.factor"</span> = <span style="color: #006080;">"1.0"</span>}</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$teragenJob | Start-AzureHDInsightJob -Cluster $clusterName `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">            | Wait-AzureHDInsightJob</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">#----------TERASORT-------------------</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$terasortJob = New-AzureHDInsightMapReduceJobDefinition `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -JobName <span style="color: #006080;">"terasortjob"</span> `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -JarFile &ldquo;/example/jars/hadoop-examples.jar&rdquo; `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -ClassName <span style="color: #006080;">"terasort"</span> `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    &ndash;Arguments <span style="color: #006080;">"-Dmapred.map.tasks=50"</span>, &ldquo;-Dmapred.reduce.tasks=25&rdquo;, &ldquo;wasb:///example/data/10GB-sort-input&rdquo;, &ldquo;wasb:///example/data/10GB-sort-output&rdquo;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$terasortJob | Start-AzureHDInsightJob -Cluster $clusterName `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">             | Wait-AzureHDInsightJob </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">#----------TERAVALIDATE----------------</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$teravalidateJob = New-AzureHDInsightMapReduceJobDefinition `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -JarFile &ldquo;/example/jars/hadoop-examples.jar&rdquo; `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -ClassName <span style="color: #006080;">"teravalidate"</span> `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    &ndash;Arguments <span style="color: #006080;">"-Dmapred.map.tasks=50"</span>, &ldquo;-Dmapred.reduce.tasks=25&rdquo;, &ldquo;wasb:///example/data/10GB-sort-output&rdquo;, &ldquo;wasb:///example/data/10GB-sort-validate&rdquo; `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -Defines @{<span style="color: #006080;">"fs.azure.selfthrottling.read.factor"</span> = <span style="color: #006080;">"1.0"</span>}</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$teravalidateJob | Start-AzureHDInsightJob -Cluster $clusterName `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                 | Wait-AzureHDInsightJob </pre>
<!--CRLF--></div>
</div>
</blockquote>
<p>&nbsp;</p>
<h1>Download Storage Logs</h1>
<p>Use the Log Analysis Tool (LAT) that you downloaded as part of the .NET SDK for Hadoop to download the storage logs that generated when you ran the job above. (Note that you will have to wait up to 10 minutes for the logs to be generated before you can download them.) To use the download utility, you need 5 pieces of information:</p>
<ul>
<li>-start: The start time of the job.</li>
<li>-end: The end time of the job.</li>
<li>-logcache: The directory to which the logs will be downloaded.</li>
<li>-account: Your storage account name (e.g. bswanstorage).</li>
<li>-key: Your storage account key.</li>
</ul>
<p>With that information, you can run a command similar to this one (the -force option is only necessary if the log cache directory doesn't exist):</p>
<blockquote>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">lat.exe download -start <span style="color: #006080;">"2014-01-02T22:49:00Z"</span> -end <span style="color: #006080;">"2014-01-02T23:23:00Z"</span> -logcache <span style="color: #006080;">"C:\logcache"</span> -account <span style="color: #006080;">"Your account name"</span> -key <span style="color: #006080;">"Your account key"</span> -force</pre>
<!--CRLF--></div>
</div>
</blockquote>
<p>Here&rsquo;s the output:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/8831.image_4A8CDA4A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/8831.image_5F00_4A8CDA4A.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7382.image_thumb_0C93498C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7382.image_5F00_thumb_5F00_0C93498C.png" alt="image" width="694" height="234" border="0" /></a></p>
</blockquote>
<p>Navigating to my <span style="font-family: courier new;">c:\logcache</span> directory, I see the downloaded files:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4657.image_359DE888.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4657.image_5F00_359DE888.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/2514.image_thumb_2A082B49.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/2514.image_5F00_thumb_5F00_2A082B49.png" alt="image" width="528" height="235" border="0" /></a></p>
</blockquote>
<p>&nbsp;</p>
<h1>Analyze Storage Logs</h1>
<p>The next step is to analyze the storage logs. To do this, you again need 5 pieces of information (the 6th is optional):</p>
<ul>
<li>-logcache: The folder you specified when downloading your storage logs.</li>
<li>-account: The name of your storage account.</li>
<li>-start: The start time of the job.</li>
<li>-end: The end time of the job.</li>
<li>-name: The name of the job. This name will be used as part of the name of the file to which the storage analyses are written.</li>
<li>-note: (Optional) This is a note about the job being analyzed.</li>
</ul>
<p>With this information, you can execute a command similar to this:</p>
<blockquote>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">lat.exe throttlinganalysis -logcache <span style="color: #006080;">"C:\logcache"</span> -account <span style="color: #006080;">"Your storage account name"</span> -start <span style="color: #006080;">"2014-01-02T22:49:00Z"</span> -end <span style="color: #006080;">"2014-01-02T23:23:00Z"</span> -name <span style="color: #006080;">"teragen3"</span> -note <span style="color: #006080;">"throttling factor set to 1, 16 node cluster"</span></pre>
<!--CRLF--></div>
</div>
</blockquote>
<p>Here&rsquo;s the output from the command line:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7713.image_37DA7144.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7713.image_5F00_37DA7144.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7317.image_thumb_69D211CE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7317.image_5F00_thumb_5F00_69D211CE.png" alt="image" width="710" height="264" border="0" /></a></p>
</blockquote>
<p>The analysis is written to two .csv files: <span style="font-family: courier new;"><em>jobname</em>.summary.csv</span> and <span style="font-family: courier new;"><em>jobname</em>.details.csv</span> (<span style="font-family: courier new;">teragen3.summary.csv</span> and <span style="font-family: courier new;">teragen3.details.csv</span> in my case). The summary file will contain information similar to this:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/3515.image_0C95DA3D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/3515.image_5F00_0C95DA3D.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/1462.image_thumb_57894B0C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/1462.image_5F00_thumb_5F00_57894B0C.png" alt="image" width="423" height="356" border="0" /></a></p>
</blockquote>
<p>We can see from the summary that some throttling did occur in my case. To get a better idea of when the throttling occurred, we need to look at the details file, which contains information about what happened at each 1-second interval of the job:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/2133.image_376E3E4F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/2133.image_5F00_376E3E4F.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/8080.image_thumb_4540844A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/8080.image_5F00_thumb_5F00_4540844A.png" alt="image" width="701" height="235" border="0" /></a></p>
</blockquote>
<p>What&rsquo;s nice about the details file is that, because it&rsquo;s a .csv file, you can use Excel features to create a picture of throughput for your job. To do this, select columns A through G, select INSERT from the main menu, and choose Scatter from the Charts options, and finally, select the Straight Lines option:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/8802.image_2525778D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/8802.image_5F00_2525778D.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/0572.image_thumb_60E51040.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/0572.image_5F00_thumb_5F00_60E51040.png" alt="image" width="712" height="323" border="0" /></a></p>
</blockquote>
<p>You should see a graph similar to this one:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6648.image_2BD88110.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6648.image_5F00_2BD88110.png"><img style="border: 0px currentcolor; display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/5661.image_thumb_39AAC70B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/5661.image_5F00_thumb_5F00_39AAC70B.png" alt="image" width="703" height="279" border="0" /></a></p>
</blockquote>
<p>As you can see, Azure Storage throttling occurred during the first job (Teragen) because of a high write load.&nbsp; In this particular example, the peak write loads were around 5Gbps which happens to be the throughput quota for uploads to a geo-replicated storage account. So, this example was straying into the red-zone a little.&nbsp; One solution to prevent the Teragen job from issuing writes to Azure Storage above the quota rate is to adjust <span style="font-family: courier new;">fs.azure.selftthrottling.write</span> to produce some self-throttling of storage requests by the Hadoop tasks.&nbsp; Other solutions include increasing storage bandwidth quota, reducing cluster size or reducing the cluster usage for the Teragen job.</p>
<p>Please note that the Log Analysis Tool is still in the &ldquo;experimental&rdquo; phase. We&rsquo;d love to hear your feedback and/or have you contribute to the project.</p>
<p>Thanks.</p>
<p>-Brian</p>]]></content:encoded>
    </item>
    <item>
      <title>Accessing Hadoop Logs in HDInsight</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/accessing-hadoop-logs-in-hdinsight</link>
      <pubDate>Mon, 06 Jan 2014 08:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2014/01/06/accessing-hadoop-logs-in-hdinsight/</guid>
      <description><![CDATA[One of the questions the HDInsight team sees a lot is a variation of the question &ldquo;How do I...]]></description>
      <content:encoded><![CDATA[<p>One of the questions the HDInsight team sees a lot is a variation of the question &ldquo;How do I figure out what went wrong when something does go wrong?&rdquo; If you are familiar with Hadoop, you are probably also familiar with rolling up your sleeves and digging into Hadoop logs to answer this question. However, we&rsquo;ve found that many folks using HDInsight don&rsquo;t know that much of the logging information they are accustomed to using is easily available to them for HDInsight clusters. This is a quick post to outline the types of logs that are written to your Azure storage account when you spin up an HDInsight cluster:</p>
<ol>
<li>Azure setup logs, Hadoop installation logs, and Hadoop Service logs are written to Azure Table Storage, and</li>
<li>Task logs are written to Azure Blob Storage for jobs submitted through Templeton.</li>
</ol>
<p>Read on to find out more.</p>
<h1>Logs Written to Windows Azure Table Storage</h1>
<p>When you create an HDInsight cluster, three tables are automatically created in Azure Table Storage:</p>
<ul>
<li><strong>setuplog</strong>: Log of events/exceptions encountered in provisioning/set up of HDInsight VMs.</li>
<li><strong>hadoopinstalllog</strong>: Log of events/exceptions encountered when installing Hadoop on the cluster. This table may be useful in debugging issues related to clusters created with custom parameters.</li>
<li><strong>hadoopservicelog</strong>: Log of events/exceptions recorded by all Hadoop services. This table may be useful in debugging issues related to job failures on HDInsight clusters.</li>
</ul>
<blockquote>
<p><strong>Note</strong>: To make these table names unique, the names are in this format: u<em>clusternameDDmonYYYY</em>at<em>HHMMSSsss</em>hadoopservicelog.</p>
</blockquote>
<p>There are many tools available for accessing data in these tables (e.g. Visual Studio, Azure Storage Explorer, Power Query for Excel). Here, I&rsquo;ll use <a href="https://blogs.msdn.com/b/powerbi/archive/2013/11/11/november-update-of-power-query-preview-is-now-available.aspx">Power Query</a> first, then <a href="https://msdn.microsoft.com/en-us/library/windowsazure/ff683677.aspx">Visual Studio</a>, to explore the <strong>hadoopservicelog</strong> table. In both cases, I&rsquo;ll assume you have <a href="https://www.windowsazure.com/en-us/manage/services/hdinsight/provision-hdinsight-clusters/">created an HDInsight cluster</a>.</p>
<h2>Using Power Query</h2>
<p>I&rsquo;ll assume you have <a href="https://www.microsoft.com/en-us/download/details.aspx?id=39933">Power Query installed</a>:</p>
<p>1. <a href="https://office.microsoft.com/en-us/excel-help/connect-to-windows-azure-table-storage-HA104122607.aspx">Connect to Azure Table Storage from Excel</a>.</p>
<p>2. Right click the <strong>hadoopservicelog</strong> table in the Navigator pane and select <strong>Edit Query</strong>.</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4353.image_7B61BC88.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4353.image_5F00_7B61BC88.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7080.image_thumb_61F9B94E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7080.image_5F00_thumb_5F00_61F9B94E.png" alt="image" width="357" height="172" border="0" /></a></p>
</blockquote>
<p>3. Optional: Delete the Partition Key, Row Key, and Timestamp columns by selecting them, then clicking <strong>Remove Columns</strong> from the options in the ribbon.</p>
<p>4. Click on the <strong>Content</strong> column to choose the columns you want to include. For my example, I chose <strong>TraceLevel</strong>, <strong>Role</strong>, and <strong>ComponentName</strong>:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6013.image_6FCBFF49.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6013.image_5F00_6FCBFF49.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7573.image_thumb_2B8B97FD.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7573.image_5F00_thumb_5F00_2B8B97FD.png" alt="image" width="364" height="485" border="0" /></a></p>
</blockquote>
<p>5. Select the TraceLevel, Role, and ComponentName columns, and then click <strong>Group By</strong> control in the ribbon.</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7506.image_0B708B40.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7506.image_5F00_0B708B40.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4375.image_thumb_04514EC8.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4375.image_5F00_thumb_5F00_04514EC8.png" alt="image" width="367" height="187" border="0" /></a></p>
</blockquote>
<p>6. Click OK in the Group By dialog box:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4774.image_$2890.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4774.image_5F00_24002890.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/8400.image_thumb_5FBFC143.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/8400.image_5F00_thumb_5F00_5FBFC143.png" alt="image" width="374" height="197" border="0" /></a></p>
</blockquote>
<p>7. Finally, click<strong> Apply &amp; Close</strong>:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7026.image_0D40E107.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7026.image_5F00_0D40E107.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7848.image_thumb_340EF747.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7848.image_5F00_thumb_5F00_340EF747.png" alt="image" width="377" height="361" border="0" /></a></p>
</blockquote>
<p>You can now use Excel to filter and sort as necessary. Obviously, you may want to include other columns (e.g. Message) in order to drill down into issues when they occur, but selecting and grouping the columns described above provides a decent picture of what is happening with Hadoop services. The same idea can be applied to the <strong>setuplog</strong> and <strong>hadoopinstalllog</strong> tables.</p>
<h2>Using Visual Studio</h2>
<p>1. In Visual Studio, select<strong> Server Explorer</strong> from the <strong>View</strong> menu:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/8510.image_2CEFBACF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/8510.image_5F00_2CEFBACF.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4718.image_thumb_0CD4AE12.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4718.image_5F00_thumb_5F00_0CD4AE12.png" alt="image" width="360" height="199" border="0" /></a></p>
</blockquote>
<p>2. Expand <strong>Windows Azure</strong>, right-click <strong>Storage</strong>, and select <strong>Attach External Storage</strong>&hellip;</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/5488.image_1AA6F40D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/5488.image_5F00_1AA6F40D.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/2555.image_thumb_56668CC0.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/2555.image_5F00_thumb_5F00_56668CC0.png" alt="image" width="369" height="303" border="0" /></a></p>
</blockquote>
<p>3. Provide your storage account name and key.</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7853.image_2159FD90.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7853.image_5F00_2159FD90.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/8424.image_thumb_2F2C438B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/8424.image_5F00_thumb_5F00_2F2C438B.png" alt="image" width="371" height="282" border="0" /></a></p>
</blockquote>
<p>4. Expand your storage account, expand <strong>Tables</strong>, and double-click the <strong>hadoopservicelog</strong> table.</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6371.image_3CFE8986.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6371.image_5F00_3CFE8986.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/3250.image_thumb_6EF62A10.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/3250.image_5F00_thumb_5F00_6EF62A10.png" alt="image" width="374" height="312" border="0" /></a></p>
</blockquote>
<p>5. Add a filter to exclude rows in which TraceLevel = &lsquo;INFO&rsquo; (more info about constructing filters here: <a href="https://msdn.microsoft.com/en-us/library/windowsazure/ff683669.aspx">Constructing Filter Strings for the Table Designer</a>):</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4721.image_0A9AB607.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4721.image_5F00_0A9AB607.png"><img style="border: 0px currentcolor; display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4743.image_thumb_186CFC02.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4743.image_5F00_thumb_5F00_186CFC02.png" alt="image" width="541" height="431" border="0" /></a></p>
</blockquote>
<p>If you are a developer, using Visual Studio provides you the extra level of detail I omitted when using Excel, and you don&rsquo;t need an &ldquo;extra&rdquo; tool.</p>
<h1>Logs Written to Windows Azure Blob Storage</h1>
<p>The logs written to Windows Azure Tables (as described above) provide one level of insight into what is happening with an HDInsight cluster. However, these tables do not provide task-level logs, which can be helpful in drilling further into issues when they occur. To provide this next level of detail, HDInsight clusters are configured to write task logs to your Blob Storage account for any job that is submitted through Templeton. (Practically, this means jobs submitted using the <a href="https://hadoopsdk.codeplex.com/wikipage?title=PowerShell%20Cmdlets%20for%20Cluster%20Management&amp;referringTitle=Documentation">Windows Azure PowerShell cmdlets</a> or the <a href="https://hadoopsdk.codeplex.com/wikipage?title=Job%20Submission%20.NET%20APIs&amp;referringTitle=Documentation">.NET Job Submission APIs</a>, not jobs submitted through RDP/command-line access to the cluster.) I&rsquo;ll illustrate how to access these logs by submitting a job and then using <a href="https://clumsyleaf.com/products/cloudxplorer">CloudXPlorer</a> to view the logs.</p>
<h2>Submit a job</h2>
<p>I&rsquo;ll run the WordCount example that is installed with an HDInsight cluster. You can submit this job using either the <a href="https://hadoopsdk.codeplex.com/wikipage?title=PowerShell%20Cmdlets%20for%20Cluster%20Management&amp;referringTitle=Documentation">PowerShell cmdlets</a> or the <a href="https://hadoopsdk.codeplex.com/wikipage?title=Job%20Submission%20.NET%20APIs&amp;referringTitle=Documentation">.NET Job Submission APIs</a>. Note that in each example I set the <strong>StatusFolder</strong> to &ldquo;wordcountstatus&rdquo;. This will be the folder that contains the task logs. Also note that if you use the PowerShell cmdlets, task logs are collected by default. With the .NET job submission APIs, you must set <span style="font-family: courier new;">EnableTaskLogs = true</span> to collect task logs.</p>
<h3>Powershell cmdlets</h3>
<blockquote>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$clusterName = <span style="color: #006080;">"bswandemo"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$wordCountJobDef = New-AzureHDInsightMapReduceJobDefinition `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -JarFile <span style="color: #006080;">"wasb:///example/jars/hadoop-examples.jar"</span> `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -ClassName <span style="color: #006080;">"wordcount"</span> `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -Arguments <span style="color: #006080;">"wasb:///example/data/gutenberg/davinci.txt"</span>, `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">               <span style="color: #006080;">"wasb:///wordcountoutput"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$wordCountJob = Start-AzureHDInsightJob `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -Cluster $clusterName `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -JobDefinition $wordCountJobDef</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">Wait-AzureHDInsightJob `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -Job $wordCountJob `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -WaitTimeoutInSeconds 3600</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">Get-AzureHDInsightJobOutput `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -Cluster $clusterName `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    -JobId $wordCountJob.JobId `</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    -StandardError</pre>
<!--CRLF--></div>
</div>
</blockquote>
<h3>.NET Job Submission APIs</h3>
<blockquote>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #0000ff;">string</span> clusterName = <span style="color: #006080;">"bswandemo2"</span>;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">var store = <span style="color: #0000ff;">new</span> X509Store();</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">store.Open(OpenFlags.ReadOnly);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">var cert = store.Certificates.Cast&lt;X509Certificate2&gt;().First(item =&gt; item.Thumbprint == <span style="color: #006080;">"{Thumbprint of certificate}"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">var jobSubmissionCreds = <span style="color: #0000ff;">new</span> JobSubmissionCertificateCredential(<span style="color: #0000ff;">new</span> Guid(<span style="color: #006080;">"{Your Subscription ID}"</span>), cert, clusterName);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">var jobClient = JobSubmissionClientFactory.Connect(jobSubmissionCreds);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">var MRJob = <span style="color: #0000ff;">new</span> MapReduceJobCreateParameters()</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">{</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    ClassName = <span style="color: #006080;">"wordcount"</span>,</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    JobName = <span style="color: #006080;">"WordCount"</span>,</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    JarFile = <span style="color: #006080;">"wasb:///example/jars/hadoop-examples.jar"</span>,</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    StatusFolder = <span style="color: #006080;">"wordcountstatus"</span>,</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    EnableTaskLogs = <span style="color: #0000ff;">true</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">};</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">MRJob.Arguments.Add(<span style="color: #006080;">"wasb:///example/data/gutenberg/davinci.txt"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">MRJob.Arguments.Add(<span style="color: #006080;">"wasb:///wordcountoutput"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">var jobResults = jobClient.CreateMapReduceJob(MRJob);</pre>
<!--CRLF--></div>
</div>
</blockquote>
<blockquote>
<p><strong>Note</strong>: If you don&rsquo;t specify a <strong>StatusFolder</strong>, one will be created for you using a GUID for the folder name.</p>
</blockquote>
<p>&nbsp;</p>
<h2>View logs</h2>
<p>After your job completes, you can view the logs using any of the many available tools for viewing Azure Blob Storage. Here, I&rsquo;m using CloudXplorer. Note that a new folder has been created (<strong>templeton-hadoop</strong>) for containing job output information. The files in each of the <span style="font-family: courier new;">job_</span> folders contain high-level job completion information (percentComplete, exitValue, userArgs, etc.). However, under the <strong>admin</strong> folder (under this folder since this was the user who submitted the job), you will find the wordcountstatus (specified at when I submitted the job) that contains task attempt information for each task attempt of the job.</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/3755.image_3F3B1242.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/3755.image_5F00_3F3B1242.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/3678.image_thumb_0A2E8312.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/3678.image_5F00_thumb_5F00_0A2E8312.png" alt="image" width="596" height="433" border="0" /></a></p>
</blockquote>
<p>Each of the <span style="font-family: courier new;">attempt_</span> folders contains <strong>stderr</strong>, <strong>stdout</strong>, and <strong>syslog</strong> files. You can drill into these to get a better understanding of if/when something when wrong:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/0844.image_45EE1BC5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/0844.image_5F00_45EE1BC5.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/5153.image_thumb_10E18C95.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/5153.image_5F00_thumb_5F00_10E18C95.png" alt="image" width="421" height="178" border="0" /></a></p>
</blockquote>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/2514.image_1EB3D290.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/2514.image_5F00_1EB3D290.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/3122.image_thumb_5E7DB915.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/3122.image_5F00_thumb_5F00_5E7DB915.png" alt="image" width="731" height="251" border="0" /></a></p>
</blockquote>
<p>Also note that the <strong>job.xml.html</strong> file contains all the Hadoop settings that were used when running the job you submitted:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6758.image_1C79DA85.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6758.image_5F00_1C79DA85.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/3034.image_thumb_155A9E0D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/3034.image_5F00_thumb_5F00_155A9E0D.png" alt="image" width="498" height="167" border="0" /></a></p>
</blockquote>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6170.image_232CE408.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6170.image_5F00_232CE408.png"><img style="display: inline;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/1464.image_thumb_62F6CA8D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/1464.image_5F00_thumb_5F00_62F6CA8D.png" alt="image" width="734" height="372" border="0" /></a></p>
</blockquote>
<h2>Disabling Logging</h2>
<p>Hopefully, you will find the information logged in your Azure storage account to be useful in debugging Hadoop jobs. I do want to point out, however, that because these logs are written to your storage account, you are being billed for storing them. You should create a retention/clean-up policy that is consistent with your development needs to avoid unnecessary charges.</p>
<p>Currently, collection of task logs (the logs written to Blob Storage) is off by default when using the .NET job submission APIs (December update, version 1.0.4.0). To enable it, set<span style="font-family: courier new;"> EnableTaskLogs = true</span> when defining your job (see the example above). In previous versions, collection of task logs in on by default.</p>
<p>The ability to turn off logging will be available via the PowerShell cmdlets soon.</p>
<p>As always, we&rsquo;re interested in your feedback on the usefulness of these logs.</p>
<p>Thanks.</p>
<p>-Brian</p>]]></content:encoded>
    </item>
    <item>
      <title>Maximizing HDInsight throughput to Azure Blob Storage</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/maximizing-hdinsight-throughput-to-azure-blob-storage</link>
      <pubDate>Mon, 25 Nov 2013 20:12:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2013/11/25/maximizing-hdinsight-throughput-to-azure-blob-storage/</guid>
      <description><![CDATA[The HDInsight service supports both HDFS and Windows Azure Storage (BLOB Service) for storing data....]]></description>
      <content:encoded><![CDATA[<p>The <a href="https://www.windowsazure.com/en-us/manage/services/hdinsight/get-started-hdinsight/">HDInsight service</a> supports both HDFS and <a href="https://www.windowsazure.com/en-us/develop/net/how-to-guides/blob-storage/">Windows Azure Storage (BLOB Service)</a> for storing data. <a href="https://www.windowsazure.com/en-us/manage/services/hdinsight/howto-blob-store/">Using BLOB Storage with HDInsight</a> gives you low-cost, redundant storage, and allows you to scale your storage needs independently of your compute needs. However, Windows Azure Storage allocates bandwidth to a storage account that can be exceeded by HDInsight clusters of sufficient size. If this occurs, Windows Azure Storage will throttle requests. This article describes when throttling may occur and how to maximize throughput to BLOB Storage by avoiding throttling.</p>
<blockquote>
<p><strong>Note</strong>: In HDInsight, HDFS is intended to be used as a cache or for intermediary storage. When a cluster is deleted, data in HDFS will be discarded. Data intended for long-term storage should be stored in Windows Azure Storage (BLOBS).</p>
</blockquote>
<h1>Overview</h1>
<p>If you run a heavy I/O workload on an HDInsight cluster of sufficient size*, reads and/or writes may be throttled by Windows Azure Storage. Throttling can result in jobs running slowly, tasks failing, and (in rare cases) jobs failing. Throttling occurs when the aggregate load that a cluster puts on a storage account exceeds the allotted bandwidth for the storage account. To address this, HDInsight clusters have a tunable self-throttling mechanism that can slow read and/or write traffic to a storage account. The self-throttling mechanism exposes two parameters: <span style="font-family: Courier New;">fs.azure.selfthrottling.read.factor</span> and <span style="font-family: Courier New;">fs.azure.selftthrottling.write.factor</span>. These parameters govern the rate of read and write traffic from an HDInsight cluster to a storage account. Values for these parameters are set at job submission time. Values must be in the range (0, 1], where 1 corresponds to no self-throttling, 0.5 corresponds to roughly 1/2 the unrestricted throughput rate, and so on. Conservative default values for these parameters are set based on cluster size at cluster creation time ("conservative" here means that values are such that throttling is highly unlikely to occur at all, but bandwidth utilization may be below the allocated amount). To arrive at optimal values for the self-throttling parameters, you should <a href="https://www.windowsazure.com/en-us/manage/services/storage/how-to-monitor-a-storage-account/#configurelogging">turn on storage account logging</a> prior to running a job, analyze the logs to understand if/when throttling occurred, and adjust the parameter values accordingly.</p>
<blockquote>
<p><strong>Note</strong>: We are currently working on ways for a cluster to self-tune its throughput rate to avoid throttling and maximize bandwidth utilization.</p>
</blockquote>
<p>* The number of nodes required to trigger throttling by Windows Azure Storage depends on whether geo-replication is enabled for the storage account (because bandwidth allocation is different for each case). If geo-replication is enabled, clusters with more than 7 nodes may encounter throttling. If geo-replication is not enabled, clusters with more than 10 nodes may encounter throttling.</p>
<h1>What is throttling?</h1>
<p>Limits are placed on the bandwidth allocated to Windows Azure Storage accounts to guarantee high availability for all customers. Limiting bandwidth is done by rejecting requests to a storage account (HTTP response 500 or 503) when the request rate exceeds the allocated bandwidth. Windows Azure Storage imposes the following bandwidth limits on a single storage account:</p>
<ul>
<li>Bandwidth for a Geo Redundant storage account (geo-replication on)</li>
<ul>
<li>Ingress - up to 5 gigabits per second</li>
<li>Egress - up to 10 gigabits per second</li>
</ul>
<li>Bandwidth for a Locally Redundant storage account (geo-replication off)</li>
<ul>
<li>Ingress - up to 10 gigabits per second</li>
<li>Egress - up to 15 gigabits per second</li>
</ul>
</ul>
<p>Note that these limits are subject to change. For more information, see <a href="https://blogs.msdn.com/b/windowsazure/archive/2012/11/02/windows-azure-s-flat-network-storage-and-2012-scalability-targets.aspx">Windows Azure&rsquo;s Flat Network Storage and 2012 Scalability Targets</a>. For information about enabling or disabling geo-replication for a storage account, see <a href="https://www.windowsazure.com/en-us/manage/services/storage/how-to-manage-a-storage-account/#georeplication">How to manage storage accounts</a>.</p>
<h1>When will my cluster be throttled?</h1>
<p>An HDInsight cluster will be throttled if/when its throughput rates to Windows Azure Storage exceed those stated above. Throughput, in turn, is dependent on the nature of the job being run. Perhaps the best way to understand in advance if a job will encounter throttling is by comparing it to a well-known workload, the Terasort benchmark. With the <span style="font-family: Courier New;">fs.azure.selfthrottling.read.factor</span> and <span style="font-family: Courier New;">fs.azure.selftthrottling.write.factor</span>&nbsp; parameters each set to 1 (i.e. no self-throttling), HDInsight clusters generally encounter throttling during the Teragen and Teravalidate phases of the Terasort workload* under the following conditions:</p>
<ul>
<li>Geo-replication for the storage account is on and the cluster has more than 15 nodes, or</li>
<li>Geo-replication for the storage account is off and the cluster has more than 31 nodes.</li>
</ul>
<p>These numbers are for reference only. A cluster will only encounter throttling if the job that it is running produces throughput in excess of that allocated for the storage account.</p>
<p>* Run with 4 map slots and 2 reduce slots.</p>
<h1>How do I know my cluster is being throttled?</h1>
<p>Initial indications that a cluster workload is being throttled by Windows Azure Storage may include the following:</p>
<ul>
<li>Longer-than-expected job completion times</li>
<li>A high number of task failures</li>
<li>Job failures (in rare cases). If this occurs, task-attempt error messages will be of the form &ldquo;java.io.IOException &hellip; caused by com.microsoft.windowsazure.services.core.storage.StorageException: The server encountered an unknown failure: The server is busy.&rdquo;</li>
</ul>
<p>While the above are <em>indications</em> that your cluster is being throttled, the best way to understand if your workload is being throttled is by inspecting responses returned by Windows Azure Storage. Responses with response code (http status code) of 500 or 503 indicate that a request has been throttled. One way to collect WA Storage responses is to turn on storage logging (<a href="https://www.windowsazure.com/en-us/manage/services/storage/how-to-monitor-a-storage-account/#configurelogging">https://www.windowsazure.com/en-us/manage/services/storage/how-to-monitor-a-storage-account/#configurelogging</a>).</p>
<h1>How can throttling be avoided?</h1>
<p>If you have a workload that encounters throttling, there are three ways avoid it:</p>
<ol>
<li>Reduce your cluster size</li>
<li>Adjust the settings that control the cluster&rsquo;s self-throttling mechanism</li>
<li>Request an increase in bandwidth allocated for your storage account.</li>
</ol>
<p>The sections below go into more detail.</p>
<h2>Reduce your cluster size</h2>
<p>The first question to answer in avoiding throttling by Windows Azure Storage is this: Do I need all the CPUs in my cluster? In many cases, the answer here might be yes (e.g. the <a href="https://hadoop.apache.org/docs/current/api/org/apache/hadoop/examples/terasort/package-summary.html">Terasort benchmark</a>), in which case you can skip this section. However, some workloads that are truly I/O dominant may not require the CPUs available in a large cluster. By reducing the number of nodes in your cluster, you can reduce the load on storage and (potentially) avoid throttling (in addition to saving money!).</p>
<h2>Adjust settings that control self-throttling</h2>
<p>The <span style="font-family: Courier New;">fs.azure.selfthrottling.read.factor</span> and <span style="font-family: Courier New;">fs.azure.selftthrottling.write.factor</span> settings control the rate at which an HDInsight cluster reads and writes to Windows Azure Storage. Values for these settings must be in the range (0, 1], where 1 corresponds to no self-throttling, 0.5 corresponds to roughly 1/2 the unrestricted throughput rate, and so on. Default values for these settings are determined at cluster creation time according to the following formulas (n = number of nodes in cluster):</p>
<blockquote>
<p><span style="font-family: courier new;">fs.azure.selfthrottling.read/write.factor</span> = 1, n &lt;= 7</p>
<p><span style="font-family: courier new;">fs.azure.selfthrottling.read/write.factor</span> = 32/(5n), n &gt; 7</p>
</blockquote>
<p>The formula for n &gt; 7 is conservative, based on the &ldquo;worst-case&rdquo; scenario (for a storage account with geo-replication enabled) in which the throughput capacity for each node in the cluster is maximized. In practice, this is rare. You can override the default values for these settings at job submission time. Depending on your workload, you may find that increasing the value for either or both of these settings when you submit a job improves job performance. However, increasing the default value by too much may result in throttling by Windows Azure Storage.</p>
<h3>How do high latencies affect the self-throttling mechanism?</h3>
<p>One of the assumptions built into the self-throttling mechanism is that end-to-end request latencies are low (in the 500ms to 1000ms range). If this assumption does not apply, bandwidth utilization may be low and/or jobs may take longer-than-expected to complete. In this case, increasing the values for <span style="font-family: courier new;">fs.azure.selfthrottling.read.factor</span> and <span style="font-family: courier new;">fs.azure.selfthrottling.write.factor</span> (within the range of (0, 1]) may improve performance.</p>
<p>That&rsquo;s it for today. I&rsquo;d be interested in feedback on this feature, so please use the comments below. And, as I mentioned earlier, we are currently working on ways for a cluster to self-tune its throughput rate to avoid throttling and maximize bandwidth utilization without the need for any manual intervention.</p>
<p>Thanks.</p>
<p>-Brian</p>]]></content:encoded>
    </item>
    <item>
      <title>Insights on HDInsight</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/insights-on-hdinsight</link>
      <pubDate>Mon, 25 Nov 2013 20:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2013/11/25/insights-on-hdinsight/</guid>
      <description><![CDATA[I think it&rsquo;s about time I dust off this blog and realign it with my current focus: HDInsight....]]></description>
      <content:encoded><![CDATA[<p>I think it&rsquo;s about time I dust off this blog and realign it with my current focus: <a href="https://www.windowsazure.com/en-us/documentation/services/hdinsight/">HDInsight</a>. I&rsquo;ve been heads-down since February (when I joined the HDInsight team) learning about &ldquo;big data&rdquo; and Hadoop. I haven&rsquo;t had much time for writing, but I&rsquo;m hoping to change that. I&rsquo;ve learned quite a bit in the last few months, and I find that writing is the best way to solidify my learning (not to mention share what I&rsquo;ve learned). If you have topics you&rsquo;d like to see covered, let me know in the comments or on Twitter (<a href="https://twitter.com/brian_swan">@brian_swan</a>) &ndash; I do what I can to cover them.</p>
<p>If you have PHP-related questions (the topic of the vast majority of the blog to date), feel free to ask them. I&rsquo;ll do the best I can to answer them, but as I mentioned earlier, my recent focus has been HDInsight for the past several months.</p>
<p>Thanks.</p>
<p>-Brian&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Azure Real World: Managing and Monitoring Drupal Sites on Windows Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/azure-real-world-managing-and-monitoring-drupal-sites-on-windows-azure</link>
      <pubDate>Tue, 17 Apr 2012 08:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2012/04/17/azure-real-world-managing-and-monitoring-drupal-sites-on-windows-azure/</guid>
      <description><![CDATA[A few weeks ago, I co-authored an article (with my colleague Rama Ramani) about how the Screen...]]></description>
      <content:encoded><![CDATA[<p>A few weeks ago, I co-authored an article (with my colleague <a href="https://twitter.com/#!/rrsubr">Rama Ramani</a>) about how the Screen Actors Guild Awards website migrated its Drupal deployment from LAMP to Windows Azure: <a href="https://go.microsoft.com/fwlink/?LinkId=247931">Azure Real World: Migrating a Drupal Site from LAMP to Windows Azure</a>. Since then, Rama and another colleague, <a href="https://twitter.com/#!/jason_roth_msft">Jason Roth</a>, have been working on writing up how the SAG Awards website was managed and monitored in Windows Azure. The article below is the fruit of their work&hellip;a very interesting/educational read.</p>
<h2><a name="_Toc321991535"></a>Overview</h2>
<p>Drupal is an open source content management system that runs on PHP. Windows Azure offers a flexible platform for hosting, managing, and scaling Drupal deployments. This paper focuses on an approach to host Drupal sites on Windows Azure, based on learning from a BPD Customer Programs Design Win engagement with the <a href="https://www.sagawards.org/">Screen Actors Guild Awards Drupal website</a>. This paper covers guidelines and best practices for managing an existing Drupal web site in Windows Azure. For more information on how to migrate Drupal applications to Windows Azure, see <a href="https://go.microsoft.com/fwlink/?LinkId=247931">Azure Real World: Migrating a Drupal Site from LAMP to Windows Azure</a>.</p>
<p>The target audience for this paper is Drupal administrators who have some exposure to Windows Azure. More detailed pointers to Windows Azure content is provided throughout the paper as links.</p>
<h2><a name="_Toc321991536"></a>Drupal Application Architecture on Windows Azure</h2>
<p>Before reviewing the management and monitoring guidelines, it is important to understand the architecture of a typical Drupal deployment on Windows Azure. First, the following diagram displays the basic architecture of Drupal running on Windows and IIS7.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/3034.DrupalArchitectureOnWinServer.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78/3034.DrupalArchitectureOnWinServer.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/3034.DrupalArchitectureOnWinServer.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78/3034.DrupalArchitectureOnWinServer.jpg" alt="" border="0" /></a></p>
<p>In the Windows Server scenario, you could have one or more machines hosting the web site in a farm. Those machines would either persist the site content to the file system or point to other network shares.</p>
<p>For Windows Azure, the basic architecture is the same, but there are some differences. In Windows Azure the site is hosted on a web role. A web role instance is hosted on a Windows Server 2008 virtual machine within the Windows Azure datacenter. Like the web farm, you can have multiple instances running the site. But there is no persistence guarantee for the data on the file system. Because of this, much of the shared site content should be stored in Windows Azure Blob storage. This allows them to be highly available and durable. Usually, a large portion of the site caters to static content which lends well to caching. And caching can be applied in a set of places &ndash; browser level caching, CDN to cache content in the edge closer to the browser clients, caching in Azure to reduce the load on backend, etc. Finally, the database can be located in SQL Azure. The following diagram shows these differences.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/7080.DrupalArchitectureOnAzure.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78/7080.DrupalArchitectureOnAzure.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/7080.DrupalArchitectureOnAzure.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78/7080.DrupalArchitectureOnAzure.jpg" alt="" width="560" height="378" border="0" /></a></p>
<p>For monitoring and management, we will look at Drupal on Windows Azure from three perspectives:</p>
<ul>
<li><strong>Availability</strong>: Ensure the web site does not go down and that all tiers are setup correctly. Apply best practices to ensure that the site is deployed across data centers and perform backup operations regularly.</li>
</ul>
<ul>
<li><strong>Scalability</strong>: Correctly handle changes in user load. Understand the performance characteristics of the site.</li>
</ul>
<ul>
<li><strong>Manageability</strong>: Correctly handle updates. Make code and site changes with no downtime when possible.</li>
</ul>
<p>Although some management tasks span one or more of these categories, it is still helpful to discuss Drupal management on Windows Azure within these focus areas.</p>
<h2><a name="_Toc321991537"></a>Availability</h2>
<p>One main goal is that the Drupal site remains running and accessible to all end-users. This involves monitoring both the site and the SQL Azure database that the site depends on. In this section, we will briefly look at monitoring and backup tasks. Other crossover areas that affect availability will be discussed in the next section on scalability.</p>
<h3><a name="_Toc321991538"></a>Monitoring</h3>
<p>With any application, monitoring plays an important role with managing availability. Monitoring data can reveal whether users are successfully using the site or whether computing resources are meeting the demand. Other data reveals error counts and possibly points to issues in a specific tier of the deployment.</p>
<p>There are several monitoring tools that can be used.</p>
<ul>
<li>The <a href="https://msdn.microsoft.com/en-us/library/windowsazure/gg441576.aspx">Windows Azure Management Portal</a>.</li>
</ul>
<ul>
<li>Windows Azure diagnostic data.</li>
</ul>
<ul>
<li>Custom monitoring scripts.</li>
</ul>
<ul>
<li>System Center Operations Manager.</li>
</ul>
<ul>
<li>Third party tools such as <a href="https://www.cerebrata.com/Products/AzureDiagnosticsManager/Default.aspx">Azure Diagnostics Manager</a> and <a href="https://azurestorageexplorer.codeplex.com/">Azure Storage Explorer</a>.</li>
</ul>
<p>The Windows Azure Management Portal can be used to ensure that your deployments are successful and running. You can also use the portal to manage features such as Remote Desktop so that you can directly connect to machines that are running the Drupal site.</p>
<p>Windows Azure diagnostics allows you to collect performance counters and logs off of the web role instances that are running the Drupal site. Although there are many options for configuring diagnostics in Azure, the best solution with Drupal is to use a diagnostics configuration file. The following configuration file demonstrates some basic performance counters that can monitor resources such as memory, processor utilization, and network bandwidth.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">DiagnosticMonitorConfiguration</span> <span style="color: #ff0000;">xmlns</span><span style="color: #0000ff;">="https://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                                <span style="color: #ff0000;">configurationChangePollInterval</span><span style="color: #0000ff;">="PT1M"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                                <span style="color: #ff0000;">overallQuotaInMB</span><span style="color: #0000ff;">="4096"</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">  <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">DiagnosticInfrastructureLogs</span> <span style="color: #ff0000;">bufferQuotaInMB</span><span style="color: #0000ff;">="10"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                                <span style="color: #ff0000;">scheduledTransferLogLevelFilter</span><span style="color: #0000ff;">="Error"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                                <span style="color: #ff0000;">scheduledTransferPeriod</span><span style="color: #0000ff;">="PT1M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">  <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">Logs</span> <span style="color: #ff0000;">bufferQuotaInMB</span><span style="color: #0000ff;">="0"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">        <span style="color: #ff0000;">scheduledTransferLogLevelFilter</span><span style="color: #0000ff;">="Verbose"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        <span style="color: #ff0000;">scheduledTransferPeriod</span><span style="color: #0000ff;">="PT1M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">  <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">Directories</span> <span style="color: #ff0000;">bufferQuotaInMB</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">scheduledTransferPeriod</span><span style="color: #0000ff;">="PT5M"</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #008000;">&lt;!-- These three elements specify the special directories that are set up for the log types --&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">CrashDumps</span> <span style="color: #ff0000;">container</span><span style="color: #0000ff;">="wad-crash-dumps"</span> <span style="color: #ff0000;">directoryQuotaInMB</span><span style="color: #0000ff;">="256"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">FailedRequestLogs</span> <span style="color: #ff0000;">container</span><span style="color: #0000ff;">="wad-frq"</span> <span style="color: #ff0000;">directoryQuotaInMB</span><span style="color: #0000ff;">="256"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">IISLogs</span> <span style="color: #ff0000;">container</span><span style="color: #0000ff;">="wad-iis"</span> <span style="color: #ff0000;">directoryQuotaInMB</span><span style="color: #0000ff;">="256"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">  <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">Directories</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">  <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounters</span> <span style="color: #ff0000;">bufferQuotaInMB</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">scheduledTransferPeriod</span><span style="color: #0000ff;">="PT1M"</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #008000;">&lt;!-- The counter specifier is in the same format as the imperative diagnostics configuration API --&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounterConfiguration</span> <span style="color: #ff0000;">counterSpecifier</span><span style="color: #0000ff;">="\Memory\Available MBytes"</span> <span style="color: #ff0000;">sampleRate</span><span style="color: #0000ff;">="PT10M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounterConfiguration</span> <span style="color: #ff0000;">counterSpecifier</span><span style="color: #0000ff;">="\Network Interface(*)\Bytes Total/sec"</span> <span style="color: #ff0000;">sampleRate</span><span style="color: #0000ff;">="PT10M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounterConfiguration</span> <span style="color: #ff0000;">counterSpecifier</span><span style="color: #0000ff;">="\Processor(*)\% Processor Time"</span> <span style="color: #ff0000;">sampleRate</span><span style="color: #0000ff;">="PT10M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounterConfiguration</span> <span style="color: #ff0000;">counterSpecifier</span><span style="color: #0000ff;">="\System\Processor Queue Length"</span> <span style="color: #ff0000;">sampleRate</span><span style="color: #0000ff;">="PT10M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounterConfiguration</span> <span style="color: #ff0000;">counterSpecifier</span><span style="color: #0000ff;">="\Web Service(_Total)\Current Connections"</span> <span style="color: #ff0000;">sampleRate</span><span style="color: #0000ff;">="PT10M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounterConfiguration</span> <span style="color: #ff0000;">counterSpecifier</span><span style="color: #0000ff;">="\Web Service(_Total)\Bytes Total/sec"</span> <span style="color: #ff0000;">sampleRate</span><span style="color: #0000ff;">="PT10M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounterConfiguration</span> <span style="color: #ff0000;">counterSpecifier</span><span style="color: #0000ff;">="\Web Service(_Total)\Connection Attempts/sec"</span> <span style="color: #ff0000;">sampleRate</span><span style="color: #0000ff;">="PT10M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounterConfiguration</span> <span style="color: #ff0000;">counterSpecifier</span><span style="color: #0000ff;">="\Web Service(_Total)\Get Requests/sec"</span> <span style="color: #ff0000;">sampleRate</span><span style="color: #0000ff;">="PT10M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">PerformanceCounterConfiguration</span> <span style="color: #ff0000;">counterSpecifier</span><span style="color: #0000ff;">="\Web Service(_Total)\Files Sent/sec"</span> <span style="color: #ff0000;">sampleRate</span><span style="color: #0000ff;">="PT10M"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">  <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">PerformanceCounters</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">  <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">WindowsEventLog</span> <span style="color: #ff0000;">bufferQuotaInMB</span><span style="color: #0000ff;">="0"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                   <span style="color: #ff0000;">scheduledTransferLogLevelFilter</span><span style="color: #0000ff;">="Verbose"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                   <span style="color: #ff0000;">scheduledTransferPeriod</span><span style="color: #0000ff;">="PT5M"</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #008000;">&lt;!-- The event log name is in the same format as the imperative diagnostics configuration API --&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">DataSource</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="System!*"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">  <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">WindowsEventLog</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">DiagnosticMonitorConfiguration</span><span style="color: #0000ff;">&gt;</span></pre>
<!--CRLF--></div>
</div>
<p>For more information about setting up diagnostic configuration files, see <a href="https://msdn.microsoft.com/en-us/library/windowsazure/hh411551.aspx">How to Use the Windows Azure Diagnostics Configuration File</a>. This information is stored locally on each role instance and then transferred to Windows Azure storage per a defined schedule or on-demand. See <a href="https://msdn.microsoft.com/en-us/library/windowsazure/hh411544.aspx">Getting Started with Storing and Viewing Diagnostic Data in Windows Azure Storage</a>. Various monitoring tools, such as <a href="https://www.cerebrata.com/Products/AzureDiagnosticsManager/Default.aspx">Azure Diagnostics Manager</a>, help you to more easily analyze diagnostic data.</p>
<p>Monitoring the performance of the machines hosting the Drupal site is only part of the story. In order to plan properly for both availability and scalability, you should also monitor site traffic, including user load patterns and trends. Standard and custom diagnostic data could contribute to this, but there are also third-party tools that monitor web traffic. For example, if you know that spikes occur in your application during certain days of the week, you could make changes to the application to handle the additional load and increase the availability of the Drupal solution.</p>
<h3><a name="_Toc321991539"></a>Backup Tasks</h3>
<p>To remain highly available, it is important to backup your data as a defense-in-depth strategy for disaster recovery. This is true even though SQL Azure and Windows Azure Storage both implement redundancy to prevent data loss. One obvious reason is that these services cannot prevent administrator error if data is accidentally deleted or incorrectly changed.</p>
<p>SQL Azure does not currently have a formal backup technology, although there are many third-party tools and solutions that provide this capability. Usually the database size for a Drupal site is relatively small. In the case of SAG Awards, it was only ~100-150 MB. So performing an entire backup using any strategy was relatively fast. If your database is much larger, you might have to test various backup strategies to find the one that works best.</p>
<p>Apart from third-party SQL Azure backup solutions, there are several strategies for obtaining a backup of your data:</p>
<p>&middot; <a href="https://go.microsoft.com/fwlink/?LinkId=247931">Use the Drush tool and the portabledb-export command</a>.</p>
<p>&middot; Periodically <a href="https://msdn.microsoft.com/en-us/library/windowsazure/ff951624.aspx">copy the database using the CREATE DATABASE Transact-SQL command</a>.</p>
<p>&middot; Use Data-tier applications (DAC) to assist with <a href="https://msdn.microsoft.com/en-us/library/windowsazure/hh335292.aspx">backup </a>and <a href="https://msdn.microsoft.com/en-us/library/windowsazure/hh335291.aspx">restore</a> of the database.</p>
<p>SQL Azure backup and data security techniques are described in more detail in the topic, <a href="https://msdn.microsoft.com/en-us/library/hh852669.aspx">Business Continuity in SQL Azure</a>.</p>
<p>Note that bandwidth costs accrue with any backup operation that transfers information outside of the Windows Azure datacenter. To reduce costs, you can copy the database to a database within the same datacenter. Or you can export the data-tier applications to blob storage in the same datacenter.</p>
<p>Another potential backup task involves the files in Blob storage. If you keep a master copy of all media files uploaded to Blob storage, then you already have an on-premises backup of those files. However, if multiple administrators are loading files into Blob storage for use on the Drupal site, it is a good idea to enumerate the storage account and to download any new files to a central location. The following PHP script demonstrates how this can be done by backing up all files in Blob storage after a specified modification date.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&lt;?php</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">/**</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">* Backup the blob storage to a local folder </span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">* </span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">* PHP version 5.3</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">* </span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">* @category Blob Backup</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">* @package Windows Azure</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">* @author Bibin Kurian</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">* @copyright 2011 Microsoft Corp. (https://www.microsoft.com)</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">* @license New BSD license, (https://www.opensource.org/licenses/bsd-license.php)</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">* @version SVN: 1.0</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">* @link</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">* </span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">*/</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">/** Microsoft_WindowsAzure_Storage_Blob */</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">require_once</span> <span style="color: #006080;">'Microsoft/WindowsAzure/Storage/Blob.php'</span>;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">//Windows Azure BLOB storage account name</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">define(<span style="color: #006080;">"AZURE_STORAGE_ACCOUNT"</span>, <span style="color: #006080;">"YOUR_ACCOUNTNAME"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">//Windows Azure BLOB storage container name</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">define(<span style="color: #006080;">"AZURE_STORAGE_CONTAINER"</span>, <span style="color: #006080;">"YOUR_STORAGECONTAINERNAME"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">//Windows Azure BLOB storage secret key</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">define(</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #006080;">"AZURE_STORAGE_KEY"</span>, </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #006080;">"YOUR_SECRETKEY"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">//backup folder</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">define(<span style="color: #006080;">"STORAGE_BACKUP_DIR"</span>, <span style="color: #006080;">"YOUR_LOCALDRIVE"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">//backup from date</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">define(<span style="color: #006080;">"DEFAULT_BACKUP_FROM_DATE"</span>, strtotime(<span style="color: #006080;">"Mon, 19 Dec 2011 22:00:00 GMT"</span>));</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">//backup to date</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">define(<span style="color: #006080;">"DEFAULT_BACKUP_TO_DATE"</span>, time());</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">//directory seperator</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">define(<span style="color: #006080;">"DS"</span>, <span style="color: #006080;">"\\");</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">//start backup logic</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">//current datetime to create the backup folder</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$now = date("F j, Y, g.i A");</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">$fullBackupDirPath = STORAGE_BACKUP_DIR . DS . $now . DS. AZURE_STORAGE_CONTAINER;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">mkdir($fullBackupDirPath, 0755, <span style="color: #0000ff;">true</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">//For the directory creations, pointing the current directory to user specified directory</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">chdir($fullBackupDirPath);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #008000;">//BLOB object</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$blobObj = <span style="color: #0000ff;">new</span> Microsoft_WindowsAzure_Storage_Blob(</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #006080;">'blob.core.windows.net'</span>, </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    AZURE_STORAGE_ACCOUNT,</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    AZURE_STORAGE_KEY</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #008000;">//$blobObj-&gt;setProxy(true, 'YOUR_PROXY_IF_NEEDED', 80);</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$blobs = (<span style="color: #0000ff;">array</span>)$blobObj-&gt;listBlobs(AZURE_STORAGE_CONTAINER, <span style="color: #006080;">''</span>, <span style="color: #006080;">''</span>, 35000);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">backupBlobs($blobs, $blobObj);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #0000ff;">function</span> backupBlobs($blobs, $blobObj) {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">foreach</span> ($blobs <span style="color: #0000ff;">as</span> $blob) {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        <span style="color: #0000ff;">if</span> (strtotime($blob-&gt;lastmodified) &gt;= DEFAULT_BACKUP_FROM_DATE &amp;&amp; strtotime($blob-&gt;lastmodified) &lt;= DEFAULT_BACKUP_TO_DATE) {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">            $path = pathinfo($blob-&gt;name);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">            <span style="color: #0000ff;">if</span> ($path[<span style="color: #006080;">'basename'</span>] != <span style="color: #006080;">'$$$.$$$'</span>) {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                $dir = $path[<span style="color: #006080;">'dirname'</span>];</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                $oldDir = getcwd();</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                <span style="color: #0000ff;">if</span> (handleDirectory($dir)) {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                    chdir($dir);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                    $blobObj-&gt;getBlob(</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                        AZURE_STORAGE_CONTAINER,</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                        $blob-&gt;name,</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                        $path[<span style="color: #006080;">'basename'</span>]</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                    );</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                    chdir($oldDir);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">                }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">            }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">        }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">}</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">function</span> handleDirectory($dir) {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #0000ff;">if</span> (!checkDirExists($dir)) {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">        <span style="color: #0000ff;">return</span> mkdir($dir, 0755, <span style="color: #0000ff;">true</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span>;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">}</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #0000ff;">function</span> checkDirExists($dir) {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">if</span>(file_exists($dir) &amp;&amp; is_dir($dir)) {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span>;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span>;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">}</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">?&gt;</pre>
<!--CRLF--></div>
</div>
<p>This script has a dependency on the Windows Azure SDK for PHP. Also note there are several parameters that you must modify such as the storage account, secret, and backup location. As with SQL Azure, bandwidth and transaction charges apply to a backup script like this.</p>
<h2><a name="_Toc321991540"></a>Scalability</h2>
<p>Drupal sites on Windows Azure can scale as load increased through typical strategies of scale-up, scale-out, and caching. The following sections describe the specifics of how these strategies are implemented in Windows Azure.</p>
<p>Typically you make scalability decisions based on monitoring and capacity planning. Monitoring can be done in staging during testing or in production with real-time load. Capacity planning factors in projections for changes in user demand.</p>
<h3><a name="_Toc321991541"></a>Scale Up</h3>
<p>When you configure your web role prior to deployment, you have the option of specifying the Virtual Machine (VM) size, such as <strong>Small </strong>or <strong>ExtraLarge</strong>. Each size tier adds additional memory, processing power, and network bandwidth to each instance of your web role. For cost efficiency and smaller units of scale, you can test your application under expected load to find the smallest virtual machine size that meets your requirements.</p>
<p>The workload usually in most popular Drupal websites can be separated out into a limited set of Drupal admins making content changes and a large user base who perform mostly read-only workload. End users can be allowed to make &lsquo;writes&rsquo;, such as uploading blogs or posting in forums, but those changes are not &lsquo;content changes&rsquo;. Drupal admins are setup to operate without caching so that the writes are made directly to SQL Azure or the corresponding backend database. This workload performs well with <strong>Large</strong> or <strong>ExtraLarge</strong> VM sizes. Also, note that the VM size is closely tied to all hardware resources, so if there are many content-rich pages that are streaming content, then the VM size requirements are higher.</p>
<p>To make changes to the Virtual Machine size setting, you must <a href="https://msdn.microsoft.com/en-us/library/windowsazure/ee814754.aspx">change the vmsize attribute</a> of the WebRole element in the service definition file, ServiceDefinition.csdef. A virtual machine size change requires existing applications to be redeployed.</p>
<h4><a name="_Toc321991542"></a>Scale Out</h4>
<p>In addition to the size of each web role instance, you can increase or decrease the number of instances that are running the Drupal site. This spreads the web requests across more servers, enabling the site to handle more users. To change the number of running instances of your web role, see <a href="https://msdn.microsoft.com/en-us/library/windowsazure/ee871996.aspx">How to Scale Applications by Increasing or Decreasing the Number of Role Instances</a>.</p>
<p>Note that some configuration changes can cause your existing web role instances to recycle. You can choose to handle this situation by applying the configuration change and continue running. This is done by handling the <strong>RoleEnvironment.Changing</strong> event. For more information see, <a href="https://msdn.microsoft.com/en-us/library/gg432963.aspx">How to Use the RoleEnvironment.Changing Event</a>.</p>
<p>A common question for any Windows Azure solution is whether there is some type of built-in automatic scaling. Windows Azure does not provide a service that provides auto-scaling. However, it is possible to create a custom solution that scales Azure services using the <a href="https://msdn.microsoft.com/en-us/library/windowsazure/ee460799.aspx">Service Management API</a>. For an example of this approach, see <a href="https://blogs.msdn.com/b/silverlining/archive/2011/10/05/an-auto-scaling-module-for-php-applications-in-windows-azure.aspx">An Auto-Scaling Module for PHP Applications in Windows Azure</a>.</p>
<h3><a name="_Toc321991543"></a>Caching</h3>
<p>Caching is an important strategy for scaling Drupal applications on Windows Azure. One reason for this is that SQL Azure implements throttling mechanisms to regulate the load on any one database in the cloud. Code that uses SQL Azure should have robust error handling and retry logic to account for this. For more information, see <a href="https://msdn.microsoft.com/en-us/library/windowsazure/ff394106.aspx">Error Messages (SQL Azure Database)</a>. Because of the potential for load-related throttling as well as for general performance improvement, it is strongly recommended to use caching.<ins cite="mailto:Rama%20Ramani" datetime="2012-04-11T11:25"></ins></p>
<p>Although Windows Azure provides a Caching service, this service does not currently have interoperability with PHP. Because of this, the best solution for caching in Drupal is to use a module that uses an open-source caching technology, such as Memcached.</p>
<p>Outside of a specific Drupal module, you can also configure Memcached to work in PHP for Windows Azure. For more information, see <a href="https://blog.maartenballiauw.be/post/2011/10/21/Running-Memcached-on-Windows-Azure-for-PHP.aspx">Running Memcached on Windows Azure for PHP</a>. Here is also an example of how to get Memcached working in Windows Azure using a plugin: <a href="https://www.davidaiken.com/2011/01/11/windows-azure-memcached-plugin/">Windows Azure Memcached plugin</a>.</p>
<p>In a future paper, we hope to cover this architecture in more detail. For now, here are several design and management considerations related to caching.</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="193">
<p>Area</p>
</td>
<td valign="top" width="445">
<p>Consideration</p>
</td>
</tr>
<tr>
<td valign="top" width="193">
<p>Design and Implementation<strong></strong></p>
</td>
<td valign="top" width="445">
<p>For a technology like Memcached, will the cache be collocated (spread across all web role instances)? Or will you attempt to setup a dedicated cache ring with worker roles that only run Memcached?</p>
</td>
</tr>
<tr>
<td valign="top" width="193">
<p>Configuration<strong></strong></p>
</td>
<td valign="top" width="445">
<p>What memory is required and how will items in the cache be invalidated?</p>
</td>
</tr>
<tr>
<td valign="top" width="193">
<p>Performance and Monitoring<strong></strong></p>
</td>
<td valign="top" width="445">
<p>What mechanisms will be used to detect the performance and overall health of the cache?</p>
</td>
</tr>
</tbody>
</table>
<p>For ease of use and cost savings, collocation of the cache across the web role instances of the Drupal site works best. However, this assumes that there is available reserve memory on each instance to apply toward caching. It is possible to increase the virtual machine size setting to increase the amount of available memory on each machine. It is also possible to add additional web role instances to add to the overall memory of the cache while at the same time improving the ability of the web site to respond to load. It is possible to create a dedicated cache cluster in the cloud, but the steps for this are beyond the scope of this <a>paper</a><a name="_msoanchor_1" href="file:///C:/Users/bswan/AppData/Local/Microsoft/Windows/Temporary Internet Files/Content.Outlook/YJHR1A2O/#_msocom_1"></a>[RR1] .</p>
<p>For Windows Azure Blob storage, there is also a caching feature built into the service called the Content Delivery Network (CDN). CDN provides high-bandwidth access to files in Blob storage by caching copies of the files in edge nodes around the world. Even within a single geographic region, you could see performance improvements as there are many more edge nodes than Windows Azure datacenters. For more information, see <a href="https://msdn.microsoft.com/en-us/library/windowsazure/ee795176.aspx">Delivering High-Bandwidth Content with the Windows Azure CDN</a>.</p>
<h2><a name="_Toc321991544"></a>Manageability</h2>
<p>It is important to note that each hosted service has a <strong>Staging </strong>environment and a <strong>Production </strong>environment. This can be used to manage deployments, because you can load and test and application in staging before <a href="https://msdn.microsoft.com/en-us/library/windowsazure/ee517253.aspx">performing a VIP swap with production</a>.</p>
<p>From a manageability standpoint, Drupal has an advantage on Windows Azure in the way that site content is stored. Because the data necessary to serve pages is stored in the database and blob storage, there is no need to redeploy the application to change the content of the site.</p>
<p>Another best practice is to use a separate storage account for diagnostic data than the one that is used for the application itself. This can improve performance and also helps to separate the cost of diagnostic monitoring from the cost of the running application.</p>
<p>As mentioned previously, there are several tools that can assist with managing Windows Azure applications. The following table summarizes a few of these choices.</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="181">
<p>Tool</p>
</td>
<td valign="top" width="457">
<p><strong>Description</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="181">
<p><strong><a href="https://msdn.microsoft.com/en-us/library/windowsazure/gg441576.aspx">Windows Azure Management Portal</a></strong></p>
</td>
<td valign="top" width="457">
<p>The web interface of the Windows Azure management portal shows deployments, instance counts and properties, and supports many different common management and monitoring tasks.</p>
</td>
</tr>
<tr>
<td valign="top" width="181">
<p><a><strong>Azure Diagnostics Manager</strong></a></p>
</td>
<td valign="top" width="457">
<p>A Red Gate Software product that provides advanced monitoring and management of diagnostic data. This tool can be very useful for easily analyzing the performance of the Drupal site to determine appropriate scaling decisions.</p>
</td>
</tr>
<tr>
<td valign="top" width="181">
<p><strong><a href="https://azurestorageexplorer.codeplex.com/">Azure Storage Explorer</a></strong></p>
</td>
<td valign="top" width="457">
<p>A tool created by Neudesic for viewing Windows Azure storage account. This can be useful for viewing both diagnostic data and the files in Blob storage.</p>
</td>
</tr>
</tbody>
</table>
<h2><a name="_Toc321991545"></a>Ad<a name="_Toc321991545"></a>ditional Drupal Resources</h2>
<p>The following list contains additional resources for managing your Drupal deployment on Windows Azure:</p>
<ul>
<li><a href="https://www.microsoft.com/web/drupal/">Install Drupal for Windows</a></li>
<li><a href="https://go.microsoft.com/fwlink/?LinkId=247931">Azure Real World: Migrating a Drupal Site from LAMP to Windows Azure</a></li>
<li><a href="https://drupal.org/node/1167138">Drupal on Windows Azure</a></li>
<li><a href="https://drupal.org/getting-started/7/admin">Getting Started with Drupal 7 Administration</a></li>
<li><ins cite="mailto:Rama%20Ramani" datetime="2012-04-11T11:33"><a href="https://drupal.org/documentation/modules/statistics">Drupal Statistics</a></ins></li>
<li><a title="Windows Azure Traffic Manager (WATM)" href="https://azure.microsoft.com/en-us/documentation/articles/traffic-manager-overview/">Windows Azure Traffic Manager (WATM)</a></li>
<li><a href="https://www.microsoft.com/download/en/details.aspx?id=11324">System Center Operations Manager MP for Azure applications</a></li>
<li><a href="https://www.microsoft.com/download/en/details.aspx?id=28951">System Center Operations Manager MP for SQL Azure</a></li>
</ul>
<p><a href="https://twitter.com/home?status=Azure Real World: Managing and Monitoring Drupal Sites on Windows Azure: https://bit.ly/HOdKqN">Share this on Twitter</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Reflecting on DrupalCon Denver</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/reflecting-on-drupalcon-denver</link>
      <pubDate>Wed, 28 Mar 2012 08:22:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2012/03/28/reflecting-on-drupalcon-denver/</guid>
      <description><![CDATA[I saw a Tweet on Monday that nicely summed up the start to my week:The only thing worse than a...]]></description>
      <content:encoded><![CDATA[<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/1423.drupal-drop_00980FD9.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/1423.drupal_2D00_drop_5F00_00980FD9.jpg"><img style="margin: 0px 10px 16px 25px; float: right; display: inline; background-image: none;" title="drupal drop" border="0" alt="drupal drop" align="right" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4150.drupal-drop_thumb_4E343C59.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4150.drupal_2D00_drop_5F00_thumb_5F00_4E343C59.jpg" width="244" height="184" /></a></p>
<p>I saw a Tweet on Monday that nicely summed up the start to my week:<strong>The only thing worse than a Monday is a Monday after #DrupalCon</strong>. I&rsquo;m not sure I&rsquo;ve quoted it <em>exactly</em>, but I&rsquo;m sure I&rsquo;ve captured the sentiment. My Monday wasn&rsquo;t bad as in 3-day-hangover bad, it was just bad in that it was a let down after the fun and intensity of <a href="https://denver2012.drupal.org/">DrupalCon Denver</a>. I met lots of great people, had many interesting conversations, and learned a ton. Mix in a few parties, and it was an excellent week.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/0434.image_75025299.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/0434.image_5F00_75025299.png"><img style="margin: 0px 25px 0px 0px; float: left; display: inline;" title="image" alt="image" align="left" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4628.image_thumb_14B12C62.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4628.image_5F00_thumb_5F00_14B12C62.png" width="240" height="180" /></a>The highlights for me were <a href="https://twitter.com/#!/alexpilotti">Alessandro Pilotti&rsquo;s</a> pre-conference training: <a href="https://denver2012.drupal.org/content/deploying-drupal-scale-microsoft-platform">Deploying Drupal at Scale on the Microsoft Platform</a>. Alessandro did a live demo of using <a href="https://www.iis.net/download/ApplicationRequestRouting">Application Request Routing</a> and <a href="https://www.iis.net/download/webfarmframework">Web Farm Framwork</a> to very quickly create a Drupal web farm that could be easily scaled out. That he was able to do this in less than an hour (the demo, not the entire training) was impressive (as was the 480 GB SSD, 16 GB RAM laptop he used to simultaneously run 4 Windows VMs!). You can read a summary of the demo and get the detailed training slides <a href="https://blogs.msdn.com/b/brian_swan/archive/2012/03/20/deploying-drupal-at-scale-on-microsoft-platform.aspx">here</a>.</p>
<p>Alessandro followed Monday&rsquo;s training with a <a href="https://denver2012.drupal.org/content/lightning-talk-mobile-essentials-drupal">Lightning talk on Tuesday</a> about using <a href="https://phonegap.com/">PhoneGap</a> to develop mobile applications for any platform, including Windows Phone. After hearing <a href="https://denver2012.drupal.org/keynote/luke-wroblewski">Luke Wroblewski&rsquo;s keynote address on Thursday</a> (he talked about the growth of mobile, the importance of developing for mobile, and the opportunities mobile creates&hellip;nice summary <a href="https://www.ostraining.com/blog/live/mobile-first/">here</a>), I&rsquo;m keen to dig a bit deeper into PhoneGap.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7183.msft-drupal-banner_0D91EFEA.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7183.msft_2D00_drupal_2D00_banner_5F00_0D91EFEA.jpg"><img style="margin: 0px 0px 0px 25px; float: right; display: inline; background-image: none;" title="msft-drupal banner" border="0" alt="msft-drupal banner" align="right" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/0830.msft-drupal-banner_thumb_1444F96D.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/0830.msft_2D00_drupal_2D00_banner_5F00_thumb_5F00_1444F96D.jpg" width="184" height="244" /></a>Training aside, the highlight of the conference for me was meeting people and learning from the conversations I had with them. I still got a lot of &ldquo;So, what is Microsoft doing at DrupalCon?&rdquo; questions that <a href="https://blogs.msdn.com/b/brian_swan/archive/2010/04/26/what-was-microsoft-doing-at-drupalcon.aspx">I got 2 years ago at DrupalCon SF</a>, and it was nice to be able to say what we&rsquo;ve <em>been</em> doing. We&rsquo;ve been working with community members to improve PHP performance on Windows, improve IIS functionality and tooling around PHP, improve the Drupal installation experience on Windows, develop Drupal modules that leverage the Microsoft platform, improve Drush on Windows, and develop free training courses (like Alessandro&rsquo;s). And, this time around, some people even had specific Microsoft-related questions&hellip;</p>
<p>The question I was asked most often was something along the lines of &ldquo;When will you support Drupal/Sharepoint integration?&rdquo; The short answer was, &ldquo;We do now!&rdquo; Sharepoint 2010 provides several APIs &ndash; the tricky part is in <a href="https://msdn.microsoft.com/en-us/library/hh313619.aspx">determining which one to use</a>. Since most people I talked to wanted some way to surface Sharepoint data (from internal-facing Sharepoint deployment) on an public facing Drupal deployment, I&rsquo;m guessing that the <a href="https://msdn.microsoft.com/en-us/library/ee705814.aspx">Sharepoint 2010 Web Services API</a> is going to be the easiest path (I&rsquo;m assuming familiarity with REST). And, another option is the <a href="https://technet.microsoft.com/en-us/library/ff934619.aspx">Content Manageability Interoperability Services (CMIS) connector</a>.</p>
<p>That&rsquo;s it for me. Hopefully, you got a chance to stop by our booth and chat a bit. If you did (and even if you didn&rsquo;t), I&rsquo;d be interested in hearing your thoughts in the comments below.</p>
<p>Thanks.</p>
<p>-Brian</p>
<p><a href="https://twitter.com/home?status=Reflecting on DrupalCon Denver:https://bit.ly/GWFc41">Share this on Twitter</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Deploying Drupal at Scale on Microsoft Platform</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/deploying-drupal-at-scale-on-microsoft-platform</link>
      <pubDate>Tue, 20 Mar 2012 10:52:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2012/03/20/deploying-drupal-at-scale-on-microsoft-platform/</guid>
      <description><![CDATA[I find that every conference I attend is a humbling experience. There are just so many knowledgeable...]]></description>
      <content:encoded><![CDATA[<p>I find that every conference I attend is a humbling experience. There are just so many knowledgeable people that I&rsquo;m constantly reminded of how much I <em>don&rsquo;t </em>know. The pre-conference training at DrupalCon Denver was no exception (and the real conference hadn&rsquo;t even begun!). In the <a href="https://denver2012.drupal.org/content/deploying-drupal-scale-microsoft-platform">Deploying Drupal at Scale on Microsoft Platform</a> training yesterday, <a href="https://twitter.com/#!/alexpilotti">Alessandro Pilotti</a> delivered a densely packed training session that, once again, left me feeling humble. Alessandro&rsquo;s breadth and depth of knowledge about running PHP applications on Windows (and Drupal in particular) is truly impressive.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6840.image_0448F9C9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6840.image_5F00_0448F9C9.png"><img style="border: 0px currentcolor; display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/8182.image_thumb_2604AC8D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/8182.image_5F00_thumb_5F00_2604AC8D.png" width="564" height="209" /></a></p>
<p>As you can see from the training agenda, there is no way I can re-cap the day&rsquo;s work in a single blog post, so I won&rsquo;t try. I will, however, do my best to summarize his final demo of the day: creating a Drupal Web Farm using the <a href="https://www.iis.net/download/webfarmframework">Microsoft Web Farm Framework</a>. What stood out at the end of the demo was the ease and speed with which he had a Drupal Web Farm up and running (almost completely from scratch!). <strong>Alessandro&rsquo;s slides, which are attached to this post</strong>, go into much more detail than I will, so check them out if you want more than an interview.</p>
<blockquote>
<p><strong>Note</strong>: I will capture the high-level steps that Alessandro went through in creating a Drupal Web Farm. I&rsquo;ve selected several slides from his presentation to to this &ndash; all of which show how to use IIS GUI tooling. However, Alessandro made a point of showing how everything he did could also be done from the command line using <a href="https://learn.iis.net/page.aspx/114/getting-started-with-appcmdexe">appcmd.exe</a> and <a href="https://www.iis.net/download/PowerShell">PowerShell commands</a>.</p>
</blockquote>
<p>Alessandro did a live demo of the following scenario: He had 4 Windows Server VM&rsquo;s running on his laptop (480 GB SSD with 16 MB RAM !), which would serve as load balancer (<a href="https://www.iis.net/download/ApplicationRequestRouting">Application Request Routing</a> + <a href="https://www.iis.net/download/webfarmframework">Web Farm Framwork</a>), two web servers (each hosting <a href="https://drupal.org/">Drupal</a>), and database server/file server.</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/3005.image6_1E793D20.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/3005.image6_5F00_1E793D20.png"><img style="display: inline;" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/3302.image6_thumb_24C013AE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/3302.image6_5F00_thumb_5F00_24C013AE.png" width="512" height="386" /></a></p>
</blockquote>
<blockquote>
<p><strong>Note</strong>: For the purposes of the demo, he used one VM for both the database server and file server, but he pointed out that having each on a separate machine (as shown in the diagram) would be the way to go for a production site.</p>
</blockquote>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4382.image9_4B21F6F9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4382.image9_5F00_4B21F6F9.png"><img style="display: inline;" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7610.image9_thumb_4A49910F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7610.image9_5F00_thumb_5F00_4A49910F.png" width="516" height="389" /></a></p>
</blockquote>
<p>Next, he used the <a href="https://www.microsoft.com/web/downloads/platform.aspx">Web Platform Installer</a> to install Drupal&nbsp; and configure IIS on the primary server.</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6471.image15_49712B25.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6471.image15_5F00_49712B25.png"><img style="display: inline;" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/2744.image15_thumb_21CAAEFB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/2744.image15_5F00_thumb_5F00_21CAAEFB.png" width="518" height="388" /></a></p>
</blockquote>
<p>Again using the Web Platform Installer, he then installed Application Request Routing and Web Farm Framework.</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6471.image18_67030624.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6471.image18_5F00_67030624.png"><img style="display: inline;" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/1754.image18_thumb_4A19E14F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/1754.image18_5F00_thumb_5F00_4A19E14F.png" width="518" height="384" /></a></p>
</blockquote>
<p>With ARR and WFF installed, he could create a Web Farm&hellip;</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/0677.image21_49417B65.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/0677.image21_5F00_49417B65.png"><img style="display: inline;" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6545.image21_thumb_445EC7A9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6545.image21_5F00_thumb_5F00_445EC7A9.png" width="513" height="383" /></a></p>
</blockquote>
<p>&hellip;and add a primary host to the farm. (He also added the 2nd web server as a secondary host using the same UI.)</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/7534.image24_55CF2881.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/7534.image24_5F00_55CF2881.png"><img style="display: inline;" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4401.image24_thumb_02E41550.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4401.image24_5F00_thumb_5F00_02E41550.png" width="513" height="385" /></a></p>
</blockquote>
<p>Finally, he provisioned the second server (and could have just as easily done more) using WFF. (Note that WFF uses <a href="https://www.iis.net/download/WebDeploy">Web Deploy</a>. Complete details are in the attached slide deck.)</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/2350.image27_7B58A5E2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/2350.image27_5F00_7B58A5E2.png"><img style="display: inline;" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6076.image27_thumb_0133497C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6076.image27_5F00_thumb_5F00_0133497C.png" width="512" height="384" /></a></p>
</blockquote>
<p>&nbsp;</p>
<p>And, Voila! A scalable Drupal Web Farm. Of course, it wasn&rsquo;t quite as simple as Voila!, but he did manage to go from four &ldquo;blank&rdquo; Windows Server VMs to a running web farm in about 45 minutes&hellip;very impressive IMHO.</p>
<p>Be sure to check out the attached slides from Alessandro&rsquo;s presentation.</p>
<p>Thanks.</p>
<p>-Brian</p>
<p><a href="https://twitter.com/home?status=Deploying Drupal at scale on the Microsoft platform: https://tinyurl.com/74zqw9a">Share this on Twitter</a></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/28/55/40/DrupalCon2012_DrupalOnIIS.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-28-55-40/DrupalCon2012_5F00_DrupalOnIIS.zip">DrupalCon2012_DrupalOnIIS.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Azure Real World: Migrating a Drupal Site from LAMP to Windows Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/azure-real-world-migrating-a-drupal-site-from-lamp-to-windows-azure</link>
      <pubDate>Mon, 19 Mar 2012 06:58:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2012/03/19/azure-real-world-migrating-a-drupal-site-from-lamp-to-windows-azure/</guid>
      <description><![CDATA[Last month, the Interoperability team at Microsoft highlighted work done to move the Screen Actors...]]></description>
      <content:encoded><![CDATA[<p>Last month, the Interoperability team at Microsoft highlighted work done to move the <a href="https://www.sagawards.org/">Screen Actors Guild Awards Drupal website</a> from a Linux-Apache-MySQL-PHP (LAMP) environment to the Windows Azure platform: <a href="https://blogs.msdn.com/b/interoperability/archive/2012/02/24/sag-awards-website-moves-to-windows-azure.aspx">SAG Awards Drupal Website Moves to Windows Azure</a>. The move was the result of collaboration between SAG Awards engineers and engineers from Microsoft&rsquo;s Interoperability Team and Customer Advisory Team (CAT). The move allowed the SAG Awards website to handle a sustained traffic spike during the SAG Awards show in January. Since then, I&rsquo;ve had the opportunity to talk with some of the engineers who helped with the move. In this post I&rsquo;ll describe the challenges and steps taken in moving the SAG Awards website from a LAMP environment to the Windows Azure platform.</p>
<p style="padding-left: 30px;">Note: <a href="https://twitter.com/#!/rrsubr">Rama Ramani</a>, Senior Program Manager on the Customer Advisory Team at Microsoft, &nbsp;was co-author of this post.</p>
<h3>Background</h3>
<p>The <a href="https://www.sag.org/">Screen Actors Guild</a> (SAG) is the United States&rsquo; largest union representing working actors. In January of every year since 1995, SAG has hosted the <a href="https://www.sagawards.org/">Screen Actors Guild Awards</a> (SAG Awards) to honor performers in motion pictures and TV series. In 2011, the SAG Awards Drupal website, deployed on a LAMP stack, was impacted by site outages and slow performance during peak-usage days, with SAG having to consistently upgrade their hardware to meet demand for those days. That upgraded hardware was then not optimally used during the rest of the year. In late 2011, SAG Awards engineers began working with Microsoft engineers to migrate its website to Windows Azure in anticipation of its 2012 show. In January of 2012, the SAG Website had over 350K unique visitors and 1.1M page views, with traffic spiking to over 160K visitors during the show.</p>
<h3>Overview and Challenges</h3>
<p>In many ways, the SAG Awards website was a perfect candidate for Windows Azure. The website has moderate traffic throughout most of the year, but has a sustained traffic spike shortly before, during, and after the awards show in January. The elastic scalability and fast storage services offered by the Azure platform were designed to handle this type of usage.</p>
<p>The main challenge that SAG Awards and Microsoft engineers faced in moving the SAG Awards website to Windows Azure was in architecting for a very high, sustained traffic spike while accommodating the need of SAG Awards administrators to frequently update media files during the awards show. Both intelligent use of Windows Azure Blob Storage and a custom module for invalidating cached pages when content was updated were key to delivering a positive user experience.</p>
<blockquote>
<p><b>Note</b>: In this post I will focus on how the Drupal website was moved to Windows Azure, as well as how content and data were moved to Windows Azure Blob Storage and SQL Azure. I won&rsquo;t cover the details of the caching strategy.</p>
</blockquote>
<p>The process for moving the SAG-Awards website from a LAMP environment to the Windows Azure platform can be broken down into five high-level steps:</p>
<ol>
<li><b>Export data.</b> A custom Drush command (<a href="https://drupal.org/sandbox/damz/1174672">portabledb-export</a>) was used to create a database dump of MySQL data. A .zip archive of media files was created for later use.</li>
<li><b>Install Drupal on Windows.</b> The Drupal files that comprised the installation in the LAMP environment were copied to Windows Server/IIS as an initial step in discovering compatibility issues.</li>
<li><b>Import data to SQL Azure.</b> A custom <a href="https://drush.ws/drush_windows_installer">Drush</a> command (<a href="https://drupal.org/sandbox/damz/1174672">portabledb-import</a>) was used together with the database dump created in step 1 to import data to SQL Azure.</li>
<li><b>Copy media files to Azure Blob Storage.</b> After unpacking the .zip archive in step 1, <a href="https://clumsyleaf.com/products/cloudxplorer">CloudXplorer</a> was used to copy these files to Windows Azure Blob Storage.</li>
<li><b>Package and deploy Drupal.</b> The Azure packaging tool <a href="https://msdn.microsoft.com/en-us/library/windowsazure/gg432988.aspx">cspack</a> was used to package Drupal for deployment. Deployment was done through the <a href="https://windows.azure.com/">Windows Azure Portal</a>.</li>
</ol>
<blockquote>
<p><strong>Note</strong>: The portabledb commands mentioned above are authored and maintained by Damien Tournoud.</p>
</blockquote>
<p>Details for each of these high-level steps are in the sections below.</p>
<h3>Export Data</h3>
<p>Microsoft and SAG engineers began investigating the best way to export MySQL data by looking at Damien Tournoud&rsquo;s <a href="https://drupal.org/sandbox/damz/1174672">portabledb Drush commands</a>. They found that this tool worked perfectly when moving Drupal to Windows and SQL Server, but they needed to make some modifications to the tool for exporting data to SQL Azure. (These modifications have since been incorporated into the <strong>portabledb</strong> commands, which are now available as part of the <a href="https://drupal.org/project/azure">Windows Azure Integration Module</a>.)</p>
<p>The names of media files stored in the <span style="font-family: Courier New;" face="Courier New">file_managed</span> table were of the form <span style="font-family: Courier New;" face="Courier New">public://field/image/file_name.avi</span>. In order for these files to be streamed from Windows Azure Blob Storage (as they would be by the Windows Azure Integration module when deployed in Azure), the file names needed to be modified to this form: <span style="font-family: Courier New;" face="Courier New">azurepublic://field/image/file_name.avi</span>. This was an easy change to make.</p>
<p>Because the SAG Awards website would be retrieving all data from the cloud, Windows Azure Storage connection information needed to be stored in the database. The <strong>portabledb</strong> tool was modified to create a new table, <span style="font-family: Courier New;" face="Courier New">azure_storage</span>, for containing this information.</p>
<p>Finally, to allow all media files to be retrieved from Blob Storage, the <span style="font-family: Courier New;" face="Courier New">file_default_scheme</span> table needed to be updated with the stream wrapper name: <span style="font-family: Courier New;" face="Courier New">azurepublic</span>.</p>
<p>Using the modified <strong>portabledb</strong> tool, the following command produced the database dump:</p>
<blockquote>
<p><span style="font-family: Courier New;" face="Courier New">drush portabledb-export&nbsp; --use-windows-azure-storage=true --windows-azure-stream-wrapper-name=azurepublic --windows-azure-storage-account-name=azure_storage_account_name --windows-azure-storage-account-key=azure_storage_account_key&nbsp; --windows-azure-blob-container-name=azure_blob_container_name --windows-azure-module-path=sites/all/modules --ctools-module-path=sites/all/modules&nbsp; &gt; drupal.dump</span></p>
</blockquote>
<p>Note that the <span style="font-family: Courier New;" face="Courier New">portabledb-export</span> command does not copy media files themselves. Instead, the local media files were compressed in a .zip archive for use in a later step.</p>
<h3>Install Drupal on Windows</h3>
<p>In order to use the <strong>portabledb-import</strong> command (the counter part to the <strong>portabledb-export</strong> command above), a Drupal installation needed to be set up on Windows (with <a href="https://drush.ws/drush_windows_installer">Drush for Windows</a> installed). This was necessary, in part, because connectivity to SQL Azure was to be managed by the Commerce Guys&rsquo; <a href="https://drupal.org/project/sqlsrv">SQL Server/SQL Azure module</a> for Drupal, which relies on the <a href="https://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;id=20098">SQL Server Drivers for PHP</a>, a Windows-only PHP extension. Having a Windows installation of Drupal would also make it possible to package the application for deployment to Windows Azure. For this reason, Microsoft and SAG Awards engineers copied the Drupal files from the LAMP environment to a Windows Server machine. The team incrementally moved the rest of the application to an IIS/SQL Server Express stack before moving the backend to SQL Azure.</p>
<blockquote>
<p><b>Note</b>: The Windows Server machine was actually a virtual machine running in a Windows Azure Web Role in the same data center as SQL Azure. The Web Role was configured to allow RDP connections, which the team used to install and configure the SAG website installation. This was done to avoid timeouts that occurred when attempting to upload data from an on-premises machine to SQL Azure.</p>
</blockquote>
<p>There were, however, some customizations made to the Drupal installation before running the <strong>portabledb-import</strong> command. Specifically,</p>
<ul>
<li>The <a href="https://drupal.org/project/sqlsrv">SQL Server/SQL Azure module for Drupal</a> was installed and enabled.</li>
<li>The <a href="https://drupal.org/project/memcache">memcache module for Drupal</a> was installed and enabled.</li>
<li>The <a href="https://drupal.org/project/azure">Windows Azure Integration module for Drupal</a> was installed and enabled. Note that this module has a dependency on the <a href="https://drupal.org/project/ctools">CTools module</a>. It also requires <a href="https://github.com/damz/phpazure-experimental">Damien Tournoud&rsquo;s branch of the Windows Azure SDK for PHP</a>, which must be unpacked and put into a folder called <strong>phpazure</strong> in the module&rsquo;s main directory. (As of this writing, Damien Tournoud&rsquo;s changes have not been merged with the Windows Azure SDK for PHP. However, they may be merged in the future.)</li>
<li>Database connection information in the settings.php file was modified to connect to SQL Azure.</li>
<li>A custom caching module was installed and enabled.</li>
</ul>
<p>Some customizations to PHP were also necessary since this PHP installation would be packaged with the application itself:</p>
<ul>
<li>The <a href="https://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;id=20098">php_pdo_sqlsrv.dll</a> extension was installed and enabled. This extension provided connectivity to SQL Azure.</li>
<li>The <a href="https://us.php.net/manual/en/book.memcache.php">php_memcache.dll</a> extension was installed an enabled. This would be used for caching purposes.</li>
<li>The <a href="https://phpazurecontrib.codeplex.com/">php_azure.dll</a> extension was installed and enabled. This extension allowed configuration information to be retrieved from the Windows Azure service configuration file after the application was deployed. This allowed changes to be made without having to re-package and re-deploy the entire application. For example, database connection information could be retrieved in the<span style="font-family: Courier New;" face="Courier New"> settings.php</span> file like this:</li>
</ul>
<blockquote>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;" id="codeSnippetWrapper">
<div style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;" id="codeSnippet">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$databases[<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'driver'</span>] = <span style="color: #006080;">'sqlsrv'</span>;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$databases[<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'username'</span>] = azure_getconfig(<span style="color: #006080;">'sql_azure_username'</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$databases[<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'password'</span>] = azure_getconfig(<span style="color: #006080;">'sql_azure_password'</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$databases[<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'host'</span>] = azure_getconfig(<span style="color: #006080;">'sql_azure_host'</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$databases[<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'default'</span>][<span style="color: #006080;">'database'</span>] = azure_getconfig(<span style="color: #006080;">'sql_azure_database'</span>);</pre>
<!--CRLF--></div>
</div>
</blockquote>
<p>With Drupal running on Windows, and with the customizations to Drupal and PHP outlined above, the importing of data could begin.</p>
<h3>Import Data to SQL Azure</h3>
<p>There were two phases to importing the SAG Awards website data: importing database data to SQL Azure and copying media files to Windows Azure Blob Storage. As alluded to above, importing data to SQL Azure was done with the <strong>portabledb-import</strong> Drush command. With SQL Azure connection information specified in Drupal&rsquo;s <span style="font-family: Courier New;" face="Courier New">settings.php</span> file, the following command copied data from the <span style="font-family: Courier New;" face="Courier New">drupal.dump</span> file (which was copied to Drupal&rsquo;s root directory on the Windows installation) to SQL Azure:</p>
<blockquote>
<p><span style="font-family: Courier New;" face="Courier New">drush portabledb-import --delete-local-files=false --copy-files-blob-storage=false --use-production-storage=true mysite.dump</span></p>
</blockquote>
<blockquote>
<p><b>Note</b>: The <span style="font-family: Courier New;" face="Courier New">copy-files-blob-storage</span> flag was set to <strong>false</strong> in the command above. While the<span style="font-family: Courier New;" face="Courier New"> portabledb-import</span> command <i>can</i> copy media files to Blob Storage, Microsoft and SAG engineers had some work to do in modifying media file names (discussed in the next section). For this reason, they chose not to use this tool for uploading files to Blob Storage.</p>
</blockquote>
<p>The next step was to create stored procedures on SQL Azure that are designed to handle some SQL that is specific to MySQL. The SQL Server/SQL Azure module for Drupal normally creates these stored procedures when the module is enabled, but since Drupal would be deployed with the module already enabled, these stored procedures needed to be created manually. Engineers executed the stored procedure creation DDL that is defined in the module by accessing SQL Azure through the management portal.</p>
<p>After the import was complete, the Windows installation of the SAG Awards website was now retrieving all database data from SQL Azure. However, recall that the <strong>portabledb-export</strong> command modified the names of media files in the<span style="font-family: Courier New;" face="Courier New"> file_managed</span> table so that the Drupal Azure module would retrieve media files from Blob Storage. The final phase in importing data was to copy media files to Blob Storage.</p>
<blockquote>
<p><b>Note</b>: After this phase was complete, engineers cleared the cache through the Drupal admin panel.</p>
</blockquote>
<h3>Copy Media Files to Blob Storage</h3>
<p>The main challenge in copying media files to Windows Azure Blob Storage was in handling Linux file name conventions that are not supported on Windows. While Linux supports a colon (:) as part of a file name, Windows does not. Consequently, when the .zip archive of media files was unpacked on Windows, file names were automatically changed: all colons were converted to underscores (_). However, colons <i>are</i> supported in Blob Storage as part of blob names. This meant that files could be uploaded to Blob Storage from Windows with underscores in the blob names, but the blob names would have to be modified manually to match the names stored in SQL Azure.</p>
<p>Engineers used <a href="https://www.win-rar.com/website/index.php?id=start&amp;L=0">WinRAR</a> to unpack the .zip archive of media files. WinRAR provided a record of all file names that were changed in the unpacking process. Engineers then used <a href="https://clumsyleaf.com/products/cloudxplorer">CloudXplorer</a> to upload the media files to Blob Storage and to change the modified files names, replacing underscores with colons.</p>
<p>At this point in the migration process, the SAG Awards website was fully functional on Windows and was retrieving all data (database data and media files) from the cloud.</p>
<h3>Package and Deploy Drupal</h3>
<p>There were two main challenges in packaging the SAG Awards website for deployment to Drupal: packaging a custom installation of PHP and creating the necessary startup tasks.</p>
<p>Because customizations were made to the PHP installation powering Drupal, engineers needed to package their custom PHP installation for deployment to Windows Azure. The other option was to rely on Microsoft&rsquo;s Web Platform Installer to install a &ldquo;vanilla&rdquo; installation of PHP and then write scripts to modify it on start up. Since it is relatively easy to package a custom PHP installation for deployment to Azure, engineers chose to go that route. (For more information, see <a href="https://blogs.msdn.com/b/silverlining/archive/2011/11/23/packaging-a-custom-php-installation-for-windows-azure.aspx">Packaging a Custom PHP Installation for Windows Azure</a>.)</p>
<p>The startup tasks that needed to be performed were the following:</p>
<ul>
<li>Configure IIS to use the custom PHP installation.</li>
<li>Register the Service Runtime COM Wrapper (which played a role in the caching strategy).</li>
<li>Put Drush (which was packaged with the deployment) in the PATH environment variable.</li>
</ul>
<p>The final project structure, prior to packaging, was the following:</p>
<blockquote>
<p>\SAGAwards <br />&nbsp;&nbsp;&nbsp; \WebRole <br />&nbsp;&nbsp;&nbsp; \bin <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \php <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; install-php.cmd <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; register-service-runtime-COM-Wrapper.cmd <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WinRMConfig.cmd <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; startup-tasks-errorlog.txt <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; startup-tasks-log.txt <br />&nbsp;&nbsp;&nbsp; \resources <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \drush <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ServiceRuntimeCOMWrapper <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \WebPICmdLine <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Drupal files and folders)</p>
</blockquote>
<p>Finally, the <a href="https://www.davidaiken.com/2011/01/11/windows-azure-memcached-plugin/">Windows Azure Memcached Plugin</a> was added to the Windows Azure SDK prior to packaging so that <strong>memcache</strong> would run on startup and restart if killed.</p>
<p>The SAG Awards website was then packaged using <a href="https://msdn.microsoft.com/en-us/library/windowsazure/gg432988.aspx">cspack</a> and deployed to Windows Azure through the <a href="https://windows.azure.com/">developer portal</a>.</p>
<h3>Summary</h3>
<p>The work in moving the SAG Awards Drupal website to the Windows Azure platform was an excellent example of Microsoft&rsquo;s commitment to supporting popular OSS applications on the Windows Azure platform. The collaboration between engineers from SAG and from Microsoft&rsquo;s Interoperability and Customer Advisory Teams resulted in a win for SAG (the SAG Awards website was able to handle sustained spikes in traffic that it could not handle previously) and in valuable lessons learned for the Windows Azure team about supporting migration and scalability of OSS applications on the Azure Platform.</p>
<p>-Brian</p>
<p><a href="https://twitter.com/home?status=Azure Real World - Migrating Drupal from LAMP to Windows Azure: https://tinyurl.com/7v27wzh">Share this on Twitter</a></p>]]></content:encoded>
    </item>
    <item>
      <title>What is Microsoft Doing at DrupalCon Denver?</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/what-is-microsoft-doing-at-drupalcon-denver</link>
      <pubDate>Wed, 14 Mar 2012 08:43:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2012/03/14/what-is-microsoft-doing-at-drupalcon-denver/</guid>
      <description><![CDATA[Microsoft will be at DrupalCon Denver next week, and I have the good fortune of being one of the...]]></description>
      <content:encoded><![CDATA[<p>Microsoft will be at <a href="https://denver2012.drupal.org/">DrupalCon Denver</a> next week, and I have the good fortune of being one of the Microsoft representatives that will be attending. <a href="https://denver2012.drupal.org/program">The program</a> looks great &ndash; it&rsquo;s packed with great speakers and sessions, and there are lots of fun events planned. I&rsquo;m excited about going for those reasons, but also because I&rsquo;m curious about how this conference will be different than the last DrupalCon I attended (<a href="https://sf2010.drupal.org/">DrupalCon San Francisco, 2010</a>). At that conference, I was frequently asked &ldquo;<em>What is Microsoft doing here?</em>&rdquo; You can read more about that in the post I wrote after the conference, <a href="https://blogs.msdn.com/b/brian_swan/archive/2010/04/26/what-was-microsoft-doing-at-drupalcon.aspx">What was Microsoft Doing at DrupalCon?</a> (be sure to read the comments), but suffice it to say that I hope the fact that we will be at a Drupal conference (as a <a href="https://association.drupal.org/node/1344">sponsor</a>, no less) isn&rsquo;t as surprising as it was then. And, because of that post, I&rsquo;m going to Denver with great interest in the community reaction to us today. Essentially, I said that our commitment to Drupal would (and should) be judged by our continued involvement with and contributions to the community. Now that two years have passed since my last DrupalCon, I hope that our actions <em>do</em> speak to our continued involvement and contribution.</p>
<p>I am, of course, very eager to hear what folks at the conference have to say, but going in, I feel good about our level of commitment. At DrupalCon 2010 in S.F., we <a href="https://blogs.msdn.com/b/brian_swan/archive/2010/04/19/pdo-support-for-sql-server.aspx">announced the beta release of our PDO driver for SQL Server</a> and our engagement with <a href="https://www.commerceguys.com/">Commerce Guys</a> to build <a href="https://drupal.org/project/sqlsrv">integrated support for SQL Server into Drupal 7</a>. Since then, we have continued to engage the Drupal community by continuing to sponsor and be engaged at subsequent DrupalCons and other Drupal events worldwide, sponsoring and providing guidance for various integrations, tools, training, and much more. I&rsquo;m sure I&rsquo;m not capturing everything in this list, but here are some of the results:&nbsp;&nbsp;&nbsp;</p>
<ul>
<li><a href="https://drush.ws/drush_windows_installer">Drush 5 for Windows</a> (still in beta).</li>
<li><a href="https://www.webnotwar.ca/drupal-ogdi-open-data-goodness/">Open Data Government Initiative (OGDI) integration with Drupal</a>.</li>
<li><a href="https://blogs.msdn.com/b/interoperability/archive/2012/02/24/sag-awards-website-moves-to-windows-azure.aspx">Screen Actors Guild Awards website deployment to Windows Azure</a>. This was no small feat &ndash; look for more detail in a post in the coming weeks.</li>
<li><a href="https://drupal.org/node/1473540">DrupalWinCache</a>. We&rsquo;d like feedback on this module.</li>
<li><em>Deploying Drupal at Scale on Microsoft Platform</em> training. This was first run at <a href="https://2011.badcamp.net/program/training/deploying-drupal-scale-windows-server">BadCAMP</a> and will be run again next week at DrupalCon Denver (details below).</li>
<li><a href="https://drupal.org/project/azure">Windows Azure Integration module</a>, by the <a href="https://www.commerceguys.com/">Commerce Guys</a>.</li>
<li><a href="https://azurephp.interoperabilitybridges.com/articles/how-to-deploy-drupal-to-windows-azure-using-the-drupal-scaffold">A scaffold</a> for deploying Drupal to Windows Azure.</li>
<li><a href="https://www.ie6countdown.com/">We&rsquo;ve pretty much killed IE6</a>. Yeah!</li>
</ul>
<blockquote>
<p><strong>Note</strong>: I need to point out that the results called out above were, in part, due to the ongoing work of many people at Microsoft over the last couple of years.</p>
</blockquote>
<p>What do you think? I&rsquo;d love to hear your thoughts at the conference or in comments below.</p>
<p>OK, so now let&rsquo;s talk about DrupalCon <em>Denver</em>. What are we doing there? At a high-level, I hope we are continuing to collaborate with people and support efforts to broaden opportunities for Drupal deployments. Specifically, here are the Microsoft-related events and people to watch for:</p>
<ul>
<li><span style="text-decoration: underline;">Monday, March 19, 9:00-6:00</span> (pre-conference training): <a href="https://denver2012.drupal.org/content/deploying-drupal-scale-microsoft-platform">Deploying Drupal at Scale on the Microsoft Platform</a>. This training is for anyone &ldquo;who wants to explore the IIS ecosystem and gain knowledge on optimizing Drupal and PHP on Windows&hellip;&rdquo; This training will be run by <a href="https://twitter.com/#!/alexpilotti">Alessandro Pilotti</a>, CEO of <a href="https://www.cloudbasesolutions.com/">Cloudbase Solutions Srl</a>, and will be full of useful technical information. (I&rsquo;ll be there!)</li>
<li><span style="text-decoration: underline;">Tuesday, March 20, 3:45-4:45</span>: <a href="https://denver2012.drupal.org/content/lightning-talk-mobile-essentials-drupal">Lightning Talk: Mobile Essentials for Drupal</a>. Alessandro Pilotti will present <strong>Windows Phone: a Platform for Drupal Mobile Apps</strong>. During this session, Alessandro will demonstrate how to get the best out of Drupal and the next generation of Windows Phone devices, including some practical Javascript debugging tips.</li>
<li><span style="text-decoration: underline;">Throughout the conference</span>:</li>
<ul>
<li><strong>Microsoft booth</strong>. Stop by, say hi, and ask questions. We&rsquo;ll have some goodies as long as they last.</li>
<li><strong>Giveaways</strong>. We&rsquo;ll be giving away three <a href="https://www.lg.com/us/cell-phones/lg-C900-quantum">LG Quantum Windows Phones</a>. One of these will be given away on Tuesday at Alessandro Pilotti&rsquo;s lightning talk (details above), and the other two will be given away on Wednesday and Thursday via Twitter (look for the <em>#windowsphone</em>, <em>#drupal</em>, and <em>#drupalcon</em> hash tags).</li>
</ul>
<li>The folks from Microsoft who will be at the conference (and who will be happy to answer any questions) are Grace Francisco (<a href="https://twitter.com/#!/gracefr">@gracefr</a>), Jerry Nixon (<a href="https://twitter.com/#!/jerrynixon">@jerrynixon</a>), and myself (<a href="https://twitter.com/#!/brian_swan">@brian_swan</a>). You can read Jerry&rsquo;s pre-conference thoughts here: <a href="https://blog.jerrynixon.com/2012/02/drupal-and-microsoft-yes.html">Drupal and Microsoft? Yes!</a></li>
</ul>
<p>Looking forward to it!</p>
<p>-Brian</p>
<p><a href="https://twitter.com/home?status=What is Microsoft doing at DrupalCon Denver?: https://bit.ly/yRmbRl">Share this on Twitter</a></p>]]></content:encoded>
    </item>
    <item>
      <title>What SQL Server 2012 Means for PHP Developers</title>
      <link>https://docs.microsoft.com/archive/blogs/brian_swan/what-sql-server-2012-means-for-php-developers</link>
      <pubDate>Mon, 12 Mar 2012 12:18:00 GMT</pubDate>
      <dc:creator><![CDATA[Brian Swan - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brian_swan/2012/03/12/what-sql-server-2012-means-for-php-developers/</guid>
      <description><![CDATA[Last week, Microsoft held a virtual conference to announce the availability of SQL Server 2012. The...]]></description>
      <content:encoded><![CDATA[<p>Last week, Microsoft held a <a href="https://www.sqlserverlaunch.com/ww/Home">virtual conference</a> to announce the availability of SQL Server 2012. The conference included a number of events (speakers, videos, training activities, etc.) that focused on the <a href="https://msdn.microsoft.com/en-us/library/bb500435(SQL.110).aspx">new functionality available in this release</a>. Now that most of the fanfare has died down a bit, I&rsquo;d like to take a look at what some of that new functionality means for PHP developers. Combined with <a href="https://blogs.msdn.com/b/sqlphp/archive/2012/03/07/microsoft-drivers-3-0-for-php-for-sql-server-released-to-web.aspx">the release of the Microsoft Driver for SQL Server for PHP</a>, I think the SQL Server 2012 release makes some big improvements in developing PHP/SQL Server applications.</p>
<h3>Easier Setup of Your Development Environment</h3>
<p>If you have used SQL Server Express in the past, you may not have been overjoyed at the time it took to download, install, and configure your database server. With the introduction of <a href="https://blogs.msdn.com/b/sqlexpress/archive/2011/07/12/introducing-localdb-a-better-sql-express.aspx">SQL Server Express LocalDB,</a> you can have this done in <strong>less than 5 minutes</strong>. Here&rsquo;s how:</p>
<p>1. <a href="https://www.microsoft.com/download/en/details.aspx?id=29062">Download SQL Server Express LocalDB</a>. Choose either the <span style="font-family: Courier New;" face="Courier New">ENU\x64\SqlLocalDB.MSI</span> or the <span style="font-family: Courier New;" face="Courier New">ENU\x86\SqlLocalDB.MSI</span> depending on your computer architecture.</p>
<p>2. <a href="https://www.microsoft.com/download/en/details.aspx?id=29065">Download the command line Tools</a>. Find &ldquo;<b>Microsoft&reg; SQL Server&reg; 2012 Command Line Utilities</b>&rdquo; and select the download for your computer architecture.</p>
<p>With those two steps complete, you can connect to LocalDB and begin creating databases with the <a href="https://msdn.microsoft.com/en-us/library/ms162773(SQL.110).aspx">sqlcmd utility</a>:</p>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/2742.image_4CD2AA69.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/2742.image_5F00_4CD2AA69.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/4401.image_thumb_336AA72F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/4401.image_5F00_thumb_5F00_336AA72F.png" width="529" height="339" /></a></p>
</blockquote>
<blockquote>
<p>There is also a <a href="https://msdn.microsoft.com/en-us/library/hh212961(SQL.110).aspx">SqlLocalDB utility</a> that lets you create and manage an instance of SQL Server Express LocalDB.</p>
</blockquote>
<p>3. <a href="https://www.microsoft.com/download/en/details.aspx?id=20098">Download the Microsoft Drivers for SQL Server for PHP</a>. Add the driver to your PHP extension directory and enable it in your <span style="font-family: Courier New;" face="Courier New">php.ini</span> file, and you can connect to it like this:</p>
<blockquote>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;" id="codeSnippetWrapper">
<div style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;" id="codeSnippet">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$serverName = <span style="color: #006080;">'(localdb)\v11.0'</span>;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">$connOptions = <span style="color: #0000ff;">array</span>(<span style="color: #006080;">'AttachDBFileName'</span>=&gt;<span style="color: #006080;">'C:\Users\bswan\ExampleDB.mdf'</span>,<span style="color: #006080;">'Database'</span>=&gt;<span style="color: #006080;">'ExampleDB'</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">$conn = sqlsrv_connect($serverName, $connOptions);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #0000ff;">if</span>($conn === <span style="color: #0000ff;">false</span>)      </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">die</span>(print_r(sqlsrv_errors(), <span style="color: #0000ff;">true</span>)); </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #0000ff;">else</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">echo</span> <span style="color: #006080;">"Connected via sqlsrv!&lt;br /&gt;"</span>;</pre>
<!--CRLF--></div>
</div>
</blockquote>
<p>That&rsquo;s it. From zero to writing SQL Server database queries in PHP much faster than before.</p>
<p>Of course, that&rsquo;s not <em>entirely</em> it. There can be some gotchas, and there may be a couple more steps, depending on what you want to do. Here are a few things I ran into when getting set up:</p>
<ul>
<li>If you are installing LocalDB and the command line tools on a machine that has a previous version of SQL Server, you will need to alter your PATH environment variable. You will need to move both the <span style="font-family: Courier New;" face="Courier New">C:\Program Files\Microsoft SQL Server\110\Tools\Binn\</span> and <span style="font-family: Courier New;" face="Courier New">c:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\</span> paths <em>before</em> any other paths to SQL Server Tools (they will likely be at the end of your PATH variable by default &ndash; the order corresponds to installation order). This will make sure that when you use <span style="font-family: Courier New;" face="Courier New">sqlcmd</span>, the right version will be called.</li>
<li>Note that in my PHP code, I&rsquo;m providing an absolute path to the .mdf file. You must provide an absolute path. By default, the <span style="font-family: Courier New;" face="Courier New">sqlcmd</span> utility will create .mdf files in the User directory. However, you can use any .mdf file you might have&hellip;just provide an absolute path to it (and make sure that the <span style="font-family: Courier New;" face="Courier New">sqlcmd</span> utility has access to the directory). Beware that if the .mdf file was created with a previous version of SQL Server, it will be upgraded the first time you connect to it (which will produce a whole host of warnings). After it has been upgraded, everything should work smoothly.</li>
<li>Also note that in my PHP code, I&rsquo;m <a href="https://msdn.microsoft.com/en-us/library/cc296205.aspx">connecting using Windows Authentication</a> (I&rsquo;ve omitted the UID and PWD elements from the connection options array). When using LocalDB, you can only connect with Windows Authentication. And, if you are using IIS, it is the credentials of the application pool for PHP that are used to login. So, since we are talking about a dev environment here, I suggest setting the application pool credentials to an identity that is also a login for the targeted database. I did this by starting IIS Manager, clicking Application Pools, right clicking the DefaultAppPool (PHP is running under this pool in my case), then following these steps:</li>
</ul>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/6866.image_531980F7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/6866.image_5F00_531980F7.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/33/78/metablogapi/1273.image_thumb_40D0BA35.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-33-78-metablogapi/1273.image_5F00_thumb_5F00_40D0BA35.png" width="712" height="417" /></a></p>
</blockquote>
<h3>Friendlier Syntax: OFFSET&hellip;FETCH NEXT</h3>
<p>I&rsquo;ve written <a href="https://blogs.msdn.com/b/brian_swan/archive/tags/paging/">a few articles on strategies for paging data</a> with the SQL Server Driver for PHP, all of which relied on the <a href="https://msdn.microsoft.com/en-us/library/ms186734.aspx">ROW_NUMBER&hellip;OVER</a> syntax or server-side cursors. The ROW_NUMBER&hellip;OVER syntax is cumbersome compared to the MySQL LIMIT&hellip;OFFSET syntax, and server-side cursors are not appropriate for all scenarios. Enter the <a href="https://msdn.microsoft.com/en-us/library/ms188385(SQL.110).aspx">OFFSET&hellip;FETCH NEXT</a> syntax in SQL Server 2012. Now it&rsquo;s easy to get exactly the subset of data you want from a much larger set:</p>
<blockquote>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;" id="codeSnippetWrapper">
<div style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;" id="codeSnippet">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$sql = <span style="color: #006080;">"SELECT Name, ProductNumber </span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">        FROM Production.Product</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        ORDER BY ProductNumber</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">        OFFSET ? ROWS</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        FETCH NEXT ? ROWS ONLY";</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$params = <span style="color: #0000ff;">array</span>((<span style="color: #0000ff;">int</span>) $_GET[<span style="color: #006080;">'low'</span>], (<span style="color: #0000ff;">int</span>) $_GET[<span style="color: #006080;">'high'</span>]);    </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$stmt = sqlsrv_query($conn, $sql, $params);</pre>
<!--CRLF--></div>
</div>
</blockquote>
<p>&nbsp;</p>
<h3>More Flexibility: Client-Side Cursors</h3>
<p>Prior to the release of v3.0 of the PHP driver, the only <a href="https://blogs.msdn.com/b/brian_swan/archive/2010/05/13/understanding-cursor-options-in-the-sql-server-driver-for-php.aspx">options available</a> for moving through a result set were &ldquo;forward only&rdquo; (the default, which forces you to consume rows in order, and you can&rsquo;t move back to previous rows) or to use server-side cursors (which, as mentioned earlier, are not ideal for all scenarios). However, in the 3.0 release, <a href="https://msdn.microsoft.com/en-us/library/hh487160.aspx">client-side cursors are available</a> for getting random access to the rows of a result set. To enable this, set the <span style="font-family: Courier New;" face="Courier New">Scrollable</span> option to <span style="font-family: Courier New;" face="Courier New">buffered</span> on <a href="https://msdn.microsoft.com/en-us/library/cc296184.aspx">sqlsrv_query</a> or <a href="https://msdn.microsoft.com/en-us/library/cc296181.aspx">sqlsrv_prepare</a>:</p>
<blockquote>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;" id="codeSnippetWrapper">
<div style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;" id="codeSnippet">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$sql = <span style="color: #006080;">"SELECT Name, ProductNumber </span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">        FROM Production.Product";</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&nbsp;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">$stmt = sqlsrv_query($conn, $sql, <span style="color: #0000ff;">null</span>, <span style="color: #0000ff;">array</span>(<span style="color: #006080;">"Scrollable"</span>=&gt;<span style="color: #006080;">"buffered"</span>));</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: #0000ff;">if</span>($stmt === <span style="color: #0000ff;">false</span>)</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    <span style="color: #0000ff;">die</span>(print_r(sqlsrv_errors(), <span style="color: #0000ff;">true</span>));</pre>
<!--CRLF--></div>
</div>
</blockquote>
<p>With client-side queries (a.k.a &ldquo;buffered&rdquo; queries) enabled, you can use the <a href="https://msdn.microsoft.com/en-us/library/ee376931.aspx">sqlsrv_num_rows</a> function to get the number of rows, and you can use the following constants with <a href="https://msdn.microsoft.com/en-us/library/cc296187.aspx">sqlsrv_fetch,</a> <a href="https://msdn.microsoft.com/en-us/library/cc296174.aspx">sqlsrv_fetch_array</a>,&nbsp; or <a href="https://msdn.microsoft.com/en-us/library/cc626308.aspx">sqlsrv_fetch_object</a> to randomly access rows:</p>
<ul>
<li>SQLSRV_SCROLL_NEXT</li>
<li>SQLSRV_SCROLL_PRIOR</li>
<li>SQLSRV_SCROLL_FIRST</li>
<li>SQLSRV_SCROLL_LAST</li>
<li>SQLSRV_SCROLL_ABSOLUTE</li>
<li>SQLSRV_SCROLL_RELATIVE</li>
</ul>
<p>Just for fun, here&rsquo;s one way you could use those constants to work backwards through a result set:</p>
<blockquote>
<div style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;" id="codeSnippetWrapper">
<div style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;" id="codeSnippet">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">$num_rows = sqlsrv_num_rows($stmt);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span style="color: #0000ff;">for</span>($i = $num_rows - 1; $i &gt;= 0; $i--)</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">{</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">    $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC, SQLSRV_SCROLL_ABSOLUTE, $i);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: #008000;">// process row here</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">}</pre>
<!--CRLF--></div>
</div>
</blockquote>
<p>Of course, you can also use client-side cursors with the PDO extension. There are plenty of <a href="https://msdn.microsoft.com/en-us/library/hh487158.aspx">examples in the documentation</a>.</p>
<h3>There&rsquo;s More</h3>
<p>The improvements mentioned above are those that I think have the biggest impact for PHP developers now. But there are other things you might be interested in, such as support for <a href="https://msdn.microsoft.com/en-us/library/hh487159.aspx">AlwaysOn Connectivity</a> and for the <a href="https://msdn.microsoft.com/en-us/library/ff628176.aspx">PDO::ATTR_EMULATE_PREPARES constant</a> in the PHP Driver. And, the PHP driver still <a href="https://blogs.msdn.com/b/brian_swan/archive/2010/02/12/getting-started-with-php-and-sql-azure.aspx">provides access to SQL Azure</a>, the <a href="https://blogs.msdn.com/b/brian_swan/archive/2011/11/28/the-sql-server-odbc-driver-for-linux-is-available.aspx">SQL Server ODBC Driver for Linux</a> is in a beta release (which <a href="https://blog.acjacinto.com/2011/11/compiling-php-with-mssql-servers-native.html">some PHP developers are already taking advantage of</a>), and <a href="https://www.hadooponazure.com/">Hadoop for Azure</a> is on its way. The only down note in this release is the the PHP driver does not currently support PHP 5.4, but that&rsquo;s a temporary thing. I know the team is working hard to quickly add that support.</p>
<p>As I mentioned at the beginning, I think the release of SQL Server 2012 takes some big steps toward improving the development experience for PHP developers. Thanks to all the folks who have provided feedback to help get us here&hellip;we&rsquo;ve been listening. I&rsquo;d be very interested to hear if you agree.</p>
<p>Thanks.</p>
<p>-Brian</p>
<p><a href="https://twitter.com/home?status=What SQL Server 2012 means for PHP devs: https://bit.ly/ykkQBq">Share this on Twitter</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>