<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Mostly True</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/mostlytrue/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/mostlytrue/feed.xml</link>
    <description>Technical thoughts and musings on data analysis on Azure and other topics</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:25:08 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>The real confusion bug</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/the-real-confusion-bug</link>
      <pubDate>Sun, 06 Sep 2015 15:38:00 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2015/09/06/the-real-confusion-bug/</guid>
      <description><![CDATA[This is a story of a recent debugging session that ended up with discovering a bug that I just love...]]></description>
      <content:encoded><![CDATA[<p>This is a story of a recent debugging session that ended up with discovering a bug that I just love so much because it's a bug I can explain to my mother (I think, haven't tried - also no offense to my brilliant-pathologist-but-slightly-techphobic mother): the computer got confused because all these teams have such similar names! But before I can get to how that happened, a little background&hellip;</p>
<h1>Background</h1>
<p>In the team I'm on these days, we're tasked with developing and operating end-to-end semi-realistic applications on our Azure platform with an eye to first-hand experiencing any pitfalls/pains/horrors that our customers face and channeling that to improving the platform. Our first marquee application we developed for that was a virtual online sports betting web site (with fake money of course). Our focus was to get it realistic enough that it hits most of the technical aspects we wanted and even convince bored co-workers to spend some time on it to get some real usage, but not spend years polishing every last bit of it. As such, we managed to show a few leagues in soccer and basketball with updated schedule and betting odds by using a few sources like Bing and scraping web sites, with automated web jobs that keep updating our DB as such.</p>
<p>And even though we did coerce some co-workers to use our web site, we knew that to drive realistic loads on it we'll either have to launch enormous viral marketing campaigns or fake the load using bots. For whatever reason we decided on the latter, so we wrote a few bots that incessantly executed end-to-end scenarios against our web site and recorded their happiness/unhappiness with every interaction. And being the ambitious over-achievers that we are, we deployed this identical setup across all our Azure regions with automated pipelines that automatically recorded incidents whenever there was consistent unhappiness anywhere. Then we went on to other projects while periodically checking on those incidents to light fires under the butts of any teams responsible for this unhappiness on our platform.</p>
<h1>The incidents</h1>
<p>So that's the background, which brings us to last week. We'd recently gone through a cleanup and were very proud of ourselves having zero uninvestigated incidents, but we looked one day to find many incidents filed on the same day: in a two-and-a-half hour period on 8/29 across the world one of our bots - the Casual Soccer Browser as we fondly call him - kept failing with timeouts while trying to view the events page for Soccer. This was very strange: all these sites were independent and if there was an issue in Azure that affected all regions we'd have definitely noticed it - people running around with their hair on fire tends to be pretty conspicuous after all. So what was going on?</p>
<h1>The errant query</h1>
<p>Looking a little bit deeper into our logs for a few of those failures, we found that what was causing the page load to be so slow was the database query for fetching the events to show. So I created a graph for how long that query took (we use <a href="https://www.elastic.co/">Elasticsearch and Kibana</a> for that part of our pipeline which gives us the blessed ability to create these ad-hoc visualizations pretty quickly) and the anomaly immediately jumped out - the query was executing blazingly fast until around 11 AM that day, then it started taking around 2 minutes per execution which is crazy, then around 1:30 PM it got back to blazing fast executions like nothing happened. So we have a culprit but are just as puzzled as before: why would this query suddenly slow down like that across the world then get back to normal like this?</p>
<h1>The data dive</h1>
<p>Our main suspicion was a data problem: something strange must have happened in the soccer world around that time. So we started querying our database. We did see some matches that started and ended around that time but it was just a few matches - nothing our SQL Server databases would struggle with. Looking at the code though, I noticed that the query also looked at our Lines table to determine betting odds for any events that were bettable (bettable = we have odds and the game hasn't started yet). The way our site works is that we store the odds for a game as a row in the Lines table, and if we find that the odds have changed, we add a new row and mark the previous row as not current; only showing the current line as the odds for the game when you see it. Typically the odds can change just a few times for any given game (the way we see it) but when I did a join + count for this investigation on the games during this period I found this one game that had 15K lines for it! Definitely suspicious&hellip;</p>
<h1>The log dive</h1>
<p>So we went back to look at our logs for the web jobs that scrape web sites for current odds, I finally found the logs that explain this whole mystery - these two logs that kept repeating every time the job ran:</p>
<pre>Added "HomeTeam Real Madrid, AwayTeam Betis, HomeMoneyLine -1000, AwayMoneyLine 2500 DrawMoneyLine 900, Date 8/29/2015 12:00:00 AM" to "{ Id = 245628, HomeTeam = 38, AwayTeam = 848 }".
Added "HomeTeam Real Sociedad, AwayTeam Real Sporting, HomeMoneyLine -118, AwayMoneyLine 350 DrawMoneyLine 250, Date 8/29/2015 12:00:00 AM" to "{ Id = 245628, HomeTeam = 38, AwayTeam = 848 }".</pre>
<h1>The explanation</h1>
<p>Here is what happened: when we were writing this web site, we had a problem where our source for game schedules would call a team by one name (say Seattle Seahawks) but the source for betting odds would call it something else (say Seahawks). So in the spirit of churning out something realistic-but-quick, we wrote some code that fuzzily matched team names in a way that if they matched perfectly then fine, but if they just matched in parts that would work too. Together with matching game times that worked really well in a way that never bit us, until that day in which these two games were happening at the same time:</p>
<ol>
<li>Real Madrid vs. Real Betis</li>
<li>Real Sociedad vs. Real Sporting de Gij&oacute;n</li>
</ol>
<p>All these Real teams! And to make matters more fun, Real Sporting de Gij&oacute;n is stored in our DB as Sporting de Gij&oacute;n. So our web job while scraping for odds would first come across the odds of the first game and match it perfectly, but then it came across the second game and thought "Real Madrid is probably the same as Real Sociedad since they share part of the name, and Real Sporting de Gij&oacute;n is probably the same as Real Betis, so that must be the odds for Real Madrid vs. Real Betis!" So it kept going like this:</p>
<pre>OK, looks like the odds for this game are A:B, let&rsquo;s store that.
Nope, looks like the odds now are X:Y, let&rsquo;s invalidate the old record and store the new one.
Nope, looks like it&rsquo;s A:B again! Let&rsquo;s invalidate the old records and store the new one.
Whaddya know, it&rsquo;s X:Y again! Let&rsquo;s invalidate the old records and store the new one.</pre>
<p>This led to the explosion of the Lines table and the query for those odds taking forever until mercifully the game started and wasn't bettable anymore and the site returned to normal operation across the world. Mystery solved.</p>
<p><em> TLDR; Two games with royally similar team names happened at the same time, confusing our toy online sports betting web site until the game was over. </em></p>]]></content:encoded>
    </item>
    <item>
      <title>Fight for your right to monkey</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/fight-for-your-right-to-monkey</link>
      <pubDate>Fri, 28 Nov 2014 14:05:00 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2014/11/28/fight-for-your-right-to-monkey/</guid>
      <description><![CDATA[The gentle start to a rant...
In any software system, especially but certainly not just in the...]]></description>
      <content:encoded><![CDATA[<h1>The gentle start to a rant...</h1>
<p>In any software system, especially but certainly not just in the cloud, things can and will go horribly wrong in a variety of ways given enough time/opportunity. Some of those are unanticipated disasters: bugs, floods, hurricanes, etc. But a good number of those are just tradeoffs that are consciously made by the developers of the system in order to make other gains:</p>
<ul>
<li>a NoSQL system that anticipates some data inconsistency or even data loss to gain scale/performance,</li>
<li>a cloud system that periodically reboots your VM's to gain automatic/unmanaged updates and security,</li>
<li>...</li>
</ul>
<p>I'm not a purist, and I appreciate those tradeoffs and have made them myself many times, so I don't think these are necessarily bad or evil; but of course I'm writing this post to complain/rally about something, and it's this: if you have a platform/building block where you've made such a tradeoff and anticipate some way of things going wrong, you better give me a way to induce this failure mode to test the rest of the system with it. In other words: saying "my system occasionally decides to run around the room like a mad man to vent steam and you should design for that" is an appreciated but an almost useless statement if you don't give me a way to induce this running around mode in a controlled environment as I'm designing the room to make sure that when it happens it doesn't set the rest of the room on fire.</p>
<h1>Doing right</h1>
<p>For a decent example of doing this right, look at VM reboots in Microsoft Azure. When you have a Cloud Service in Azure, the system reserves the right to reboot or even reimage any of your role instances (VM's) at any time to deal with hardware failures/updates/etc. Your system should be resilient for that, usually by having redundant instances spread across fault domains. This is well-documented on multiple places, but even more importantly: Azure gives you <a href="http://msdn.microsoft.com/en-us/library/azure/gg441298.aspx">REST API's</a>, <a href="http://msdn.microsoft.com/en-us/library/jj152835.aspx">PowerShell commandlets</a> and Portal UI buttons to reboot, reimage or rebuild any of your role instances which is a great way to test that your application is indeed resilient to this. So you can use/do something like <a href="https://github.com/smarx/WazMonkey">WazMonkey</a> to randomly disturb your staging (or hey, if you're brave enough even your production) environment and make sure you're all good, or you can do more targeted testing to e.g. make sure your startup scripts can survive being interrupted by a reboot without ill effects.</p>
<p>Note: I don't think this example is perfect. Ideally the Azure team would have a standard supported test kit that induces all known failure modes into your application (reboot, reimage with/without data loss, etc.) and stand behind it. But as far as things go, I feel good about putting this as my "good" example.</p>
<h1>You done me wrong</h1>
<p>So what are examples of getting this wrong? Alas, there are too many of those...</p>
<p>Let me pick on the SQL Azure team first (since I worked there so as much to blame as anyone): SQL Azure very much retains the right to drop your connection at any time for a variety of reasons and encourages good client behavior to tolerate this (with the various client SDK's doing a decent job of abstracting this resilience), and yet I don't know of any way to induce such connection drops in a reasonable way.</p>
<p>Another big example is the networking stack: everyone knows that TCP/IP and our networking infrastructure is notoriously noisy and error-prone, and yet it's surprisingly hard to induce all these failures (packet drops, latency, etc.).</p>
<h1>Rallying cry</h1>
<p>For the most part I've achieved my goal with this post, which is to cathartically rant about this so I can steel myself for the next smug "you should've designed for that" or "we don't support that" statement from a platform developer. But other than ranting, a side goal is to get anyone reading this to be less tolerant of such unsupported statements, and start demanding "OK where's my test kit" every time they hear it. If enough of us start demanding this especially from the most basic building blocks in our computer systems, I sincerely believe our systems will be significantly and noticeably more stable. In a way my attitude towards this is an extension of my attitude towards all software I write: I never say I've actually written my software to perform X until I see it performing X in practice, so I can never sincerely say I've designed/written my software to be resilient to failure Y until I see it actually handle Y in practice. So if I can't induce Y, I'll have to let my software just hang out in the wild until Y inevitably happens. Which is a crazy slow way to test software, and unfortunately the way many of us do it today.</p>]]></content:encoded>
    </item>
    <item>
      <title>The ultimate showdown of NoSQL destiny!</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/the-ultimate-showdown-of-nosql-destiny</link>
      <pubDate>Fri, 05 Sep 2014 12:43:00 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2014/09/05/the-ultimate-showdown-of-nosql-destiny/</guid>
      <description><![CDATA[Sharks and bees and... fast Italians?!
If you've been following this blog recently, you'd have...]]></description>
      <content:encoded><![CDATA[<h1>Sharks and bees and... fast Italians?!</h1>
<p>If you've been following this blog recently, you'd have noticed that I'm having a blast trying <a href="http://blogs.msdn.com/b/mostlytrue/archive/2014/07/15/come-in-have-some-blue-coffee.aspx">different</a> data <a href="http://blogs.msdn.com/b/mostlytrue/archive/2014/08/12/more-blue-coffee-presto-on-azure.aspx">products</a> on Azure and playing with them. I recently managed to get <a href="http://spark.apache.org/">Spark</a> / <a href="http://spark.apache.org/sql/">Spark SQL</a> <a href="http://databricks.com/blog/2014/07/01/shark-spark-sql-hive-on-spark-and-the-future-of-sql-on-spark.html"> (Shark's replacement)</a> running on Azure in the same way, but rather than dedicate a post to them, I thought it'd be more fun to pit them all against each other, throwing Hive on HDInsight into the mix, in a friendly competition to analyze some data on my Azure blob storage. So without further ado, I present the ultimate showdown!</p>
<h1>The scenario</h1>
<p>When I thought this up, I didn't want to design or even steal a precise scientific benchmark to execute (like <a href="http://www.tpc.org/tpcds/default.asp">TPC-DS</a> for example), since I wasn't interested in precise performance benchmarking and I wouldn't be able to tune each one sufficiently anyway. (If you want a more scientific benchmark that compares some of the products here, I found this <a href="https://amplab.cs.berkeley.edu/benchmark/">awesome effort</a> to be pretty informative.) Instead I wanted a simple scenario the likes of which I see a lot, but artificial enough that I'd be able to play with it/release the code for it so anyone can replicate it. So I came up with the following: we'll have a simulated Cloud application in which each VM logs operation messages to blob store in a simple comma-separated format. For this toy example, each log is either a) a start of an operation, b) a success or c) a failure. The business questions we want each of our contestants to answer are:</p>
<ol>
<li>How many failures/successes did each VM get?</li>
<li>How long did the average successful operation take on each VM?</li>
</ol>
<p>I came up with these two questions as a good starting set for this experiment because the first one can be answered with a single scan through the data, while the other would require a self-join to correlate the start and finish messages for each operation. Which gives me a good feel for how the different contestants at least handle this first level of complexity.</p>
<h1>The data</h1>
<p>Now that I had a scenario in mind, time to cook up some data! I created a simple Azure Compute service where each instance just churns out as fast as it can log messages to its own CSV log file on my Azure blob container. Each line in that file is of the format "{date},{instance name},{operation id},{message}", where date is in a Hive-friendly format, operation ID is a GUID and message is a free-form string so I can throw in a little string manipulation later.</p>
<p>I also cooked up the data so that every tenth role instance (0, 10, 20) would have a higher random operation failure rate, and every seventh instance (0, 7, 14, 21, 28) would have a higher operation duration. This way I can double-check myself and the contestants later to see if we can catch these anomalies.</p>
<p>With that in hand, I deployed it to Azure with 30 (small) instances. They were churning out data pretty fast so I shut it down after about 10 minutes when I had 35.1 GB of data to chew on: this seemed like enough data to make a decent first cut, but not so much that I'd have to worry about sharding across storage accounts to start with.</p>
<p>(Note: all the code used for this experiment is in the public github repo <a href="https://github.com/mooso/nosqlloggingbenchmark">here</a>.)</p>
<h1>Enter our first contestant: Hive/HDInsight</h1>
<p>So let's start the showdown with Hive/HDInsight: our supported and longest standing NoSQL product in this arena. I spun up an 8-node HDInsight cluster backed by a SQL Azure Hive metastore (so I can use it later with the other contestants), created an external Hive table pointing to my logs, and started issuing the queries using the awesome relatively new Hive portal on the HDInsight cluster.</p>
<p>I created two queries for the two business questions above: <a href="https://github.com/mooso/nosqlloggingbenchmark/blob/master/Queries/CountErrors2.hql">a simple COUNT()</a> query for what I'll call the "Count Errors" scenario, and <a href="https://github.com/mooso/nosqlloggingbenchmark/blob/master/Queries/AverageOperationDuration.hql">an aggregate over self-join</a> query for what I'll call the "Average Duration" scenario. The average elapsed times for those scenarios on unadorned Hive were 280 seconds and 489 seconds respectively (and yes, the results did capture the planted anomalies so I have decent confidence in the correctness). When I created 16-node clusters, the times went down to 218 seconds and 434 seconds, which is an OK speedup but not exactly linear scaling.</p>
<p>So this was unadorned Hive on HDInsight 3.1. But one of the exciting changes that came with HDInsight 3.1 is the introduction of <a href="http://tez.apache.org/">Tez</a> to Hive, which enables a more sophisticated execution engine than plain-old Map-Reduce. It's not on by default, but it's definitely worth trying out. So I changed the execution engine to Tez (<code>SET hive.execution.engine=tez</code>) and tried it out. The results were surprisingly mixed: the best speedup was in the 16-node case in the Average Duration query which was executed in the blazingly fast time of 305 seconds (spoiler alert: this the fastest among all contestants for this scenario). Interestingly though in the 8-node case this scenario was <em>slower</em>, executing in an average of 574 seconds. For the Count Errors scenario the results are more straightforward: Tez sped up the scenario so it executes in about 2/3 the time as Hive-over-Map-Reduce for both 8-nodes and 16-nodes scenarios.</p>
<p>Here is the summary of the Hive/MR (default) and Hive/Tez results:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/64/41/7455.CountErrorsHiveSummary.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-64-41/7455.CountErrorsHiveSummary.png" alt="" /> <img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/64/41/5327.AverageDurationHiveSummary.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-64-41/5327.AverageDurationHiveSummary.png" alt="" /></p>
<h1>And in comes the youngest challenger: Presto</h1>
<p>And next comes Presto: the youngest entrant in this showdown. Since Presto is a memory-hungry beast, in my basic configuration I had 8 <a href="http://azure.microsoft.com/en-us/pricing/calculator/?scenario=cloud">A6</a> workers (which is the memory-intensive VM at 28GB RAM and 4 cores), a Large coordinator and 1 Small Hive Metastore. I used the same backing SQL Azure DB for the metastore as I did for Hive so I had the same table definition right away, then I used the Presto CLI from my box to issue the queries. I modified the <a href="https://github.com/mooso/nosqlloggingbenchmark/blob/master/Queries/CountErrors2.sql">Count Errors</a> and <a href="https://github.com/mooso/nosqlloggingbenchmark/blob/master/Queries/AverageOperationDuration.sql">Average Duration</a> queries to match the more ANSI SQL dialect of Presto (I got the same results as Hive, so again I feel good about the correctness of my results).</p>
<p>The results were pretty impressive especially on the Count Errors scenario: on 8 nodes, Presto blew away 8-node HDInsight: 55 seconds vs. the best Hive result for 8 nodes which is 182 seconds. But wait: is it fair to compare the 8 A6 nodes Presto got vs. the 8 Large nodes HDInsight uses? I can't give Presto a fair chance with Large nodes, and I can't customize node sizes on HDInsight, so I'm stuck with this apples-to-oranges comparison here. They have the same number of cores, but A6 nodes are about twice the price of Large, so I think the fair comparison is to compare against 16-node HDInsight. Even with that allowance, Presto on the Count Errors scenario strongly wins since the best Hive result there is 133 seconds, still more than twice as slow as Presto's 8-node result.</p>
<p>On the Average Duration scenario, the results are good but less impressive. 8-node Presto executed the query in an average of 462 seconds, which beats 8-node Hive (489 seconds for Hive/MR, 574 seconds for Hive/Tez) but is much slower than 16-node Hive/Tez (305 seconds).</p>
<p>So here is the summary of the rumble of Presto vs. Hive/Tez if we take the same rough price point (8 A6 vs. 16 Large):</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/64/41/6170.Presto-v-Hive-SamePricePoint.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-64-41/6170.Presto_2D00_v_2D00_Hive_2D00_SamePricePoint.png" alt="" /></p>
<p>And here is the rumble if we take the same number of cores (8 A6 vs. 8 Large):</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/64/41/7080.Presto-v-Hive-SameNumberOfCores.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-64-41/7080.Presto_2D00_v_2D00_Hive_2D00_SameNumberOfCores.png" alt="" /></p>
<p>Note: the results get switched around a bit if it's 16 A6 vs. 16 Large, since at that scale Presto is a bit slower than Hive/Tez on the Average Duration scenario, though it beats it on the Count Errors one.</p>
<p>One more note on Presto: one of the things that don't show here that much that I like about it is that of all the three I'm trying here, it struck me as the most predictable in its perf at different scale points. You've seen the surprising scale results I got out of Hive/Tez and Hive/MR, but with Presto when I tried 4 cores vs. 8 cores vs. 16 cores, on both scenarios I got a nice almost (but not quite) linear scaling in the duration: 150-&gt;55-&gt;38 on Count Errors, and 66-&gt;462-&gt;366 on Average Duration. Also, if you look at individual query durations (instead of averages) for each scale point, Presto typically has much less variation at any one scale point.</p>
<h1>And finally: our electric Shark!</h1>
<p>And now comes my newest and most troublesome addition to Blue Coffee: Spark and Spark SQL/Shark (it's really Spark SQL now, but I just like calling it Shark too much). I have to admit: this took me by far the most effort to get up and running, and even now I'm pretty sure I don't have it running that well. My troubles got much less severe once I moved away from the <a href="https://github.com/apache/spark">master</a> branch in Spark (which is way too active/unstable) and the standalone discontinued <a href="https://github.com/amplab/shark">Shark</a> repository, to the <a href="https://github.com/apache/spark/tree/branch-1.1">branch-1.1</a> branch with the <a href="https://github.com/apache/spark/tree/branch-1.1/sql">packaged Spark SQL</a> there that replaced Shark. However, even after that move I still encountered problems. I think my main performance problems that I haven't fully gotten to the bottom of is in the shuffling of data between nodes (BlockFetcher): I had to bump up a couple of connection timeouts to even get it working on the more complex Average Duration scenario, but it still worked too slow for what it is and I think it comes down to problems there.</p>
<p>For this post, I'm not using Spark's full power: I'm not loading the data first into <a href="http://spark.apache.org/docs/latest/programming-guide.html#resilient-distributed-datasets-rdds">RDD's</a>, instead just querying them from cold storage directly. As follow-up I hope to experiment with that, but for now since I'm not worrying about loading things into memory I can get away with using Large instances for the workers (instead of A6), so I can compare against HDInsight directly and fairly.</p>
<p>So I provisioned a Spark cluster: 8 Large workers, 1 Small Master node, 1 Large node for the Thrift server and 1 Small Hive Metastore node. Since the Hive metastore is backed by the same Azure DB where my table definitions are already stored, and Spark SQL understads HiveQL, I just launched the same queries I used for Hive from BeeLine from within the cluster (launching them from outside fails because Azure Load Balancer <a href="http://blogs.msdn.com/b/avkashchauhan/archive/2011/11/12/windows-azure-load-balancer-timeout-details.aspx">kills</a> my connection after one minute).</p>
<p>The results were pretty bad. On 8 workers Count Errors finishes in 271 seconds which is about the same as Hive/MR 8 nodes but much worse the Hive/Tez or Presto, and Average Duration finishes in 714 seconds which is about 25% slower than the slowest 8-node contender so far (Hive/Tez). The worse news is that on 16 nodes the times hover about the same (on average slight faster but within the variance). I dug into it a tiny bit and it seems to do with my mysterious problem with the performance of fetching blocks among the nodes: since that's slow for whatever reason, exchanging blocks among 16 nodes overwhelms any speed gains from distributing the processing among them. It also doesn't help that by default Spark SQL has <code>spark.sql.shuffle.partitions</code> set to 200 which leads to several stages (especially among the small ORDER BY parts I put in there) to be split among 200 tiny tasks, leading to pretty big unnecesary overheads.</p>
<p>Since this is the least tuned/understood contender for me, I'll refrain from putting summary graphs in here: I fully acknowledge that this needs more work to get a fair chance in the arena, so I don't want anyone skimming this post to get the wrong impression about it from a graph.</p>
<h1>So... now what?</h1>
<p>My hope is that what you get out of this post isn't the specific performance numbers - since again I didn't tune any of this, and it doesn't qualify as a fair performance benchmark. Instead, what I'm hoping you'll get is:</p>
<ol type="a">
<li>the feel for these different data analysis products and what they can do and</li>
<li>how awesome it is that you can right now choose among all those different options (and more) to analyze your data in Azure!</li>
</ol>
<p>In that spirit, I'm hoping to go on to expand this to other possibilities, e.g.: how about instead of loading the logs into blobs, the workers directly inserted them into an <a href="http://www.elasticsearch.org/">Elastic Search</a> cluster instead? Would that make the end-to-end scenario easier? Or what if the logs went into <a href="http://azure.microsoft.com/en-us/services/event-hubs/">Event Hub</a>, and from there were consumed by both a <a href="http://storm.incubator.apache.org/">Storm</a> cluster that calculated average durations on the fly, and a spooler that placed the data into Azure blob store? What if the data was placed in blob store in a more sophisticated format (e.g. ORC or Parquet) than CSV? The possibilities are endless and awesome!</p>
<p>Another avenue I'd like to explore is higher scale: go beyond my puny 35 GB data volume here and into the 10's or 100's of TB's scale. It'd be great to see this work, and what I'd need to shard/do to get this scenario working smoothly.</p>]]></content:encoded>
    </item>
    <item>
      <title>HDInsight working with different storage accounts</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/hdinsight-working-with-different-storage-accounts</link>
      <pubDate>Wed, 03 Sep 2014 14:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2014/09/03/hdinsight-working-with-different-storage-accounts/</guid>
      <description><![CDATA[Storage accounts - configured and otherwise
When you create an HDInsight cluster, whether through...]]></description>
      <content:encoded><![CDATA[<h1>Storage accounts - configured and otherwise</h1>
<p>When you create an HDInsight cluster, whether through the Azure portal or programmatically through e.g. PowerShell, you get a chance to add extra storage accounts to the cluster. In PowerShell it looks something like this:</p>
<pre>$clusterConfig = New-AzureHDInsightClusterConfig -ClusterSizeInNodes 4
$allAccounts = @('myfirstaccount','mysecondaccount','mythirdaccount')
$clusterConfig = Set-AzureHDInsightDefaultStorage $clusterConfig `
  -StorageAccountName $allAccounts[0] `
  -StorageAccountKey $(Get-AzureStorageKey $allAccounts[0]).Primary `
  -StorageContainerName 'mycontainer'
$allAccounts |
  Select-Object -Skip 1 |
  %{$clusterConfig = Add-AzureHDInsightStorage $clusterConfig `
  -StorageAccountName $_ `
  -StorageAccountKey $(Get-AzureStorageKey $_).Primary}
</pre>
<p>What that code snipppet does is setup the default storage account/container (where the cluster's data will go by default), but also configures additional storage accounts that the cluster can access in its jobs later.</p>
<p>A common question that we get though is: I already have a cluster configured, but I want to read some data from (or less frequently, write some data to) a storage account that I didn't setup in this way when I created my cluster - is that possible? The answer is: it's complicated, which is why I'm dedicating this post to a detailed explanation of that slippery answer.</p>
<h1>So when you say "configured" - what do you mean exactly?</h1>
<p>Before jumping into what's possible or not, it really helps to explain what exactly happens when a storage account is configured. Within the WASB driver that accesses data in Azure blob storage, when we try to access data within a container in a storage account, we go through a series of decisions based on our <em>available configuration</em> to determine how we'll try to access that:</p>
<ol>
<li>If we have a <a href="http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-shared-access-signature-part-1/"> Shared Access Signature </a> for the container, we'll use that.</li>
<li>Else if we have a key for the whole account, we'll use that.</li>
<li>Else we'll try to get in with anonymous access, and hope the container is a public container.</li>
</ol>
<p>The key phrase in the preceding part is "available configuration". When a cluster is created with some storage accounts like shown in the introduction, the HDInsight infrastructure does some plumbing work so that the account keys are placed (encrypted, more on that later) in the "core-site.xml" file on every node in the cluster, which is the configuration file loaded by default by almost all Hadoop ecosystem components, so that these keys are part of the available configuration for almost everything you do in HDInsight. But if you know how Hadoop configuration works, you'll know that this is not the only way things can get into the available configuration. For every job you launch, you're allowed to define whatever you want in that job's configuration, which means that you can sneak in additional storage accounts' keys in there!</p>
<h1>Alright, show me that word count!</h1>
<p>So let's try this out. The easiest way to try this is through a Map-Reduce job, and instead of writing a new job, I'll ask you to bear with me through yet another usage of the well-worn WordCount example. If you want to follow through this example, you'll need an Azure subscription, the Azure SDK installed with that subscription selected as default in PowerShell, an HDInsight cluster, and a storage account that wasn't added to that cluster when it was created. I'll assume the following input variables are defined in your PowerShell:</p>
<pre># Inputs
$clusterName = 'yourclustername'
$wantedAccountName = 'youraccount'
$wantedContainerName = 'yourcontainer'
$localPlayDirectory = 'C:\LocalPlay'
</pre>
<p>where $localPlayDirectory is just a directory we'll use for files we upload to/download from the cluster, and the rest are self-explanatory. With that out of the way, we need to get the account key, create a storage context we'll use for it, and make sure the container is there:</p>
<pre># Preliminaries: Get the key, create the context, create the container
$wantedAccountKey = $(Get-AzureStorageKey $wantedAccountName).Primary
$wantedAccountContext = New-AzureStorageContext `
  -StorageAccountName $wantedAccountName `
  -StorageAccountKey $wantedAccountKey
$container = Get-AzureStorageContainer $wantedContainerName `
 -Context $wantedAccountContext `
 -ErrorAction SilentlyContinue
If ($container -eq $null)
{
  $container = New-AzureStorageContainer -Context $wantedAccountContext `
    -Name $wantedContainerName
}
</pre>
<p>And we'll create a simple input blob in the container that we'll count the words for:</p>
<pre># Preliminaries: Create an input blob
$localPlayDirectory = md $localPlayDirectory -Force
$inputFile = "$localPlayDirectory\simple.txt"
'This is an interesting word count demo. It even has two of This' |
  Out-File $inputFile -Encoding ascii -Force
$inputBlobName = 'input/simple.txt'
$inputBlob = Set-AzureStorageBlobContent -Context $wantedAccountContext `
  -Container $wantedContainerName -Blob $inputBlobName -File $inputFile
</pre>
<p>I'll also define a function that I'll use to run jobs later:</p>
<pre>function Run-PlayJob($jobDefinition, $outputDirectory = $null)
{
  If ($outputDirectory -ne $null)
  {
    # Delete the output directory if it exists from a previous run
    $outputBlobs = Get-AzureStorageBlob -Context $wantedAccountContext `
      -Container $wantedContainerName `
      -Prefix "$outputDirectory" | Remove-AzureStorageBlob
  }
  # Run the job and wait for it to finish
  $job = Start-AzureHDInsightJob -Cluster $clusterName `
    -JobDefinition $jobDefinition
  $job = Wait-AzureHDInsightJob -Job $job
  # Get the stderror to get the diagnostics output
  Get-AzureHDInsightJobOutput -Cluster $clusterName `
    -JobId $job.JobId -StandardError
  If ($outputDirectory -ne $null)
  {
    # Download all the output blobs
    $outputBlobs = Get-AzureStorageBlob -Context $wantedAccountContext `
      -Container $wantedContainerName `
      -Prefix "$outputDirectory/part-r" |
      Get-AzureStorageBlobContent -Context $wantedAccountContext `
      -Destination $localPlayDirectory -Force
    # Dump them into stdout
    Get-ChildItem "$localPlayDirectory\$outputDirectory" |
      Get-Content
  }
  Else
  {
    # No output directory, get the stdout of the job
    Get-AzureHDInsightJobOutput -Cluster $clusterName `
      -JobId $job.JobId -StandardOutput
  }
}
</pre>
<p>OK finally we finish the preliminaries and get to the crux of this. Here is how we define a Word Count example that reads the input from an alien storage account, and writes its output there as well:</p>
<pre># Map-Reduce example
$fullAccountName = "$wantedAccountName.blob.core.windows.net"
$wordCountDef = New-AzureHDInsightMapReduceJobDefinition `
  -JarFile '/example/jars/hadoop-mapreduce-examples.jar' `
  -ClassName 'wordcount' `
  -Arguments "wasb://$wantedContainerName@$fullAccountName/$inputBlobName", `
   "wasb://$wantedContainerName@$fullAccountName/mroutput" `
  -Defines @{"fs.azure.account.key.$fullAccountName"=$wantedAccountKey}
Run-PlayJob $wordCountDef 'mroutput'
</pre>
<p>If you've been following along, running the above should give you a nice word count for this file that wasn't in the cluster's configured accounts, which is awesome! A few things to note:</p>
<ol>
<li>Note the "-Defines" section, where we defined the key for our wanted account. We could've defined even more keys for more accounts, or we could've also defined shared access signatures instead.</li>
<li>Note the usage of fully qualified WASB URI's for the input/output files so we can specify files outside the default account/container.</li>
</ol>
<h1>OK, but can Pigs fly?</h1>
<p>Well if that's all there is to it, why did I say in the beginning the answer is complicated? Seems so far to be a simple "yes", right? Well, it would be if HDInsight only exposed pure Map-Reduce, but of course there are other things in there that you can run. So would this work for everything? Well, let's try pig!</p>
<p>Fortunately I can just reuse all the preliminaries I did in the Map-Reduce section, and jump right to the Pig job definition here:</p>
<pre># Pig example
$pigScript = "SET fs.azure.account.key.$fullAccountName '$wantedAccountKey';
LOADED = LOAD 'wasb://$wantedContainerName@$fullAccountName/$inputBlobName';
TOKENIZED = foreach LOADED generate flatten(TOKENIZE((chararray)`$0)) as word;
GROUPED = group TOKENIZED by word;
COUNTED = foreach GROUPED generate COUNT(TOKENIZED), group;
store COUNTED into 'wasb://$wantedContainerName@$fullAccountName/pigoutput';"
$pigDef = New-AzureHDInsightPigJobDefinition `
 -Query $pigScript.Replace("`n", "").Replace("`r", "")
Run-PlayJob $pigDef 'pigoutput'
</pre>
<p>OK first try it out if you're a brave person following hands-on. Back? You should've seen this succeed with flying colors as well, because Pig is indeed very amenable to this treatment. The code looks a bit different but it's essentially the same idea: we use SET instead of -Defines to pass the configuration value we want, and we still use the same fully qualified URI's. So far so good.</p>
<h1>Hive, where our lucky streak runs out</h1>
<p>Stil not seeing the "it's complicated" reasoning? Well, now we get to why it's not all butterflies and rainbows. Let's try this with Hive:</p>
<pre># Hive example - doesn't work unless metastore has the key
$hiveScript = "SET fs.azure.account.key.$fullAccountName=$wantedAccountKey;
DROP TABLE IF EXISTS FromMyAccount;
CREATE EXTERNAL TABLE FromMyAccount
(AllOfIt string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
LOCATION 'wasb://$wantedContainerName@$fullAccountName/input';
SELECT * FROM FromMyAccount;"
$hiveDef = New-AzureHDInsightHiveJobDefinition `
 -Query $hiveScript.Replace("`n", "").Replace("`r", "")
Run-PlayJob $hiveDef
</pre>
<p>If you try running this, you'll finally hit the dreaded error:</p>
<p><code> Failed with exception java.io.IOException:org.apache.hadoop.fs.azure.AzureException: org.apache.hadoop.fs.azure.AzureException: Container yourcontainer in account youraccount.blob.core.windows.net not found, and we can't create it using anoynomous credentials. </code></p>
<p>What this is saying really is that WASB didn't find the key for the account in its configuration (the reason it doesn't just say that should be more understandable if you follow its reasoning I outlined in the beginning: it's in the last part of that chain where it's trying to access the data using anonymous credentials). But why? We use SET to provide this configuration, what's it complaining about? The reason lies in the stateful nature of Hive. Unlike Pig (which is stateless), Hive keeps metadata in a service called metastore (backed by a SQL database). The problem is that the "CREATE TABLE" statement runs in the metastore service, which doesn't get the SET statement so doesn't get the configuration from there. There is to the best of my knowledge no supported way to pass this configuration value to the metastore service, so unfortunately the only supported way to get that scenario going is to drop and recreate your cluster with that account configured from the start.</p>
<p>Now, you'll notice I qualified that statement with "supported". If you really want to live on the edge and get this to work temporarily, you can still do it. I won't show detailed step-by-step, but roughly:</p>
<ol>
<li>Enable Remote on the cluster (can only be done in the Azure portal.)</li>
<li>Log into the headnode. Make sure it's the active headnode not the passive one (you can check by which services are running, or by the "Hadoop Service Availability" page on the desktop). If it's the passive one, you need to log out, modify the RDP file you downloaded to point to the other headnode instance, and go there.</li>
<li>Modify the core-site.xml under the "C:\apps\dist\hadoop-xxx\etc\hadoop" directory and add the key configuration in there.</li>
<li><code>Restart-Service metastore</code></li>
<li>Rerun the script from above, it should work now.</li>
</ol>
<p>This really isn't the best idea for the long run though: the minute this VM is reimaged by Azure, or for whatever other reason HDInsight switches to the other headnode, this will stop working.</p>
<p><em>Update (9/9/2014):</em> Thanks to Ashit Gosalia from the HDInsight team for pointing me to this <a href="http://social.technet.microsoft.com/wiki/contents/articles/23256.using-an-hdinsight-cluster-with-alternate-storage-accounts-and-metastores.aspx">awesome article</a> by Eric Hanson that describes an ingenious way around this problem: instead of hitting the metastore service that doesn't have this key configured, we can bypass it and just tell Hive to get the metadata from a SQL Azure instance directly! This does require you setup your own SQL Azure DB to back this up and configure it as a metastore, so putting it together it looks like this:</p>
<pre># More inputs
$sqlAdminUser = '{fill in}'
$sqlAdminPassword = '{fill in but avoid exclamation marks}'
$metastoreDatabaseName = 'ExternalMetastore'

# Preliminaries
$location = $(Get-AzureHDInsightCluster $clusterName).Location
$sqlScriptLocation = `
 'https://raw.githubusercontent.com/apache/hive/branch-0.13/' + `
 'metastore/scripts/upgrade/mssql/hive-schema-0.12.0.mssql.sql'
$sqlScript = $(Invoke-WebRequest $sqlScriptLocation).Content

# Create SQL Azure metastore DB
$sqlServer = New-AzureSqlDatabaseServer -Location $location `
 -AdministratorLogin $sqlAdminUser -AdministratorLoginPassword $sqlAdminPassword
$sqlDatabase = New-AzureSqlDatabase -ServerName $sqlServer.ServerName `
 -DatabaseName $metastoreDatabaseName -Collation 'SQL_Latin1_General_CP1_CI_AS' `
 -Edition Web
$AllowEveroneFirewallRule = New-AzureSqlDatabaseServerFirewallRule `
 -ServerName $sqlServer.ServerName -RuleName AllowEveryone `
 -StartIpAddress 0.0.0.0 -EndIpAddress 255.255.255.255
$AllowAzureFirewallRule = New-AzureSqlDatabaseServerFirewallRule `
 -ServerName $sqlServer.ServerName -RuleName AllowAzure -AllowAllAzureServices
Invoke-Sqlcmd -Query $sqlScript `
 -ServerInstance "$($sqlServer.ServerName).database.windows.net,1433" `
 -Username $sqlAdminUser -Password $sqlAdminPassword -Database $sqlDatabase.Name
				
# Hive script pointing to my blob
$hiveScript = "
DROP TABLE IF EXISTS FromMyAccount;
CREATE EXTERNAL TABLE FromMyAccount
(AllOfIt string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
LOCATION 'wasb://$wantedContainerName@$fullAccountName/input';
SELECT * FROM FromMyAccount;"

# Defines for Metastore redirect and key
$connectionUrl = `
 "jdbc:sqlserver://$($sqlServer.ServerName).database.windows.net;" + `
 "database=$($sqlDatabase.Name);" + `
 "encrypt=true;trustServerCertificate=true;create=false"
$defines = @{
  "fs.azure.account.key.$fullAccountName" = $wantedAccountKey;
  "hive.metastore.uris" = "";
  "javax.jdo.option.ConnectionURL" = $connectionUrl;
  "javax.jdo.option.ConnectionUserName" = "$sqlAdminUser@$($sqlServer.ServerName)";
  "javax.jdo.option.ConnectionPassword" = "$sqlAdminPassword";
}
# Full Hive job definition
$hiveDef = New-AzureHDInsightHiveJobDefinition `
 -Query $hiveScript.Replace("`n", "").Replace("`r", "") `
 -Defines $defines

# Run the job
Run-PlayJob $hiveDef
</pre>
<h1>Security implications</h1>
<p>So in this last section I want to discuss some of the security implications of what I explained here. By default HDInsight encrypts the storage keys for all the initial accounts using a certificate which is generated for this cluster. This is good because these keys give wide access to everything in those accounts, so the more carefully guarded they are the better. Unfortunately this certificate isn't available outside the cluster so we couldn't do the same encryption ourselves, which means that whenever we passed those keys around we passed them in plain-text (the REST API is over SSL so it's not really plain-text over the wire). Also, all the job configuration is stored into job history files in the default container for the cluster, so after you run any of the example jobs here then look at your default container, you'll find a blob called something like "mapred/history/done/.../job_xxx_conf.xml" which contains those keys in plain sight (to anyone with access to that container).</p>
<p>So if you're running your job in someone else's cluster, you really need to assume they'll be able to access your keys if you use the techniques described here. Also even if this is your cluster, this is fairly sloppy key management to have your keys lying around like that in plain text (though I've been guilty of that myself for not-so-sensitive accounts).</p>
<p>A decent mitigation is to use shared access signatures instead of account keys. The basics are the same, except the configuration knob you want is "fs.azure.sas.youraccount.blob.core.windows.net" instead of "fs.azure.account.key.youraccount.blob.core.windows.net". This way if they key is compromised it's at least a granular key to a single container instead of the whole account. Of course for really sensitive data, you are probably better off just configuring the cluster with that account from the start so the keys are encrypted from the beginning.</p>]]></content:encoded>
    </item>
    <item>
      <title>More Blue Coffee - Presto on Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/more-blue-coffee-presto-on-azure</link>
      <pubDate>Tue, 12 Aug 2014 10:25:00 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2014/08/12/more-blue-coffee-presto-on-azure/</guid>
      <description><![CDATA[Presto!
The Facebook team recently open-sourced a very cool distributed query engine that they...]]></description>
      <content:encoded><![CDATA[<h1>Presto!</h1>
<p>The Facebook team recently open-sourced a very cool distributed query engine that they concisely called <a href="http://prestodb.io/">Presto</a>. Unlike say HBase, Presto doesn't store its own data, instead it can plug-in data from a variety of sources (e.g. Cassandra) and offers an ANSI SQL query engine that distributes the query processing to many nodes. Since I'm as knowledgable about Presto as I am about making musicals, I'll refrain from trying to explain more and instead redirect you to their <a href="http://prestodb.io/">home page</a> or <a href="https://www.facebook.com/notes/facebook-engineering/presto-interacting-with-petabytes-of-data-at-facebook/10151786197628920"> this short article </a> for more information. Instead, let me describe how I got it on Azure Compute and querying data from blob store!</p>
<h1>Presto getting a little blue...</h1>
<p>When I saw Presto I really wanted to see it in action on Azure and play with it. Of course I could've spun up a few Linux VM's and setup Presto on those (and in fact a colleague of mine started doing just that), but I was looking for a bit more fun so I decided to get it on <a href="http://blogs.msdn.com/b/mostlytrue/archive/2014/07/15/come-in-have-some-blue-coffee.aspx"> Blue Coffee </a> instead. Since Presto is pretty much all pure Java, getting it running on Windows wasn't too hard: mainly extending an if statement that only allowed OS X and Linux in to let Windows through as well, and adding a Windows native library to presto-hadoop-apache2. After that it was a matter of slight reverse engineering of their scripts and configuration to get the logic right, and boom I had it running on Azure (of course it was that easy).</p>
<h1>Snakey charm</h1>
<p>As explained, Presto on its own is not that interesting, it needs data! When I first got it up, my first test catalog for it was Cassandra: I already had that running in Blue Coffee, and configuring it was relatively easy. So I added a catalog configuration class for it, and then tried it out with a simple Azure service that stood up a Cassandra cluster next to a Presto one, with Presto configured to be able to query the Cassandra cluster. It worked like a charm, so now it was on to more interesting things...</p>
<h1>Going after the blobby prize</h1>
<p>Presto can also query data from "Hive", but it would help if I first explain why I put those quotes there. If you're not familiar with it, Hive is a Hadoop-based service that stores metadata in a database fronted by a service called the Metastore service, stores the actual data in a Hadoop-compatible file system, and then has a server that can translate SQL (HQL) queries into Map-Reduce (or in the case of Tez pure Yarn DAGs) jobs on a Hadoop cluster to get you the results. Presto though, being the crack SQL engine that it is, doesn't use that last part (which is the bulk of Hive): it just queries the Metastore service for metadata, then goes and does its own query processing fetching the data directly from the Hadoop file system when it needs it.</p>
<p>So, since blob storage is already exposed as a Hadoop file system through WASB, this seemed very enticing: I could just spin up a measly Hive metastore service pointing to data on my Azure blob storage account, then I can use Presto as a distributed SQL query engine on that data! Brilliant! Of course, I can already do this with HDInsight and Hive, but the more cool ways I can analyze my data the merrrier right?</p>
<p>Hive wasn't on Blue Coffee, so I added it (at least enough to get the Metastore service running). After that, it was just a matter of adding another catalogue configuration logic into Presto to hook it up with Hive, some fun debugging, then I was able to spin up a Presto cluster that analyzes my blob store data. It was awesome - and since I'm a generous guy like that, in this post I want to guide you through your own way of spinning up such a cluster so you can experience the awesomeness yourself.</p>
<h1>A quick guide to a DIY Presto-on-Azure cluster</h1>
<p><em>WARNING: this is all bleeding-edge stuff so don't expect easy packaged solutions here.</em></p>
<p>As usual, you need Visual Studio and the Azure SDK. To make this tutorial easier, I'll also assume you have an Azure SQL Server database with Hive metadata pointing to your data already. This means: you create an Azure SQL database, create an HDInsight cluster with this database configured as the Hive metastore, create your Hive tables there (make sure you use fully qualified WASB URI's as the location for these tables), then you can drop this HDInsight cluster since we won't need it after that. It's also possible to make the Hive metastore service backed by a local Derby server and skip the preceding step, and if you're adventurous please try that.</p>
<p>With all this prep out of the way, let's build us a Presto service!</p>
<ol>
<li>Open Visual Studio, and create a new Windows Azure Cloud Service project. Add 3 worker roles named "HiveMetastore", "PrestoCoordinator" and "PrestoWorker" (the naming is important) and make sure you have Azure SDK version 2.3 selected.</li>
<li>Right-click on the solution, manage nuget packages for solution, Online, Select &ldquo;Include Prerelease&rdquo; instead of &ldquo;Stable Only&rdquo; (because you&rsquo;re hard-core like that), search for &ldquo;Presto&rdquo;, install &ldquo;Microsoft.Experimental.Azure.Presto&rdquo; to the two Presto roles.</li>
<li>Similarly, install &ldquo;Microsoft.Experimental.Azure.Hive&rdquo; to the HiveMetastore role.</li>
<li>Use the following code for the HiveMetastore's WorkerRole.cs:
<pre>using Microsoft.Experimental.Azure.Hive; 
namespace HiveMetastore
{
	public class WorkerRole : HiveMetastoreNodeBase
	{
		protected override HiveMetastoreConfig GetMetastoreConfig()
		{
			return new HiveSqlServerMetastoreConfig(
				serverUri: "//{yourdbserver}.database.windows.net",
				databaseName: "{yourdb}",
				userName: "{user}@{yourdbserver}",
				password: "{password}");
		}
	}
}
</pre>
Filling in the appropriate values for your Azure SQL Server database.</li>
<li>Use the following code for the two Presto services' WorkerRole.cs:
<pre>using Microsoft.Experimental.Azure.Presto;
using Microsoft.WindowsAzure.ServiceRuntime;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PrestoCoordinator
{
	public class WorkerRole : PrestoNodeBase
	{
		protected override IEnumerable&lt;PrestoCatalogConfig&gt; ConfigurePrestoCatalogs()
		{
			var hiveNode = RoleEnvironment.Roles["HiveMetastore"].Instances
				.Select(GetIPAddress)
				.First();
			var hiveCatalogConfig = new PrestoHiveCatalogConfig(
				metastoreUri: String.Format("thrift://{0}:9083", hiveNode),
				hiveConfigurationProperties: new Dictionary&lt;string, string&gt;()
				{
					{ "fs.azure.skip.metrics", "true" },
					{ "fs.azure.check.block.md5", "false" },
					{ "fs.azure.account.key.{youraccount}.blob.core.windows.net", "{yourkey}" },
				});
			return new PrestoCatalogConfig[] { hiveCatalogConfig };
		}
		protected override bool IsCoordinator
		{
			get { return {true for Coordinator, false for Worker}; }
		}
	}
}
</pre>
Filling in the information for your Azure storage account, and fixing the IsCoordinator property for the coordinator/worker roles appropriately.</li>
<li>Use the following for your ServiceDefinition.cs:
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;ServiceDefinition name="&lt;your service&gt;" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2014-01.2.3"&gt;
  &lt;WorkerRole name="PrestoCoordinator" vmsize="Large"&gt;
    &lt;Imports&gt;
      &lt;Import moduleName="Diagnostics" /&gt;
    &lt;/Imports&gt;
    &lt;Endpoints&gt;
      &lt;InputEndpoint name="HTTP" protocol="tcp" port="8080" localPort="8080" /&gt;
      &lt;InternalEndpoint name="Dummy" protocol="tcp" port="8020" /&gt;
    &lt;/Endpoints&gt;
    &lt;LocalResources&gt;
      &lt;LocalStorage name="DataDirectory" cleanOnRoleRecycle="false" sizeInMB="102400" /&gt;
      &lt;LocalStorage name="InstallDirectory" cleanOnRoleRecycle="true" sizeInMB="256" /&gt;
    &lt;/LocalResources&gt;
  &lt;/WorkerRole&gt;
  &lt;WorkerRole name="PrestoWorker" vmsize="A6"&gt;
    &lt;Imports&gt;
      &lt;Import moduleName="Diagnostics" /&gt;
    &lt;/Imports&gt;
    &lt;Endpoints&gt;
      &lt;InternalEndpoint name="HTTP" protocol="tcp" port="8081" /&gt;
    &lt;/Endpoints&gt;
    &lt;LocalResources&gt;
      &lt;LocalStorage name="DataDirectory" cleanOnRoleRecycle="false" sizeInMB="102400" /&gt;
      &lt;LocalStorage name="InstallDirectory" cleanOnRoleRecycle="true" sizeInMB="256" /&gt;
    &lt;/LocalResources&gt;
  &lt;/WorkerRole&gt;
  &lt;WorkerRole name="HiveMetastore" vmsize="Small"&gt;
    &lt;Imports&gt;
      &lt;Import moduleName="Diagnostics" /&gt;
    &lt;/Imports&gt;
    &lt;Endpoints&gt;
      &lt;InternalEndpoint name="Thrift" protocol="tcp" port="9083" /&gt;
    &lt;/Endpoints&gt;
    &lt;LocalResources&gt;
      &lt;LocalStorage name="DataDirectory" cleanOnRoleRecycle="false" sizeInMB="1024" /&gt;
      &lt;LocalStorage name="InstallDirectory" cleanOnRoleRecycle="true" sizeInMB="256" /&gt;
    &lt;/LocalResources&gt;
  &lt;/WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</pre>
Notice that I use A6 for the PrestoWorker role: Presto is very memory-hungry, so I really got best results by using A6.</li>
</ol>
<p>And that should be that. This defines a service that exposes the Presto port that you can interact with using the Presto CLI (<strong>IMPORTANT: this is naively unsecured, so if you have sensitive data on your Azure account please don't deploy this</strong>). You should be able to try this out in your Azure emulator, and then interact with it using the Presto CLI:</p>
<ol>
<li>Download the CLI jar from <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/64/41/2783.presto-cli-0.74-SNAPSHOT-executable.jar" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-64-41/2783.presto_2D00_cli_2D00_0.74_2D00_SNAPSHOT_2D00_executable.jar"> here </a>.</li>
<li>Run it like this:
<pre>java -jar presto-cli-0.74-SNAPSHOT-executable.jar --server http://localhost:8080
</pre>
</li>
<li>Try it out:
<pre>use catalog hive;
show tables;
select * from mytable limit 10;
</pre>
</li>
<li>And if all goes well, you can deploy it (again, heed security warning above) and interact with it from your machine the same way except using {yourservice}.cloudapp.net instead of localhost.</li>
</ol>
<h1>Parting thoughts</h1>
<p>I really like Presto so far, and I think it's a very promising technology (I have no ties to the team that developed it, and would love to chat with them at some point). This is very early days for both Presto itself at least in the open world outside its promising start within Facebook, and for my experimentation with it on Azure. I can already see very fast query performance for certain types of queries (faster than I could get with Hive on HDInsight), and hopefully I'll get to play with it more and see what I can do with it.</p>]]></content:encoded>
    </item>
    <item>
      <title>Living on the edge - testing without mocking (Part 2)</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/living-on-the-edge-testing-without-mocking-part-2</link>
      <pubDate>Sat, 26 Jul 2014 13:23:00 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2014/07/26/living-on-the-edge-testing-without-mocking-part-2/</guid>
      <description><![CDATA[The (micro-) epic continues...
In the first part of this N-part series (where N may or may not...]]></description>
      <content:encoded><![CDATA[<h1>The (micro-) epic continues...</h1>
<p>In the <a href="http://blogs.msdn.com/b/mostlytrue/archive/2014/07/04/living-on-the-edge-testing-without-mocking-part-1.aspx">first part</a> of this N-part series (where N may or may not equal 2), I thoroughly convinced you that while testing against mock systems is wise and all, it's always cool to also live dangerously and write/run unit tests against live systems at least every once in a while. In this post I'd like to continue this with another pattern that has proved useful to me in this thrilling world.</p>
<h1>The secret wild side pattern</h1>
<p>So you're a hip start-up programmer writing a super-cool machine learning system to figure out the best coffee blends you can make for any time of day (and you're of course reading this in 2018 when Microsoft has become cool with start-ups again - isn't it great?). C-Blenda relies on a web service that always gives the available coffee beans and their prices/characteretics in any city in the world:</p>
<pre>IEnumerable&lt;BeanInfo&gt; GetAllCoffee(Location location)</pre>
<p>Now as a conscientious programmer, you abstract this out into an abstract base class (<em>not</em> an interface - a pet peeve of mine that I may expand on some day), with a concrete implementation that actually calls into the web service, and various mock implementations that you use in your tests. You then code up your brilliant implementation with awesome tests to go with it, for example this test that checks that you always give at most three recommendations for the morning (can't tax that caffeine- deprived brain too much in the morning):</p>
<pre>[TestMethod]
public void GoodNumberOfMorningRecommendations()
{
  var coffeeInfoProvider = new MockInfo();
  var recommender = new Recommender(coffeeInfoProvider);
  var ideas = recommender.TastiestBlends(Seattle(), Morning());
  Assert.IsLessThan(4, ideas.Count());
}</pre>
<p>Your tests pass, you do the obligatory dance-around-the-office celebration, but now you crave more: your tests should also pass against real data. You want your tests to be prim &amp; proper and run against mock implementations in the everyday world, but have the occasional wild night against live implementations.</p>
<h1>Introducing two-face</h1>
<p>Here is how I usually give a wild side to my tests: first I make the test class an abstract base class, with an abstract method to get the concrete implementation of the dependent system:</p>
<pre><strong>protected abstract CoffeeInfoProvider NewCoffeeInfoProvider();</strong>

[TestMethod]
public void GoodNumberOfMorningRecommendations()
{
  var coffeeInfoProvider = <strong>NewCoffeeInfoProvider()</strong>;
  var recommender = new Recommender(coffeeInfoProvider);
  var ideas = recommender.TastiestBlends(Seattle(), Morning());
  Assert.IsLessThan(4, ideas.Count());
}</pre>
<p>I keep all of the actual tests in the base class, and I then create two thin derived classes that just implement this abstract method differently: the mock one that just returns a mock implementation:</p>
<pre>public class MockCBlendaTests : BaseCBlendaTests
{
  protected override CoffeeInfoProvider NewCoffeeInfoProvider()
  {
    return new MockCoffeeInfoProvider();
  }
}</pre>
<p>And a live one that either creates a real implementation based on configured information, or skips the tests if not configured for that:</p>
<pre>public class LiveCBlendaTests : BaseCBlendaTests
{
  protected override CoffeeInfoProvider NewCoffeeInfoProvider()
  {
    var credentials = TestConfiguration.GetCoffeeInfoProviderCredentials();
    if (credentials == null)
      Assert.Inconclusive("Skipping live tests because we're not configured for it.");
    return new CoffeeInfoProvider(credentials);
  }
}</pre>
<p>(See <a href="http://blogs.msdn.com/b/mostlytrue/archive/2014/07/04/living-on-the-edge-testing-without-mocking-part-1.aspx">part 1</a> for my discussion of this TestConfiguration). And voila: I just need to enter my credentials to the web service in a config file whenver I want to test against a live system, the mock tests always run, and I can keep all the tests that don't care about which implementation they go against in one clear place.</p>
<p>Luckily all the test systems I've tried this against (NUnit, JUnit and MSTest) all have the necessary ingredients to make this work: they don't choke on abstract base test classes, and they have a way of skipping the test in the running of it.</p>
<p>This pattern has for the most part served me well. There are a couple of drawbacks though:</p>
<ol>
<li>It doesn't enforce running the live tests regularly. Ideally it'd be coupled with a continuous build system that does run the tests with live credentials at regular intervals, otherwise we're at the mercy of my and my team's discpline to actually run them when needed (which of course is always an excellent idea to depend on my discipline...).</li>
<li>Visual Studio at least doesn't differentiate in its UI that much between the two versions of the tests: you sort of see two results for a test called <code>BaseCBlendaTests.GoodNumberOfMorningRecommendations</code>, which can be confusing on which one is the mock and which is the live. It's a bit annoying but it never hurt me too much.</li>
</ol>]]></content:encoded>
    </item>
    <item>
      <title>Come in - have some Blue Coffee</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/come-in-have-some-blue-coffee</link>
      <pubDate>Tue, 15 Jul 2014 15:06:00 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2014/07/15/come-in-have-some-blue-coffee/</guid>
      <description><![CDATA[Initial sips
There's an explosion of awesome OSS projects happening in the big data analysis space...]]></description>
      <content:encoded><![CDATA[<h1>Initial sips</h1>
<p>There's an explosion of awesome OSS projects happening in the big data analysis space now. A big chunk of them follow a similar pattern: they're released as Apache projects under the <a href="http://apache.org/">Apache Software Foundation</a>, they are typically written in Java or at least a JVM language like Scala, and even though the JVM is platform-independent they are typically developed and tested on Linux with helper scripts written in bash and/or Python. Over in Redmond, a bunch of us in Microsoft thought about all the ways our customers can use these tools on Azure, and as a result we have a few ways already including:</p>
<ol>
<li>You can use <a href="http://azure.microsoft.com/en-us/services/hdinsight/">HDInsight</a>, which offers a bunch of these tools in a convenient managed service: Hadoop (Yarn, MapReduce), Hive, Pig, HBase, ...</li>
<li>You can provision <a href="http://azure.microsoft.com/en-us/documentation/articles/introduction-linux/">a linux VM</a> in Azure (yes, we'll still love you), or a bunch of them, and deploy your favorite services in there. You can even use your favorite automation tools such as <a href="http://www.getchef.com/partners/microsoft/">Chef</a> to automate that deployment.</li>
</ol>
<p>These are all excellent and supported avenues, and if they serve your needs you should definitely pursue them. However, some of us started thinking about how it would look like to run these tools in an <a href="http://azure.microsoft.com/en-us/documentation/services/cloud-services/">Azure cloud service</a>. I started experimenting with code to deploy and run some of these projects as worker roles in Azure services, and in the spirit of openness I put these experiments <a href="https://github.com/mooso/BlueCoffee">up on GitHub</a> and as <a href="https://www.nuget.org/packages/Microsoft.Experimental.Azure.JavaPlatform/">NuGet</a> <a href="https://www.nuget.org/packages/Microsoft.Experimental.Azure.Cassandra/">packages</a>. This is very much still in the early experimentation phase, but in this post I wanted to show you how you can use these packages to deploy a <a href="http://cassandra.apache.org/">Cassandra</a> cluster in Azure in your own cloud service. My hope is that those of you who love living on the bleeding edge will try it and give us thoughts/feedback on how useful this seems, general approach and whatever else you have.</p>
<h1>Adventurous gulps (tutorial)</h1>
<p>So let's walk through creating a web site that uses our own Cassandra cluster as a backing data store. To follow along, you'll need Visual Studio (I'm using VS 2013 Ultimate because I work at Microsoft and they don't mind giving us our own software, but I think Express should work), the Azure SDK, and ideally an Azure subscription, though you can just debug it on the Azure Emulator locally.</p>
<ol>
<li>First, create a new Cloud project. Add a worker role named CassandraNode, and an ASP.Net web role called FrontEnd. To simplify things I chose a simple Web Forms template with no authentication.</li>
<li>Install the Azure.Cassandra NuGet package. In the Package Manager Console window:
<pre>Install-Package Microsoft.Experimental.Azure.Cassandra -IncludePrerelease -ProjectName CassandraNode</pre>
</li>
<li>The CassandraNode role will need some local storage resources. Right-click on the CassandraNode role in the cloud project, Properties, Local Storage, and add two resources: an InstallDir sized 256 MB, and a DataDir sized 1024 MB.</li>
<li>It will also need to expose some TCP ports for communication. In the same properties page, in the Endpoints tab, expose three Internal endpoints: Storage at port 7000, RPC at port 9160 and NativeTransport at port 9042.</li>
<li>Put the following code as the definition of your WorkerRole class for the CassandraNode role:
<pre>public class WorkerRole : RoleEntryPoint
{
  private CassandraNodeRunner _runner;
  public override void Run()
  {
    _runner.Run();
  }
  public override bool OnStart()
  {
    var installDir = RoleEnvironment.GetLocalResource("InstallDir").RootPath;
    var dataDir = RoleEnvironment.GetLocalResource("DataDir").RootPath;
    var javaInstaller = new JavaInstaller(Path.Combine(installDir, "Java"));
    javaInstaller.Setup();
    var nodes =
      RoleEnvironment.CurrentRoleInstance.Role.Instances.Select(
        i =&gt; i.InstanceEndpoints.First().Value.IPEndpoint.Address.ToString());
    var config = new CassandraConfig(
      clusterName: "AzureCluster",
      clusterNodes: nodes,
      dataDirectories: new[] { Path.Combine(dataDir, "Data") },
      commitLogDirectory: Path.Combine(dataDir, "CommitLog"),
      savedCachesDirectory: Path.Combine(dataDir, "SavedCaches")
    );
    _runner = new CassandraNodeRunner(
      jarsDirectory: Path.Combine(installDir, "Jars"),
      javaHome: javaInstaller.JavaHome,
      logsDirctory: Path.Combine(dataDir, "Logs"),
      configDirectory: Path.Combine(installDir, "conf"),
      config: config);
    _runner.Setup();
    return base.OnStart();
  }
}
</pre>
This code should setup Cassandra on startup, placing the OpenJDK and the Cassandra jar files in the Install directory, and configuring Cassandra to connect with the rest of the role nodes in a cluster and putting its data in the data directory.</li>
<li>Now that we're done with the Cassandra role, let's play with it! Let's create a web site to store all the myths about Cassandra. First, we need to interface with Cassandra. To do that, we'll use the NuGet package CassandraCSharpDriver to work with it:
<pre>Install-Package CassandraCSharpDriver -ProjectName FrontEnd</pre>
</li>
<li>Now add the following two classes to store/retrieve our data from Cassandra:
<pre>public class Myth
{
  public string Name { get; set; }
  public string Description { get; set; }
}

public static class Myths
{
  private static Lazy&lt;ISession&gt; _session =
    new Lazy&lt;ISession&gt;(InitSession);
  private static Lazy&lt;PreparedStatement&gt; _insertStatement =
    new Lazy&lt;PreparedStatement&gt;(PrepareInsertStatement);

  public static void AddMyth(Myth myth)
  {
    var bound = _insertStatement.Value.Bind(myth.Name, myth.Description);
    _session.Value.Execute(bound);
  }

  public static IEnumerable&lt;Myth&gt; GetAllMyths()
  {
    return _session.Value.Execute("SELECT * FROM allmyths")
      .Select(r =&gt; new Myth()
      {
        Name = (string)r["name"],
        Description = (string)r["description"]
      });
  }

  private static PreparedStatement PrepareInsertStatement()
  {
    return _session.Value.Prepare(
      "INSERT INTO allmyths(name, description) VALUES (?, ?)");
  }

  private static ISession InitSession()
  {
    var cassandraRole = RoleEnvironment.Roles["CassandraNode"];
    var cassandraHosts = cassandraRole.Instances.Select(
      i =&gt;
        i.InstanceEndpoints.First().Value.IPEndpoint.Address).ToArray();
    var builder = Cluster.Builder()
      .AddContactPoints(cassandraHosts)
      .WithPort(9042)
      .WithDefaultKeyspace("myths");
    var cluster = builder.Build();
    var session = cluster.ConnectAndCreateDefaultKeyspaceIfNotExists();
    session.Execute(
      "CREATE TABLE IF NOT EXISTS allmyths(" +
      "name text PRIMARY KEY, description text)");
    return session;
  }
}
</pre>
This code sets up a session with Cassandra (after discovering its nodes), creates a keyspace and table for the data, and inserts/retrieves data from there.</li>
<li>Finally just add some UI. Since I'm not exactly the world's foremost expert on web UI, I'll be light on details here: Add a web form called "AddMyth.aspx" with a couple of TextBox controls, and the submit button with this simple logic:
<pre>Myths.AddMyth(new Myth()
{
  Name = NameText.Text,
  Description = DescriptionText.Text
});
Response.Redirect("Default.aspx");
</pre>
And then add a web form called "ShowMyths.aspx", with the following simple GridView:
<pre>&lt;asp:GridView id="AllMyths" runat="server"
  DataSourceID="MythsDataSource" /&gt;
&lt;asp:ObjectDataSource ID="MythsDataSource"
  runat="server"
  SelectMethod="GetAllMyths" TypeName="FrontEnd.Myths"
/&gt;
</pre>
And then link to both forms from Default.aspx.</li>
<li>If you're going to test it in the cloud, you need to make Cassandra a multi-node cluster. So either increase the node count in the UI properties for the Cloud configuration for the CassandraNode role, or just edit this in the ServiceConfiguration.Cloud.cscfg file directly:
<pre>&lt;role name="CassandraNode"&gt;
  &lt;instances count="3" /&gt;
</pre>
</li>
</ol>
<p>And we're done! You can launch this web site in the debugger on your local Compute emulator and things should work, and/or deploy it to the cloud and see Cassandra operating in Azure. If it doesn't work, you can set the Diagnostics level to "All information" in the properties page for the CassandraNode role, and check out the logs from Cassandra in the WADLogsTable in your storage account to see what went wrong.</p>
<h1>So... what other flavors have you got?</h1>
<p>Hope this gave you a taste of how to run Cassandra as a cloud service in Azure using this (though I have to emphasize again: this is experimental, and if you want a supported way please just install a supported distribution of Cassandra on Azure VM's). Other than Cassandra, I also have packages to help deploy <a href="http://kafka.apache.org/">Apache Kafka</a> and <a href="http://zookeeper.apache.org/">Apache ZooKeeper</a>. I'm also hoping to start putting other packages in there, as well as testing and making sure this approach is resilient to all the failure modes that happen in the cloud. If this all sounds particularly interesting to you, I'd love to hear your thoughts so please leave a comment on this post.</p>]]></content:encoded>
    </item>
    <item>
      <title>Living on the edge - testing without mocking (Part 1)</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/living-on-the-edge-testing-without-mocking-part-1</link>
      <pubDate>Fri, 04 Jul 2014 13:12:00 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2014/07/04/living-on-the-edge-testing-without-mocking-part-1/</guid>
      <description><![CDATA[You must be mocking me
In this day &amp; age of SaaS and everything cloud, a lot of us rarely write...]]></description>
      <content:encoded><![CDATA[<h1>You must be mocking me</h1>
<p>In this day &amp; age of SaaS and everything cloud, a lot of us rarely write code in isolation anymore. Our code is always getting a live twitter feed, using Skynet's machine learning service to analyze it for dangerous human rebellions, and reacting on the results by calling into the appropriate crowd control REST API's. And if we want to test our code to make sure it always terminates the appropriate targets, conventional wisdom tells us to introduce a mocking layer for all the services we depend on, and then test our code against fake versions of those services.</p>
<p>I agree with conventional wisdom for the most part: not only does this save us from having to kill a bunch of people everytime we test the rebellion scneario, it also saves money (Skynet is pretty expensive), helps make our tests fast and reliable (they don't fail everytime twitter is down or our internet is spotty), and helps us cover edge cases and error conditions in ways that would be very difficult to do if we're testing against real services. There are many mocking frameworks to help you do this (I'm partial to <a href="https://github.com/Moq/moq4">Moq</a> for .NET and <a href="https://code.google.com/p/mockito/">Mockito</a> for Java), and of course just good patterns of having abstract base classes and concrete implementations that either go to the live service or a fake one (though be careful of putting too much code in the live service class: this is code that won't be tested and it's a bad code smell).</p>
<p>But, and of course you knew this was coming, I also think that testing our code against live services is immensely useful, either in conjunction with testing against mocks or even sometimes instead of it. In this short series I want to discuss some patterns and practices I picked up along the way to do this, and some of my learnings so far.</p>
<h1>What I want</h1>
<p>There are various things one wants when living on the edge like that to get the <s>thrill</s> benefits of testing against live services while still getting most of the convenience, safety and cost-effectiveness of testing with mocking:</p>
<ol>
<li><strong><em>Secrets should never go into source control.</em></strong> This applies whether you're in a <a href="https://github.com/blog/1390-secrets-in-the-code">public GitHub repo</a> or in your company's super-safe code vault. Ideally, whatever patterns we come up with should make it hard to accidentally check-in a secret (account key, password, etc.) in the normal course of testing, even for a junior member in our team who's just learning the ropes.</li>
<li><em>Tests should run in isolation.</em> Even if we're all using the company's credit card to pay for our live services, ideally we should all be able to run our tests on separate machines without having to yell out over our cubicles: "I'M STARTING A RUN NOW - NOBODY DARE START ONE WHILE I'M RUNNING MINE."</li>
<li><em>Tests should clean up resources.</em> Especially for expensive resources like VM's in the cloud or pizza orders, no test run should end up with artifacts around consuming money (unless I guess you're working for an evil corporation - in which case by all means stick it to them). The challenge here is that almost by definition these tests will run with buggy code, so our cleanup mechanisms ideally should be as resilient as possible to these pesky bugs.</li>
<li><em>Live tests should be easy to run.</em> Nobody wants to run your tests, including you. So if running your test involves secret incantations and arcane rituals nobody will run them.</li>
</ol>
<h1>The test.conf file pattern</h1>
<p>This is one of my favorite patterns, and one I've seen in many projects so I'm most definitely not inventing it (I'd credit original inventor but most likely this is just one of those organically developed things). I've personally seen it more ingrained in the Java and C++ worlds than the C# world for some reason: that's just my very subjective observation, but since this is my blog I'll base on it the decision to target my example to the C# crowd.</p>
<p>The basic idea of the pattern is to put all the information about the live services you want to use for testing (including secrets) into a file or a set of files that are read by the tests and used to connect to the services. The files are never checked into source control, and whoever wants to run the tests needs to fill in the information into those files before running them. There are other ways I've seen of passing this info around for tests: e.g. environment variables, registry settings, command-line parameters and of course the dreaded hard-coded value in the unit test that you need to edit. I personally have come to prefer the conf file pattern since having these things in a file makes them so much easier to save, copy, and generally manage (in a secure way of course) than any of the other options I've seen.</p>
<h2>Getting the test.conf file</h2>
<p>The first hurdle you have to pass when implementing this pattern is where to get this file. I've seen several options:</p>
<ol>
<li>Expecting the file in the same directory as the binaries: this is cumbersome because you'd have to leave your IDE and put the file there (and this directory can be different e.g. if you're running Debug vs. Retail binaries), and also because you nuke this file whenever you nuke your binaries directory for a really clean build.</li>
<li>Expecting the file in a well-known location such as the user's profile: this is not a bad option, but a) it clutters my machine and b) different source enlistments all use the same file, which can be a bad thing (but can also be a good thing).</li>
</ol>
<p>The last option as I said isn't bad, but my current personal favorite (for C# projects) is to have the file in a special directory in the enlistment (I usually call it TestConf) and embed this file as a resource. So my enlisment is usually organized something like:</p>
<pre>|- Source
   |- EmergencyPizzaProcurement
   |- EmergencyPizzaProcurement.Tests
|- TestConf
</pre>
<p>(Note that TestConf is not checked in). And then in my project file (.csproj) for the test project, I'd have a link to it like:</p>
<pre>&lt;ItemGroup&gt;
  &lt;EmbeddedResource Include="..\..\TestConf\PizzaVendors.txt"&gt;
    &lt;Link&gt;PizzaVendors.txt&lt;/Link&gt;
  &lt;/EmbeddedResource&gt;
&lt;/ItemGroup&gt;
</pre>
<p>Of course this means that in a new enlistment people would have to manually create this directory and file in order to build that, which contradicts my easy-to-run desirable. To circumvent that, I add an MSBuild step to create this directory and file if they don't exist:</p>
<pre>&lt;Target Name="BeforeBuild" Outputs="..\..\TestConf\PizzaVendors.txt"&gt;
  &lt;MakeDir Condition="!Exists('..\..\TestConf')"
    Directories="..\..\TestConf" /&gt;
  &lt;WriteLinesToFile
    Condition="!Exists('..\..\TestConf\PizzaVendors.txt')"
    File="..\..\TestConf\PizzaVendors.txt"
    Lines="# List of URL's for pizza vendors to use (one per line)"
    Encoding="Ascii" /&gt;
&lt;/Target&gt;
</pre>
<p>This nicely doubles as a place to put simple instructions for the format of the file. Finally, in my test code I'd have a helper method to get me the configured information:</p>
<pre>public static IEnumerable&lt;string&gt; ReadConfigurationFile(string name,
  bool skipCommentLines = true, bool skipEmptyLines = true)
{
  using (Stream resourceStream =
    typeof(TestConfiguration).Assembly.GetManifestResourceStream(
    "EmergencyPizzaProcurement.Tests." + name + ".txt"))
  {
    StreamReader reader = new StreamReader(resourceStream);
    string currentLine;
    while ((currentLine = reader.ReadLine()) != null)
    {
      currentLine = currentLine.Trim();
      if (skipCommentLines &amp;&amp; currentLine.StartsWith("#")) // Comment
      {
        continue;
      }
      if (skipEmptyLines &amp;&amp; currentLine == "")
      {
        continue;
      }
      yield return currentLine;
    }
    reader.Close();
  }
}
</pre>
<h2>Avoiding these files in source control</h2>
<p>As I hope I've stressed enough by now (among many others who've stressed it before me), these files should never go into source control. I'm usually using git these days, and luckily this makes it easier to avoid having these files sneak in there: I just add a line in my <a href="https://www.kernel.org/pub/software/scm/git/docs/gitignore.html">.gitignore</a> file to always ignore these files when using <code>git add</code>:</p>
<pre># Test configuration
TestConf/</pre>
<h2>Format of the file</h2>
<p>My overriding concern when writing these files is that they should be human-readable and editable. Since these are typically targeted at myself and my coworkers, I don't care about making them super-robust or generic. So I typically avoid XML or JSON, and just opt for simple text files and create several of them instead of worrying about sections. This also works because they're usually simple and just contain enough information to connect to the live services (see below).</p>
<h2>I thought you hated configurable code...</h2>
<p><a href="http://blogs.msdn.com/b/mostlytrue/archive/2014/04/15/on-configurable-code.aspx">I definitely do.</a> And in general I hate seeing this mechanism (or similar ones) used for evil by making the tests configurable, e.g. having the test read how many files it should create to test with from a configuration file definitely veers into the dark side as far as I'm concerned. The test configuration here should just specify enough info to be able to connect to live services, no more no less. I'm only calling it test configuration because I'm not very imaginative with names, but I'm hoping to find a better name and start calling it that in the future.</p>
<p>And that's all I have to say about this pattern. In the next post I'll talk about other patterns for writing such edgy tests, but I'd love your feedback on this as usual (I'm still learning best practices here so I'd love to hear what works for you).</p>]]></content:encoded>
    </item>
    <item>
      <title>Misadventures in immutability</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/misadventures-in-immutability</link>
      <pubDate>Mon, 12 May 2014 07:33:00 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2014/05/12/misadventures-in-immutability/</guid>
      <description><![CDATA[My infatuation
Starting I think a few years ago, I began to heavily drink the immutability...]]></description>
      <content:encoded><![CDATA[<h1>My infatuation</h1>
<p>Starting I think a few years ago, I began to heavily drink the immutability kool-aid. I started getting oddly satisfied whenver I saw a class like this:</p>
<pre>public sealed class WeatherState
{
   private readonly float _temperature; // In Celsius of course
   private readonly float _windSpeed; // km/h
   ...
}
</pre>
<p>With this kind of class, if I have to write a <code>SatisfactionMeter</code> class that calculates anyone's happiness for this weather, I can simply write</p>
<pre>public sealed class SatisfactionMeter
{
   private readonly WeatherState _weather;

   public SatisfactionMeter(WeatherState weather)
   {
      _weather = weather;
   }
   ...
}
</pre>
<p>and not worry about having to clone the <code>WeatherState</code> input object in case someone decides the weather is hotter now in the middle of my calculation. If in this class I have this method:</p>
<pre>   public int GetSatisfaction(Person subject)
   {
      return _allCritera
        .Sum(criterion =&gt; criterion.EvaluateFor(subject, _weather));
   }
</pre>
<p>I can speed up my calculation on my multi-core machine by simply adding an <code>AsParallel</code> in there (assuming Person is nicely immutable as well):</p>
<pre>      return _allCritera
        .AsParallel()
        .Sum(criterion =&gt; criterion.EvaluateFor(subject, _weather));
</pre>
<p>and not worry if somewhere deep in the analysis code some clever code decides to do what-if analysis by changing the temperature up and down thus messing up other threads' calculations in weird and wonderful ways.</p>
<p>Anyway: people much smarter than me have extolled the virtues of immutability for a while now so go read their explanations if you want to learn more, but this is just to say that I was smitten and wanted this goodness whenever I can get it.</p>
<h1>Love in C# land</h1>
<p>While C# is no Haskell, a subset of said smart people mentioned above have been steadily making it much easier to reap the benefits of this style of programming:</p>
<ol>
<li>You can't mark a class as immutable, but you can mark fields as readonly and most (all?) primitive and basic library types are immutable so in practice I didn't miss that too much.</li>
<li>The <a href="https://www.nuget.org/packages/Microsoft.Bcl.Immutable">Immutable Collections library</a> has been heavenly, and even though it's still a beta nuget package I've personally been using it in almost all my projects since I found it and have had no problems at all with it.</li>
<li>Even auto-properties are going to get immutability-favoring features in <a href="http://msdn.microsoft.com/en-us/magazine/dn683793.aspx">C# 6</a>, thus hopefully correcting my pet peeve with everyone using auto-properties with private setters as if that was an equivalent way of having readonly fields (it's not - methods in the class can still mutate those properties).</li>
<li>And of course all the parallelism goodness that came after around .Net 3.5 (<a href="http://msdn.microsoft.com/en-us/library/dd460688(v=vs.110).aspx">PLINQ</a>, <a href="http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx">TPL</a>, ...) has made it much more lucrative to program in an immutable style and very easily get the parallelism advantages out of it.</li>
</ol>
<p>So overall my love affair with immutability has been mostly untroubled in C#, except for our ever-going fight with complex data structures...</p>
<h1>Brewing troubles</h1>
<p>My first seeds of doubt that maybe immutability is a bit of a phase for me, and like everyone going through a phase I'm annoying the people around me by taking it too far, were sown when I wrote a relatively big library/toolset that revolved around a complex data structure (a description of a test run, including what tests to run, how to set up their environment, what parameters they take, etc.). Since I started writing it mostly on my own I indulged in my new-found love and made it all immutable, which proved more complex than I thought. To illustrate the problems, let me take the weather example from above a little further. Let's say I want to write a weather predictor, and I realize that the easiest way to predict tomorrow's weather without those pesky weather models is to take today's weather and just add/subtract a few degrees. So to make the job of my predictor even easier, I decide to add a new method to the <code>WeatherState</code> class that just returns the same weather but with a different temperature: <code></code></p>
<pre>  public Weather ChangeTemperature(int newTemperature)
  {
    return new Weather(newTemperature, _windSpeed);
  }
</pre>
<p><code></code> And right away there are already a few problems:</p>
<ol>
<li><em>The method name:</em> If you're reading this method in an article about immutability, you may not have trouble recognizing that <code>ChangeTemperature</code> returns a new object with a new temperature. But if you're trying to use a new library and discover a method called <code>ChangeTemperature</code> on the object you're using, it's not a far stretch to think that this method actually changes the temperature in your object so you just use it like that (as if it's a setter). Which is exactly what happened when people started using my library: it became a fairly common bug for people to ignore the new returned value from the ChangeX() methods and just assume that the method changes the existing object. Now with the benefit of hindsight I don't think I would have named them ChangeX(), but to this day I don't have a great name pattern for this - maybe WithNewX? (e.g. WithNewTemperature()). Also in my defence even some base library methods suffer from this confusion: I'm sure many people fell into the trap of calling <a href="http://msdn.microsoft.com/en-us/library/fk49wtc1(v=vs.110).aspx"><code>String.Replace()</code></a> on a string thinking it replaced it in-place, instead of taking the return object as the new string.</li>
<li><em>The method implementation:</em> The implementation is a one-liner, but it's not exactly as simple as implementing a setter. You have to pass in all the members of the class to the new constructor except what you're changing, which is definitely more complex and error-prone than <code>{ _temperature = value; }</code> (and it's the reason I have this method in the first place, instead of having client code just use the constructor directly to achieve the same effect). And it gets progressively worse as the class gets bigger.</li>
</ol>
<p>Now, partially to address the second problem, I began to aggressively nest my classes to keep them from having too many members. So in this example let's say we wanted to add the wind direction to the weather state: instead of adding it as a new member, I would bundle it up with wind speed into a new <code>WindVelocity</code> class, and add that to the <code>WeatherState</code> class. Now the <code>WeatherState</code> class still only has two members (temperature and wind velocity), and everything is tidy and awesome.</p>
<p>Except of course that's when my real trouble began: let's say we want to predict tomorrow's weather as the same as today except with stronger wind. So I want to add a method to change wind speed. Now there are two ways I can do this:</p>
<ol>
<li>I can add a <code>WeatherState.ChangeWindSpeed()</code> method which creates a new velocity object with the new wind speed and returns the new weather state object or</li>
<li>I can add a <code>WindVelocity.ChangeSpeed()</code> method and a <code>WeatherState.ChangeWindVelocity()</code> method, and leave it to the client code to first construct the new wind velocity object then use that to create the new weather state object.</li>
</ol>
<p>Neither option is pretty. The first one means that my highest level class will have way too many methods, and is also a weird violation of abstraction levels (why should the weather state object understand the speed concept in the velocity object? it's an internal detail of the workings of velocity). The second one leads to pretty verbose client code: <code></code></p>
<pre>  var tomorrowsWeather = todaysWeather.ChangeWindVelocity(
    todaysWeather.WindVelocity.ChangeSpeed(
      todaysWeather.WindVelocity.Speed + 5));
</pre>
<p><code></code> In the end I settled on the second option, mainly because I'm a sadistic monster who doesn't care about the suffering of the users of my library. But even my cruel heart was moved a little by their plight...</p>
<h1>Uneasy truce</h1>
<p>Annoyingly, I don't have any real conclusions to this post. The whole experience left me with a vague feeling that surely languages can and should evolve to improve the situation here: after all this is almost purely a syntactic complexity not a conceptual one, so the language should help me out here. But I have no idea how I would do it if I were a language designer, which I guess is why I'm not a language designer.</p>
<p>And until such time as languages make these problems moot - will I still make my data structures immutable? Probably. I still love all the goodness that comes with immutability, and am not willing to give that up. I'll try to name my methods better to avoid confusion, but honestly I still don't have good solutions to the problem of changing a deeply nested member. So if you have any thoughts I'd love to hear them.</p>]]></content:encoded>
    </item>
    <item>
      <title>WASB back stories: Masquerading a key-value store</title>
      <link>https://docs.microsoft.com/archive/blogs/mostlytrue/wasb-back-stories-masquerading-a-key-value-store</link>
      <pubDate>Tue, 22 Apr 2014 04:57:05 GMT</pubDate>
      <dc:creator><![CDATA[Mostafa Elhemali MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mostlytrue/2014/04/22/wasb-back-stories-masquerading-a-key-value-store/</guid>
      <description><![CDATA[There are a few excellent articles out there already that introduce the concept of Azure Blob...]]></description>
      <content:encoded><![CDATA[<p>There are a <a href="http://azure.microsoft.com/en-us/documentation/articles/hdinsight-use-blob-storage/">few</a> excellent <a href="http://blogs.msdn.com/b/cindygross/archive/2013/04/25/access-azure-blob-stores-from-hdinsight.aspx">articles</a> out there already that introduce the concept of Azure Blob Storage and how it's accessed from HDInsight. In this post though I wanted to start giving some backstage looks at some of the decisions we made while exposing blobs to HDInsight, hopefully answering a tiny part of the oft-asked question "what the hell was Microsoft thinking when they came up with this @#$?" My focus today will be on the mismatch between key-value stores and hierarchical file systems, with a vague hope of addressing some other topics such as concurrency and URL choices in later posts.</p>
<h1>The problem</h1>
<p>Azure Blob Storage, like <a href="http://aws.amazon.com/s3/">Amazon S3</a> and <a href="https://cloud.google.com/products/cloud-storage/">Google Cloud Storage</a> and I'm sure other data storage systems in the cloud and on Earth, takes a nice simple do-one-thing-well approach: give me a bunch of bits and a name within a namespace, and I'll associate these bits with that name for you to ask for it later. In the case of Azure, the bunch of bits is called a blob and the namespace is called a container (within a storage account). The bits could be a video stream or an XML document, the name could be "Plan for next billion $.docx" or "My consciousness.vhd" and it all looks the same as far as storage is concerned. In particular though: the name could be "I\am\a\directory\with\a\file" or it could be "Psht/this/is/what/a/directory/looks/like" and it would still be treated as a plain old name in blob storage, since in the storage service itself these "\" and "/" characters have no special meaning and are just like "a" or "$". This is not true of the <a href="http://msdn.microsoft.com/en-US/library/azure/microsoft.windowsazure.storage.blob.cloudblobdirectory(v=azure.10).aspx">SDK</a> and some of the <a href="http://clumsyleaf.com/products/cloudxplorer">tools</a> on top of the service, but they are all providing their own illusions on top of a simple flat name-value store, just like we needed to provide our own illusion...</p>
<p>The problem is that Hadoop wants its backing file system to be a <em>hierarchical</em> file system, with the <a href="http://en.wikipedia.org/wiki/Directory_(file_systems)">directory</a> structure we've all grown familiar with and fond of. So we needed to code up our WASB FileSystem class (this is the code that presents the Azure Storage service as a FileSystem implementation in Hadoop) to bridge the two worlds in a way that:</p>
<ol>
<li>Presents the hierarchical system abstractions as faithfully as possible with (as much as possible) no cracks through which our abstraction leaks. This is important not just for theoretical purity, but as we painfully learned through trial and error because any leaks in our abstraction can cause various Hadoop ecosystem components to break in strange and wondrous ways...</li>
<li>Enables customers to analyze data in blob store that they obtained through common tools outside HDInsight.</li>
</ol>
<h1>The approach</h1>
<p>Given the requirements, the most obvious approach is to do what the SDK and most tools over Azure storage do: if Hadoop asks us to store the file "Trip Durations.csv" in the directory "Buses" within the top-level directory "Seattle", then we just store it as the blob "Seattle/Buses/Trip Durations.csv". Then when Hadoop asks us to list all the files in the directory "Seattle/Buses", we looks for all blobs whose names start with the prefix "Seattle/Buses/" (and whose names don't contain "/" after that) and we return those, taking everything after the last "/" as the file name. And if it asks us to list all directories under "Seattle", we'll look for all blobs whose names start with the prefix "Seattle/" and whose names <em>do</em> contain "/" after that, find all the distinct directory names (sandwiched between the "/" characters) and return those: e.g. if we find "Seattle/Buses/Trip Durations.csv", "Seattle/Buses/Ridership.csv" and "Seattle/Bikes/Trip Durations.csv" then the two directories we return are "Buses" and "Bikes". Easy (sort-of).</p>
<p>But of course life can't be that easy. The first major problem comes when Hadoop does something like this:</p>
<p><em>Tricky case 1</em></p>
<pre>Create directory "Cars" under "Seattle"
List all directories under "Seattle"</pre>
<p>The trickiness here comes from the fact that we want to create (and see) an empty directory. The scheme above doesn't allow for that: we typically would know that there is a directory called "Cars" once we see a blob called "Seattle/Cars/Pollution.csv" but we have no blob called that yet. We liked the basic approach, so we considered two ways to supplement and salvage it:</p>
<ol>
<li>Create a special catalog blob per container that records such facts as the existence of empty directories.</li>
<li>Create a special marker blob per directory that we create.</li>
</ol>
<p>We decided against the first approach mainly because of contention problems when many machines are creating/deleting directories all over the place and want to record this in the one blob. So we turned to the second, and now our problem became how do we mark these special blobs. Our first attempt (which some people saw in our very early previews) was to create empty blobs with a special suffix "_$folder$", which worked OK but its main drawback (aside from its ugliness when viewed outside HDInsight) was that it led to the following situation being possible:</p>
<p><em>Tricky case 2</em></p>
<pre>(In Hadoop) Create directory "Thoughts" and put file "Brilliance" in there with very important thoughts
(Oustide Hadoop) Create blob "Thoughts" with very important thoughts in there
(In Hadoop) Tell me whether "Thoughts" is a directory or a file</pre>
<p>With our implementation so far, the third step would be stumped: we have three blobs in there, "Thoughts_$folder$", "Thoughts/Brilliance" and "Thoughts", so the concept "Thoughts" is both a file and a directory! Of course we could error out, but we weren't very fond of that because a well-meaning customer could find themselves in that situation, with data in there to analyze and no simple remedy. Ideally we would've stopped the customer in the second step before the data is placed so they could place it in a consistent manner in the first place. So for this and other reasons, we decided to move to our current implementation: we create the marker blob as an empty blob with the exact name of the directory and no ugly suffixes, and mark it instead using attached <a href="http://msdn.microsoft.com/en-us/library/dd179414.aspx">metadata</a> called "hdi_isfolder". So now the second step in case 2 above becomes nicely blocked: the customer would get an obvious conflict and would have to stubbornly delete the marker blob before creating the new "Thoughts" blob and shooting herself in the foot.</p>
<h1>Other wrinkles</h1>
<p>With the approach above of honoring the standard "this/is/a/directory/with/a/file" naming convention and using special metadata-marked blobs to create empty directories we were mostly OK. We hit some interesting situations though during implementation and testing, so for fun here is my favorite:</p>
<p><em>Tricky case 3</em></p>
<pre>(Outside Hadoop) Create the blob "Songs/Get Lucky"
(In Hadoop) Check if the directory "Songs" exists
(In Hadoop) Delete the file "Songs/Get Lucky"
(In Hadoop) Check if the directory "Songs" exists</pre>
<p>The correct behavior is to answer "Yes" both times we check if the directory exists: the first time because we decided to honor the naming convention and say that the existence of the blob "Songs/Get Lucky" implies the directory "Songs", and the second time because we already said the directory exists and didn't delete it so it should still exist (normal file systems don't delete a directory just because the last file is deleted). But the na&iuml;ve implementation of our approach would not yield this behavior: our implementation would dutifully perform the complex "Check for prefix or marker blob" check in the second step and correctly answer "Yes", then in the third step delete the blob "Songs/Get Lucky", then in the fourth step say "No" since now the container is completely empty.</p>
<p>To deal with this (and other quirks) we codified the concepts of "materialized" and "implicit" directories: a materialized directory is one where we have the special marker blob, and an implicit one is one we infer from the existence of blobs that have it as a prefix (i.e. an implicit directory "Songs" exists because of the existence of the blob "Songs/Get Lucky"). Then whenever we delete a file, we check if its parent directory is implicit or materialized: if it's implicit, we materialize it first before we delete the file then the situation above would be resolved.</p>
<p>Note that we could've dealt with this situation in the second step instead: when we check for directory existence, we always materialize it if necessary before answering "Yes". The main reason we didn't do that is that we honor read-only operations: Azure Storage allows customers to give read-only permissions on a container to an HDInsight cluster (through the use of <a href="http://msdn.microsoft.com/en-us/library/ee395415.aspx">Shared Access Signature</a> keys), so if we're doing a read-only operation like checking for directory existence, we avoid doing any write operations such as materializing a directory. When deleting a file though we assume we have write-access so we give ourselves leeway to do that.</p>]]></content:encoded>
    </item>
  </channel>
</rss>