<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Learn Amazon Web Services</title>
	<atom:link href="http://learnaws.com/feed" rel="self" type="application/rss+xml" />
	<link>http://learnaws.com</link>
	<description>The Amazon cloud, explained.</description>
	<pubDate>Fri, 07 Aug 2009 22:53:23 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Guests, fish and EC2 instances start to smell after 3 days</title>
		<link>http://learnaws.com/archives/244</link>
		<comments>http://learnaws.com/archives/244#comments</comments>
		<pubDate>Fri, 07 Aug 2009 22:53:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=244</guid>
		<description><![CDATA[3 days is probably an overstatement, but I think keeping an EC2 instance around for a long time is a bad habit.
Most developers don&#8217;t like to think that their software leaks memory, resources, etc, but in fact it most likely does. Even if the software that you wrote does not leak, keep in mind the [...]]]></description>
			<content:encoded><![CDATA[<p>3 days is probably an overstatement, but I think keeping an EC2 instance around for a long time is a bad habit.</p>
<p>Most developers don&#8217;t like to think that their software leaks memory, resources, etc, but in fact it most likely does. Even if the software that you wrote does not leak, keep in mind the system your software runs on top of may leak.</p>
<p>I think there are about 200K lines of code (LOC) that make up Xen, the virtualization platform that Amazon uses, 500K LOC or so for the Java VM (if you are using Java) and 2.5M LOC for a typical distribution of Linux. That is a lot of software - surely there will be memory and resource leaks somewhere in there.</p>
<p>If there are leaks, the system will degrade over time. The longer you keep the system running, the slower it will get. EC2 makes this really easy to solve - just kill your instance every so often and launch a new fresh instance. This means you should be using custom AMIs, EBS and or S3 to store your data of course.</p>
<p>To ensure your application appears to the outside world as a stable system, you&#8217;ll need to use Elastic Load Balancing, or at least Elastic IP to create a stable fascade on top of your ever-changing EC2 instances.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/244/feed</wfw:commentRss>
		</item>
		<item>
		<title>3 reasons why EC2 should be more expensive than a real server?</title>
		<link>http://learnaws.com/archives/239</link>
		<comments>http://learnaws.com/archives/239#comments</comments>
		<pubDate>Tue, 21 Jul 2009 01:29:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=239</guid>
		<description><![CDATA[As you probably know, Amazon Elastic Compute Cloud (EC2) offers a new way to purchase computing power - you rent a virtual server instance for 10 cents/hour versus buying an actual server.
The usual assumption is that EC2 should be cheaper than buying a real server. But, lately, I&#8217;ve been wondering why we make that assumption?
Below [...]]]></description>
			<content:encoded><![CDATA[<p>As you probably know, Amazon Elastic Compute Cloud (EC2) offers a new way to purchase computing power - you rent a virtual server instance for 10 cents/hour versus buying an actual server.</p>
<p>The usual assumption is that EC2 should be cheaper than buying a real server. But, lately, I&#8217;ve been wondering why we make that assumption?</p>
<p>Below are 3 reasons why I think EC2 should actually be more expensive than a real server.</p>
<ol>
<li><strong>Convenience</strong> - even the fastest hardware vendor will take days if not weeks to deliver a new server. With EC2, you can have as many servers as you would like, and they will be ready in a few minutes. We are accustomed to paying more for convenience like this (i.e. express shipping, home delivery, etc), so why should computing be any different?</li>
<li><strong>No buyer remorse </strong>- how often have you purchased the wrong server? Maybe it is more powerful than you need? Maybe it is less powerful than you need? Usually we just buy as much as we can afford and live with the consequences. With EC2, there is no buyer remorse. You can choose amongst a set of hardware archetypes to meet your needs - you are billed hourly, so you can literally &#8216;trade in&#8217; your server whenever you need to without any kind of penalty. That seems like a benefit that we often overlook.</li>
<li><strong>Portability </strong>- a real server might be close in cost or even cheaper in the long term than EC2. But, what happens if you need to move it to another data center? Or another continent? With EC2, you can move your server instance between zones (i.e. data centers) and regions (i.e. continents) with a few clicks of your mouse.</li>
</ol>
<p>Thanks!</p>
<p>Eric.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/239/feed</wfw:commentRss>
		</item>
		<item>
		<title>The original &#8216;Turk&#8217;</title>
		<link>http://learnaws.com/archives/236</link>
		<comments>http://learnaws.com/archives/236#comments</comments>
		<pubDate>Fri, 22 May 2009 21:45:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Add new tag]]></category>

		<category><![CDATA[Mechanical Turk]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=236</guid>
		<description><![CDATA[Hey guys,
Amazon&#8217;s Mechanical Turk is named after an 18th century machine named &#8216;Turk&#8217; that could beat all comers at chess. You can read a nice write up about it here http://www.guardian.co.uk/technology/2009/may/21/answering-services
]]></description>
			<content:encoded><![CDATA[<p>Hey guys,</p>
<p>Amazon&#8217;s Mechanical Turk is named after an 18th century machine named &#8216;Turk&#8217; that could beat all comers at chess. You can read a nice write up about it here <a title="http://www.guardian.co.uk/technology/2009/may/21/answering-services" href="http://www.guardian.co.uk/technology/2009/may/21/answering-services" target="_blank">http://www.guardian.co.uk/technology/2009/may/21/answering-services</a></p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/236/feed</wfw:commentRss>
		</item>
		<item>
		<title>A little about myself&#8230;</title>
		<link>http://learnaws.com/archives/226</link>
		<comments>http://learnaws.com/archives/226#comments</comments>
		<pubDate>Wed, 22 Apr 2009 19:56:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=226</guid>
		<description><![CDATA[Hey guys,
A friendly reader made an interesting comment about how I sound somewhat secretive when I sign-off on my posts. That was really never my intention, I was actually just trying to sound casual. So, in light of that, I thought I would share a little about myself.
A little history about myself &#8230;
I was born [...]]]></description>
			<content:encoded><![CDATA[<p>Hey guys,</p>
<p>A friendly reader made an interesting comment about how I sound somewhat secretive when I sign-off on my posts. That was really never my intention, I was actually just trying to sound casual. So, in light of that, I thought I would share a little about myself.</p>
<p>A little history about myself &#8230;</p>
<p>I was born in the <a href="http://www.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=moscow+idaho&amp;sll=37.0625,-95.677068&amp;sspn=52.902929,114.257812&amp;ie=UTF8&amp;z=13&amp;iwloc=A" target="_blank">Moscow, ID, USA</a>, but I was raised mostly in a small, Canadian city named <a href="http://www.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=windsor+ontario+canada&amp;sll=46.732362,-117.001363&amp;sspn=0.090361,0.22316&amp;ie=UTF8&amp;z=12&amp;iwloc=A" target="_blank">Windsor</a>. I attended the <a href="http://www.uwo.ca" target="_blank">University of Western Ontario</a>, where I studied Computer Science.</p>
<p>I started my professional career in a small company in Toronto called <a href="http://www.klg.com" target="_blank">KL Group</a> working in technical support. KL Group was one of the first companies to produce commercial user interface components for Motif. I&#8217;m sure I&#8217;m dating myself, but Motif is a toolkit for X-Windows, a graphical user interface package used in my UNIX distributions. KL Group eventually introduced components for the then-new Java JDK; this was an area that I worked in as well.</p>
<p>I learned a tremendous amount working for KL Group. Technical support is not the most glamorous position, but boy do you ever learn a lot! Since KL Group built user interface components, the customers I supported were mostly developers who were integrating these components into their applications. Looking back, I think the reason I learned so much from this job is that I was forced to solve problems that I had absolutely on influence in designing. IMHO, when you&#8217;re writing code yourself, you can influence the sorts of problems you have to solve because you get to choose (to some degree) - the programming language, the execution environment, the platform, etc. In some cases, as a developer, if you hit a really tough problem, you can find a way around it.</p>
<p>But, in technical support, I didn&#8217;t have that option - I had to work with whatever environment, design, etc the customer already had in place. Not to mention there is always a severe time crunch because usually calling technical support is the last resort our customers took.</p>
<p>Anyways, KL Group was a great learning experience for me.  After finishing my CS degree, I joined Microsoft.</p>
<p>At the time, Windows and Microsoft software was actually quite unfamiliar for me. My university and KL Group were both primarily UNIX and Java. It&#8217;s funny to say this now, but at the time I didn&#8217;t even own a PC <img src='http://learnaws.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> my only experience with a PC and Windows was from using a PC X windows server at KL Group.</p>
<p>My first job with Microsoft was in their Developer Tools Division - I really love developer tools and would spend most of my 8-year career here. I worked initially in quality assurance for Visual Studio. Quality assurance is another position that is not very glamorous, but is a great learning experience. When you&#8217;re charged with finding bugs in software, you get a really good idea of how software should be built.</p>
<p>I eventually left my beloved Developer Division to work as a developer in Windows 2003 - I was part of the team that worked on UDDI. If I remember correctly, we had the distinction of being the first .NET feature in Windows 2003, as well as one of the first web service related products.</p>
<p>UDDI was great fun, but after a while I realized that Developer Tools was where my heart was. I returned as a program manager for the profiler feature in Visual Studio Team System.  At Microsoft, feature teams are essentially made up of developers, testers and program managers. A lot has been said and written about program managers at Microsoft, so there isn&#8217;t much for me to add. This was an interesting position, but I&#8217;m not sure it was the best fit for me; but being a PM helped me get to my next position, which I think was the best fit for me.</p>
<p>My next and final stop at Microsoft was to be the product manager for Team Foundation Server - the server-side component to Visual Studio Team System. I really think this is where I did my best work at Microsoft. Being a product manager is a combination of many skills - coding, speaking, evangelizing, planning, etc. I spent about 2 years traveling the world telling people about this new product.</p>
<p>While I loved my job, after 2 years or so I decided it was time to move on. I&#8217;ve always had the dream of starting my own business, so in late 2006 I decided to do that.</p>
<p>I started a small consulting company named CounterPunch Software. My business was basically training, custom development and building product demonstrations. My legal company name is still CounterPunch Software, but in 2008 I decided to rename my company as WonderAffect. I thought this name better reflected the product demonstration related work that I was doing.</p>
<p>Building product demonstrations led me to Amazon Web Services. I loved using AWS for quickly spinning up computers to host demos on. Even when I was building Windows-based demonstrations, I often used SQS, SimpleDB and S3 for storage and communication.</p>
<p>I&#8217;ve made use of AWS since 2006 or so and decided to concentrate on it as part of my business. Recently, I started this web site to blog about subjects in AWS that are of interest to me. I also do training, development and consultation for Amazon Web Services.</p>
<p>If you want to see what I&#8217;m up to, check out:<a href="http://www.learnaws.com" target="_blank"> www.learnaws.com</a> and <a href="http://www.wonderaffect.com">www.wonderaffect.com</a> I used to blog at <a href="http://blogs.counterpunchsoftware.com" target="_blank">blogs.counterpunchsoftware.com</a>, but I haven&#8217;t posted there in quite some time.</p>
<p>Finally, here is what I look like (granted it is a glammed-up profile shot :)):</p>
<p><img class="aligncenter size-full wp-image-227" title="photo" src="http://learnaws.com/wp-content/uploads/2009/04/photo.jpg" alt="photo" width="152" height="231" /></p>
<p>Well that&#8217;s all I can think of to share right now; if anyone has any questions, please feel free to ask.</p>
<p>Thanks!</p>
<p>Eric Lee.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/226/feed</wfw:commentRss>
		</item>
		<item>
		<title>Dreamhost.com offers integrated Amazon CloudFront support!</title>
		<link>http://learnaws.com/archives/219</link>
		<comments>http://learnaws.com/archives/219#comments</comments>
		<pubDate>Wed, 15 Apr 2009 19:17:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=219</guid>
		<description><![CDATA[Dreamhost is my favorite hosting company - they are cheap and offer you all kinds of good stuff. I just noticed that they now also offer integrated Amazon CloudFront.

And as an added bonus, they are running a Tax Day sale today!
]]></description>
			<content:encoded><![CDATA[<p>Dreamhost is my favorite hosting company - they are cheap and offer you all kinds of good stuff. I just noticed that they now also offer integrated Amazon CloudFront.</p>
<p><img class="aligncenter size-full wp-image-221" title="picture-67" src="http://learnaws.com/wp-content/uploads/2009/04/picture-67.png" alt="picture-67" width="214" height="349" /></p>
<p>And as an added bonus, they are running a Tax Day sale today!</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/219/feed</wfw:commentRss>
		</item>
		<item>
		<title>Lessons learned from the other side of the pond&#8230;</title>
		<link>http://learnaws.com/archives/207</link>
		<comments>http://learnaws.com/archives/207#comments</comments>
		<pubDate>Wed, 15 Apr 2009 00:18:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=207</guid>
		<description><![CDATA[I just returned from a training trip in London and Paris; I had the privilege of meeting some really great people and had a lot of fun doing the training. Still shaking the cobwebs of jet lag out of my head though 
I often feel I learn as much from the training as my students [...]]]></description>
			<content:encoded><![CDATA[<p>I just returned from a training trip in London and Paris; I had the privilege of meeting some really great people and had a lot of fun doing the training. Still shaking the cobwebs of jet lag out of my head though <img src='http://learnaws.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
I often feel I learn as much from the training as my students do. On this particular trip, a few issues and points of interest were raised so I thought I would summarize a few of them in this blog.</p>
<p><span style="text-decoration: underline;"><strong>EC2 Reserved Instance Pricing is now available for the EU region</strong></span></p>
<p>Similar to a futures market for computing power, EC2 Reserved Instances are a great way to lock in a price; now it is available in Europe.</p>
<blockquote><p>We are excited to announce that Amazon Elastic Compute Cloud (Amazon EC2) Reserved Instances are now available in Europe. Reserved Instances give you the option to make a low, one-time payment for each instance you want to reserve and in turn receive a significant discount on the hourly usage charge for that instance. After the one-time payment for an instance, that instance is reserved for you, and you have no further obligation; you may choose to run that instance for the discounted usage rate for the duration of your term, or if and when you do not use the instance, you will not pay usage charges on it.</p>
<p>Please visit  <a href="http://aws.amazon.com/ec2">http://aws.amazon.com/ec2</a> for more information on Reserved Instances, including pricing for the Europe Region.</p></blockquote>
<p><span style="text-decoration: underline;"><strong>VAT and tax help</strong></span></p>
<p>Helpful tax info (including some information related to VAT) can be found here: <a href="http://aws.amazon.com/tax-help/" target="_blank">http://aws.amazon.com/tax-help/</a></p>
<p><span style="text-decoration: underline;"><strong>SQS is now available in the EU</strong></span></p>
<p>This is really new, Simple Queue Service is now available in the EU region - <a href="http://aws.amazon.com/about-aws/whats-new/2009/04/09/announcing-amazon-sqs-wsdl-version-2009-02-01-and-amazon-sqs-in-europe/" target="_blank">http://aws.amazon.com/about-aws/whats-new/2009/04/09/announcing-amazon-sqs-wsdl-version-2009-02-01-and-amazon-sqs-in-europe/.</a></p>
<p><span style="text-decoration: underline;"><strong>Handling Amazon Web Services Disputes</strong></span></p>
<p>This is not the most pleasant thing to talk about, and I don&#8217;t think there have been any major disputes so far, but European AWS users should note section #14 in the user agreement (<a href="http://aws.amazon.com/agreement/" target="_blank">http://aws.amazon.com/agreement/</a>) about how disputes are handled.</p>
<blockquote><p><em><strong>14. Disputes</strong></em></p>
<p><em><strong>14.1.</strong> Notwithstanding anything to the contrary, we may seek injunctive or other relief in any state, federal, or national court of competent jurisdiction for any actual or alleged infringement of Amazon’s or any third party’s intellectual property and/or proprietary rights. Any dispute relating in any way to your visit to the <span class="caps">AWS</span> Website or to products or services sold or distributed by <span class="caps">AWS</span> or its affiliates in which the aggregate total claim for relief sought on behalf of one or more parties exceeds <strong>$7,500 shall be adjudicated in any state or federal court in King County, Washington, and you consent to exclusive jurisdiction and venue in such courts.</strong> You further acknowledge that our rights in the Amazon Properties are of a special, unique, extraordinary character, giving them peculiar value, the loss of which cannot be readily estimated and may not be adequately compensated for in monetary damages.</em></p>
<p><em><strong>14.2. Governing Law.</strong> By using the Services, you agree that the laws of the State of Washington, without regard to principles of conflicts of laws, will govern this Agreement and any dispute of any sort that might arise between you and us. The parties expressly exclude application of the United Nations Convention for the International Sale of Goods to this Agreement.</em></p></blockquote>
<p><span style="text-decoration: underline;"><strong>Service Level Agreements</strong></span></p>
<p>This is not specific to Europe of course, but it came up during the training so I thought I would try and gather the various SLA information.</p>
<p>The SLA for EC2 can be found here <a href="http://aws.amazon.com/ec2-sla/" target="_blank">http://aws.amazon.com/ec2-sla/</a>, here are some highlights:</p>
<blockquote><p><em><span class="caps">AWS</span> will use commercially reasonable efforts to make Amazon <span class="caps">EC2</span> available with an Annual Uptime Percentage (defined below) of at least <strong>99.95%</strong> during the Service Year.  In the event Amazon <span class="caps">EC2</span> does not meet the Annual Uptime Percentage commitment, you will be eligible to receive a Service Credit&#8230;</em></p></blockquote>
<p>The SLA for S3 can be found here <a href="http://aws.amazon.com/s3-sla/" target="_blank">http://aws.amazon.com/s3-sla/</a>, again here are some highlights:</p>
<blockquote><p><em><span class="caps">AWS</span> will use commercially reasonable efforts to make Amazon S3 available with a Monthly Uptime Percentage (defined below) of at least <strong>99.9%</strong> during any monthly billing cycle (the “Service Commitment”). In the event Amazon S3 does not meet the Service Commitment, you will be eligible to receive a Service Credit&#8230;</em></p></blockquote>
<p>There is no SLA for SQS right now, but here are a few bits of information about security, usage, etc.</p>
<p>From the Amazon User Agreement:</p>
<p style="padding-left: 4em;"><em><strong>5.4.1.</strong> Provided that you comply with the terms of this Agreement and our policies and procedures for the use of Amazon <span class="caps">SQS</span>, you may use Amazon <span class="caps">SQS</span> in connection with data owned or lawfully obtained by you (such data, to the extent to which actually used in connection with Amazon <span class="caps">SQS</span>, “Your Amazon <span class="caps">SQS</span> Content”). You acknowledge that neither we nor our licensors are responsible in any manner, and you are solely responsible, for your Amazon <span class="caps">SQS</span>, <strong>we will not sell or license your Amazon <span class="caps">SQS</span> Content and will not disclose Your Amazon <span class="caps">SQS</span> Content except as we may determine to be necessary or desirable to comply with the Agreement, the request of a governmental or regulatory body, subpoenas or court orders, or for other legal purposes.</strong></em></p>
<p style="padding-left: 4em;"><em><strong>5.4.2.</strong> Your use of Amazon <span class="caps">SQS</span> is subject to the limits specified in the most recent user documentation, including limits on the available number of queues or messages, message size, and the number of days during which a message or inactive queue can be maintained. <strong>You may not knowingly create and maintain inactive queues.</strong> We may delete, without liability of any kind, any of your Amazon <span class="caps">SQS</span> Content that sits in a queue or any queue that remains inactive for more than the number of days specified in the user documentation.</em></p>
<p>Some relevant SQS FAQs (<a href="http://aws.amazon.com/sqs/faqs/" target="_blank">http://aws.amazon.com/sqs/faqs/</a>):</p>
<dl class="faq">
<blockquote><dt><em><strong> Q: How reliably is my data stored in Amazon <span class="caps">SQS</span>?</strong> Amazon <span class="caps">SQS</span> stores all queue and message information in Amazon’s network of highly reliable, highly available data centers. All messages are stored redundantly on multiple servers and in multiple data centers, which means that no single computer or network failure renders <span class="caps">SQS</span> messages inaccessible.</em> </dt>
</blockquote>
</dl>
<blockquote><p><em><strong> Q: How can I secure the messages in my queues?</strong> Authentication mechanisms are provided to ensure that messages stored in Amazon <span class="caps">SQS</span> queues are secured against unauthorized access. Only the <span class="caps">AWS</span> account owners can access the queues they create.</em></p>
<p><em>Amazon <span class="caps">SQS</span> uses proven cryptographic methods to authenticate your identity, either through the use of your Access Key ID and request signature, or through the use of an X.509 certificate. For the details of how to use either of these authentication mechanisms with Amazon <span class="caps">SQS</span>, please see the Amazon <span class="caps">SQS</span> Developer Guide.</em></p>
<dl class="faq">
<dt><em><strong>Q: What happens if there is no activity against a queue for an extended period of time?</strong> We reserve the right to delete a queue if none of the following requests have been issued against the queue for more than <strong>30 consecutive days</strong>: SendMessage, ReceiveMessage, DeleteMessage, GetQueueAttributes and SetQueueAttributes. You should design your application with this in mind. </em></dt>
</dl>
</blockquote>
<p>Since CloudFront is based on S3, there isn&#8217;t too much more to say in terms of SLA. One interesting thing to note, if you expect to serve a lot of content:</p>
<blockquote><p><em>By default, a customer’s Amazon CloudFront distributions support peak data transfer speeds of<strong> 1,000 megabits per second and peak request rates of 1,000 requests per second</strong>. If you expect more than this amount of traffic, please complete the form below. We will add more capacity to your distributions within 2 business days.</em></p></blockquote>
<p>The form mentioned in the quote above can be found here <a href="http://aws.amazon.com/cloudfront-request/" target="_blank">http://aws.amazon.com/cloudfront-request/</a></p>
<p>SimpleDB is still in beta so there is no SLA associated with it. Not too much to note about it - one blurb in the Amazon usage rights about old data being deleted after 6 months of inactivity.</p>
<p style="padding-left: 4em;"><em><strong>5.9.2.</strong> You must comply with the terms of the technical documentation applicable to (including the Amazon SimpleDB Developer Guide) as posted by us and updated by us from time to time on the <span class="caps">AWS</span> Website, including, without limitation, any limitations on the number and total size of domains, items and attributes that may be stored on the Amazon SimpleDB servers. <strong>We may delete, without liability of any kind, any of your Amazon SimpleDB Content that has not been accessed in the previous 6 months.</strong></em></p>
<p>That&#8217;s the major small-print stuff I wanted to point out. If I missed anything please let me know.</p>
<p>Thanks!</p>
<p>Eric.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/207/feed</wfw:commentRss>
		</item>
		<item>
		<title>Fun with Amazon Elastic MapReduce and TechCrunch.com</title>
		<link>http://learnaws.com/archives/162</link>
		<comments>http://learnaws.com/archives/162#comments</comments>
		<pubDate>Mon, 06 Apr 2009 04:13:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Featured]]></category>

		<category><![CDATA[EC2]]></category>

		<category><![CDATA[MapReduce]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=162</guid>
		<description><![CDATA[Hey guys,
Amazon recently announced a new service - Amazon Elastic MapReduce. This new service is basically an environment where Hadoop - the popular grid computing framework - is installed and ready to run jobs.
All you really need to do is write your job and choose how many instances you want in your grid.
I wrote an [...]]]></description>
			<content:encoded><![CDATA[<p>Hey guys,</p>
<p>Amazon recently announced a new service - <a href="http://aws.amazon.com/elasticmapreduce/" target="_blank">Amazon Elastic MapReduce</a>. This new service is basically an environment where Hadoop - the popular grid computing framework - is installed and ready to run jobs.</p>
<p>All you really need to do is write your job and choose how many instances you want in your grid.</p>
<p>I wrote an involved sample and write-up for this service based on the <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=2275&amp;categoryID=263" target="_blank">Freebase</a> data set, but this service is so easy to use I wanted to get another sample written as well.</p>
<p>A common use for grid computing frameworks like Hadoop is to use them to index web sites. It is commonly believed that Google uses Hadoop (or a framework like Hadoop) to create their massive search indexes.</p>
<p>I decided to do something similar on a much smaller scale. Like many people in technology, I like to read <a href="http://www.techcrunch.com" target="_blank">TechCrunch</a>. Part of the fun in reading that site is going through the comments; it is a very lively site, so there are literally dozens of comments per article.</p>
<p>I wanted to get an idea of who is posting the most comments; this kind of question is perfect for Amazon Elastic MapReduce.</p>
<p>The first thing I did was to use <a href="http://www.httrack.com/" target="_blank">HTTrack</a> to download TechCrunch.com to my local file system. I hope they didn&#8217;t mind the extra traffic - as far as I can tell HTTrack is pretty good about following robot guidance, so hopefully it wasn&#8217;t too much of a nuisance.</p>
<p>I actually started up a Windows EC2 instance and ran HTTrack from there; EC2 instances get to use Amazon&#8217;s network insfrastructure so the download was pretty fast. TechCrunch is a huge site, so it took about 8 hours to get the entire site down.</p>
<p>HTTrack downloads everything and replicates directory structures so that each link will work. This is great, but Amazon Elastic MapReduce (actually Hadoop) cannot traverse directories, so I needed a flat layout.</p>
<p>I wrote a small program to traverse into each directory created by HTTrack and look for HTML files. Each file that was found was given a unique name (a GUID) and copied into a flat directory.</p>
<p>Amazon Elastic MapReduce uses S3 for its input and output. So, my next step was to take my flat list of uniquely named HTML files and copy them into an S3 bucket. I used <a href="http://www.s3fox.net/">S3 Organizer</a> to do that. I ran this from my Windows EC2 instance as well since there were so many files - it took a few hours for the upload to finish.</p>
<p>With my files in S3, the fun with Amazon Elastic MapReduce starts. There are 2 ways to write jobs in Amazon Elastic MapReduce (and in Hadoop) - you can use streaming, or you can write a Java JAR.</p>
<p>I find streaming to be much easier. All you do is read from standard input and write to standard output; as a friendly reader pointed out, Amazon Elastic MapReduce supports a number of different languages.</p>
<blockquote><p>Develop your data processing application authored in your choice of Java, Ruby, Perl, Python, <span class="caps">PHP</span>, R, or C++. There are several code samples available in the <a href="http://docs.amazonwebservices.com/ElasticMapReduce/latest/GettingStartedGuide/">Getting Started Guide</a> that will help you get up and running quickly.</p></blockquote>
<p>In my experience, I&#8217;ve only used Ruby and Python for streaming jobs and they both worked well. I had some trouble with PHP during the private beta and have not had a chance to try it again.</p>
<p>I&#8217;m going to use Ruby for this example. The basic structure of a streaming job looks as shown below:</p>
<p><img class="aligncenter size-full wp-image-165" title="picture-33" src="http://learnaws.com/wp-content/uploads/2009/04/picture-33.png" alt="picture-33" width="450" height="198" /></p>
<p>Amazon ElasticMap Reduce is going to traverse the S3 bucket location we give it and give our code the contents of each file. Amazon ElasticMap Reduce will decide how many instances of our code it needs. We don&#8217;t have to worry about that in our code.</p>
<p>The code we are writing is called the mapper - essentially, we are taking raw input and outputting a structured format. Another chunk of code - called a reducer - will handle this structured output.</p>
<p>So what will our input look like? Since we are just handling the HTML files, our input will literally be the HTML pages that make up TechCrunch.com. As an example, let&#8217;s have a look at the page that announced Amazon Elastic MapReduce (<a href="http://www.techcrunch.com/2009/04/02/with-hadoop-amazon-adds-a-web-scale-file-system-to-its-cloud-computer/" target="_blank">http://www.techcrunch.com/2009/04/02/with-hadoop-amazon-adds-a-web-scale-file-system-to-its-cloud-computer/</a>)</p>
<p>We are interested in comment authors, so scroll down to the <strong>Comments </strong>section. I am using <strong><a href="https://addons.mozilla.org/en-US/firefox/addon/1843" target="_blank">FireBug</a> </strong>- a really handy tool for analyzing web pages - and it lets me right-click on an element and view its source.</p>
<p><img class="aligncenter size-full wp-image-167" title="picture-34" src="http://learnaws.com/wp-content/uploads/2009/04/picture-34.png" alt="picture-34" width="429" height="302" /></p>
<p>You can of course do a complete view source for the page, but that does not take into account dynamically generated (a la AJAX) source. FireBug works from the document object model, so it is able to show you AJAX-generated code.</p>
<p>Anyways, in our particular case I don&#8217;t think there is any dynamically generated HTML so it does not matter; but FireBug is a good tool to keep in mind.</p>
<p>The result of our inspection is <img class="aligncenter size-full wp-image-168" title="picture-35" src="http://learnaws.com/wp-content/uploads/2009/04/picture-35.png" alt="picture-35" width="556" height="117" /></p>
<p>We can see that our comment author value is contained in <strong>span </strong>tag that has a CSS class of <strong>comment_author vcard</strong>. In this particular case, there is a link to the author&#8217;s blog.</p>
<p>There are actually 3 variations in how the comment author is shown:</p>
<ol>
<li>There can be a link as shown above</li>
<li>There can be a link to their Facebook profile</li>
<li><img class="aligncenter size-full wp-image-169" title="picture-38" src="http://learnaws.com/wp-content/uploads/2009/04/picture-38.png" alt="picture-38" width="550" height="132" />There name can just be shown with no link</li>
</ol>
<p><img class="aligncenter size-full wp-image-172" title="picture-371" src="http://learnaws.com/wp-content/uploads/2009/04/picture-371.png" alt="picture-371" width="474" height="85" /></p>
<p>Our mapper code will handle each of these cases. Ruby has pretty convenient Regular Expressions, so we can define the patterns we are looking for ahead of time.</p>
<p><img class="aligncenter size-full wp-image-173" title="picture-40" src="http://learnaws.com/wp-content/uploads/2009/04/picture-40.png" alt="picture-40" width="788" height="140" /></p>
<p>The first pattern finds a comment author; the second pattern helps us narrow down whether we have a link in the name.</p>
<p>I&#8217;m not a regular expressions expert, so there may be a more efficient way to describe the pattern; with regular expressions there always seems to be a be <img src='http://learnaws.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The first part of our code is quite simple. We will take each line of input that we are given and try to match it with our regular expression.</p>
<p>If we get a match, we have a comment author.</p>
<p><img class="aligncenter size-full wp-image-175" title="picture-42" src="http://learnaws.com/wp-content/uploads/2009/04/picture-42.png" alt="picture-42" width="461" height="229" /></p>
<p>If we have a comment author, then we want to check to see if there is a link to the name (case #1 and #2) or if it is just the name (case #3).</p>
<p>We are going to test for case #3, that is the easiest to handle</p>
<p><img class="aligncenter size-full wp-image-176" title="picture-43" src="http://learnaws.com/wp-content/uploads/2009/04/picture-43.png" alt="picture-43" width="615" height="83" /></p>
<p>If this <strong>if </strong>statement evaluates to true, then we are just going to print out some structured output</p>
<p><img class="aligncenter size-full wp-image-177" title="picture-45" src="http://learnaws.com/wp-content/uploads/2009/04/picture-45.png" alt="picture-45" width="393" height="62" /></p>
<p>We will talk more about why the output looks that way. For now, our mapper code looks as shown below.</p>
<p><img class="aligncenter size-full wp-image-174" title="picture-41" src="http://learnaws.com/wp-content/uploads/2009/04/picture-41.png" alt="picture-41" width="634" height="358" /></p>
<p>Now let&#8217;s handle case #1 and #2. All we are doing is using our second regular expression to pull out the value behind the link. You&#8217;ll notice a little bit of a hack where I am removing the ending <strong>fb:name</strong> element. I couldn&#8217;t find an easy way to express that with a regular expression, so it seemed easy enough to just remove it afterwards.</p>
<p><img class="aligncenter size-full wp-image-178" title="picture-46" src="http://learnaws.com/wp-content/uploads/2009/04/picture-46.png" alt="picture-46" width="889" height="287" /></p>
<p>So, in both cases, we end up printing out a value like <strong>LongValueSum:Eric Lee 1</strong>. This is the output of the mapper.</p>
<p>In Amazon Elastic MapReduce (and in Hadoop in general), we process our data by using mappers and reducers. A simple explanation of how these work together is that the mapper makes some sense of the raw data, but it does not do any correlation. The reducer takes the output of the mapper and does the correlation.</p>
<p>In our case, our mapper is &#8216;making some sense of the data&#8217; by looking for the comment author values. There are lots of pages in TechCrunch that either do not have comments, or are simply not blog posts. This input gets filtered out by our mapper since nothing in it matches our search terms.</p>
<p>We can write a reducer, but Amazon Elastic MapReduce has a few standard reducers - one of which is called <strong>aggregate</strong>. The <strong>aggregate </strong>reducer takes output like <strong>LongValueSum:Eric Lee 1 </strong>and correlates it for us.</p>
<p>For example, if we were to parse through all of TechCrunch.com, we will have authors who have made several comments. So, our mapper will produce output like:</p>
<p><strong>LongValueSum:Eric Lee 1</strong></p>
<p><strong>LongValueSum:Eric Lee 1</strong></p>
<p><strong>LongValueSum:Eric Lee 1</strong></p>
<p><strong>LongValueSum:Eric Lee 1</strong></p>
<p>Remember, it is not the job of the mapper to do any correlation; just output structured data. If we use the default <strong>aggregate </strong>reducer, it will take this output and correlate it for us to produce:</p>
<p><strong>LongValueSum:Eric Lee 4</strong></p>
<p>I&#8217;m pretty lazy so I try to design my map reduce usage to use the default <strong>aggregate </strong>reducer as much as possible. It seems like most of the time, that type of correlation is really what you want anyways.</p>
<p>At this point we have our raw data from HTTrack, we have our mapper and we know we are going to use the default reducer. Let&#8217;s do a quick test before we send all of this to Amazon Elastic MapReduce.</p>
<p>Of course, we can test our code by installing Hadoop on our local system and running a job. But, one of the reasons that I like streaming jobs so much is that they are easy to test; to do a simple sanity test, we don&#8217;t need a local installation of Hadoop.</p>
<p>For testing purposes, I downloaded a few of the HTTrack files to my local system.</p>
<p><img class="aligncenter size-full wp-image-179" title="picture-47" src="http://learnaws.com/wp-content/uploads/2009/04/picture-47.png" alt="picture-47" width="405" height="211" /></p>
<p>Amazon Elastic MapReduce is going to take each of these files and send them to my mapper. I can mimic this by using <strong>cat </strong>(on Mac/Linux) or <strong>type </strong>(Windows).</p>
<p><img class="aligncenter size-full wp-image-180" title="picture-48" src="http://learnaws.com/wp-content/uploads/2009/04/picture-48.png" alt="picture-48" width="553" height="45" /></p>
<p>If I run this command, all of my files will be outputted to standard output; now we just have to point this to our mapper. We can do that by using the pipe (<strong>|</strong>) command.</p>
<p><img class="aligncenter size-full wp-image-181" title="picture-49" src="http://learnaws.com/wp-content/uploads/2009/04/picture-49.png" alt="picture-49" width="770" height="32" /></p>
<p>This simulation is good enough for a quick sanity test of our mapper - if we run it, we should see our structured output.</p>
<p><img class="aligncenter size-full wp-image-182" title="picture-50" src="http://learnaws.com/wp-content/uploads/2009/04/picture-50.png" alt="picture-50" width="475" height="204" /></p>
<p>In the little snippet above, we can see a few cases where our reducer will do some correlation for us. Your results will vary based on your test data.</p>
<p>At this point we are ready to use Amazon Elastic MapReduce.</p>
<p>The first step is to upload our code into S3 - I use S3 Organizer to create some sub-directories to help me organize my code.</p>
<p><img class="aligncenter size-full wp-image-183" title="picture-51" src="http://learnaws.com/wp-content/uploads/2009/04/picture-51.png" alt="picture-51" width="321" height="117" /></p>
<p>This is where I ran into a little confusion. As you might know, in S3, there is no such thing as hierarchies. All buckets are essentially peers and in each bucket there are objects. There is no such thing as buckets within buckets.</p>
<p><strong>But</strong>, S3 Organizer allows you to use a <strong>/ </strong>in your object names to mimic a directory structure in the UI. This is purely a UI trick - in reality, your S3 data is all flat.</p>
<p>What can be a little confusing is that all of the samples in Amazon Elastic MapReduce use this nomenclature. It&#8217;s actually pretty handy once you get used to it, but it is a little confusing at first.</p>
<p>Creating a job in Amazon Elastic MapReduce is really easy. First, you go to the console <a href="https://console.aws.amazon.com/elasticmapreduce/home" target="_blank">https://console.aws.amazon.com/elasticmapreduce/home</a></p>
<p>Sign-up for the Amazon Elastic MapReduce service if you haven&#8217;t already done so.</p>
<p>Once you&#8217;ve signed in, create a new job by clicking the <strong>Create New Job Flow </strong>button.</p>
<p><img class="aligncenter size-full wp-image-163" title="picture-32" src="http://learnaws.com/wp-content/uploads/2009/04/picture-32.png" alt="picture-32" width="386" height="302" /></p>
<p>This brings up a dialog box that will define your new job.</p>
<p>The name of the job does not really matter, pick anything you want and press the <strong>Continue </strong>button.</p>
<p>The next page is where you configure your job; take a deep breath at this point. The data you are entering is not difficult, but you can&#8217;t make any typos here. There is limited checking in the dialog, you really just have to get all of the values right.</p>
<p>The first piece of data is the input location - this is the S3 bucket where your raw HTTrack flat files are. I use S3 Organizer to navigate to the location and then cut and paste the value.</p>
<p><img class="aligncenter size-full wp-image-185" title="picture-52" src="http://learnaws.com/wp-content/uploads/2009/04/picture-52.png" alt="picture-52" width="369" height="188" /></p>
<p>Amazon Elastic MapReduce does not want the leading /, so the value I put into the input location is <strong>learnaws-mapreduce/data/techcrunch/</strong><br />
Make sure to enter your value exactly as shown in S3 Organizer (minus the leading slash); this includes the trailing slash.</p>
<p><img class="aligncenter size-full wp-image-186" title="picture-53" src="http://learnaws.com/wp-content/uploads/2009/04/picture-53.png" alt="picture-53" width="532" height="177" /></p>
<p>I know I&#8217;m probably beating you over the head about not making any typos - the reason is that when you start your job, there is a fair bit of overhead that Amazon Elastic MapReduce will go through. This overhead usually takes about 5 minutes to complete. There are a lot of typo-related errors that are not caught until after this overhead is complete - so you might have to wait 5 minutes before your job fails because of a simple typing mistake.</p>
<p>The second location is your output location. This is just a bucket location in S3 that you have created. The trick here is that it must be a location that does not exist yet. Amazon Elastic MapReduce will not overwrite your output, so if you give it a location that already exists, it will fail.</p>
<p>Using S3 Organizer again, here is how I organize my output.</p>
<p><img class="aligncenter size-full wp-image-187" title="picture-54" src="http://learnaws.com/wp-content/uploads/2009/04/picture-54.png" alt="picture-54" width="229" height="133" /></p>
<p>As you can see, I have a few output locations already (i.e. tc_comments_3, tc_comments_2, etc). The value I specify in the dialog will be a new location (i.e. tc_comments_4).</p>
<p><img class="aligncenter size-full wp-image-188" title="picture-55" src="http://learnaws.com/wp-content/uploads/2009/04/picture-55.png" alt="picture-55" width="525" height="191" />It makes sense to double-check your values at this point. The input location has to exist, the output location cannot exist yet. Both location paths should have a trailing /.</p>
<p>OK, enough nagging about typos <img src='http://learnaws.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> now we specify the location of our mapper code. It is just a direct path to our S3 object.</p>
<p><img class="aligncenter size-full wp-image-189" title="picture-56" src="http://learnaws.com/wp-content/uploads/2009/04/picture-56.png" alt="picture-56" width="261" height="158" /></p>
<p>Our value in the dialog box should be:</p>
<p><img class="aligncenter size-full wp-image-190" title="picture-57" src="http://learnaws.com/wp-content/uploads/2009/04/picture-57.png" alt="picture-57" width="522" height="257" />Lastly, we specify our reducer. If we wrote our own reducer, then we would just give it a S3 path to the code. But since we are using a default one, we just specify the name - <strong>aggregate</strong><br />
<img class="aligncenter size-full wp-image-191" title="picture-58" src="http://learnaws.com/wp-content/uploads/2009/04/picture-58.png" alt="picture-58" width="517" height="229" /></p>
<p>That&#8217;s all the data we need for our job - one more time, double check your values and then press the <strong>Continue </strong>button.</p>
<p>The next page lets you choose how big of a cluster you want to process your data; feel free to keep the default or choose your own value. I used 8 instances of the default small variety to process the TechCrunch data. The processing took about 2 hours to complete.</p>
<p>Press the <strong>Continue </strong>button when you have chosen your setup. This should bring you to the last page of the dialog box; press the <strong>Create Job Flow </strong>dialog to create and run your job.</p>
<p>If all goes well, your job should complete in a couple of hours.</p>
<p>Amazon Elastic MapReduce and Hadoop are hiding a fair bit of complexity from us. Our small mapper Ruby script will be instantiated a number of times across the number of machines we chose. Hadoop figures out the optimal number of mappers to run in parallel based on the input we give it. Amazon Elastic MapReduce handles the work of instantiating the number of machines (EC2 instances) behind the scenes for us. Since there are a number of mapper instances writing to standard output, it helps to have a low-latency file system to handle all this output. Hadoop can use a few different distributed file systems (including its own). But, Amazon Elastic MapReduce configures Hadoop to use a S3-based distributed file system.</p>
<p>Again, all of this complexity is hidden from us. We can just sit back (or walk away) and let the processing complete.</p>
<p><img class="aligncenter size-full wp-image-192" title="picture-59" src="http://learnaws.com/wp-content/uploads/2009/04/picture-59.png" alt="picture-59" width="973" height="172" /></p>
<p>For some funny reason, I felt some odd sense of accomplishment in keeping 8 computers busy for about 2 hours <img src='http://learnaws.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The data that will be generated is stored at your output location in S3.</p>
<p><img class="aligncenter size-full wp-image-193" title="picture-60" src="http://learnaws.com/wp-content/uploads/2009/04/picture-60.png" alt="picture-60" width="405" height="297" /><br />
I did some experimentation with running another job to process this output and store it into SimpleDB. It was an interesting exercise, but ultimately I decided it was wrong for this example.</p>
<p>I downloaded these results to my local file system - there really isn&#8217;t all that much data once it has been correlated. Here is a snippet from one of those files.</p>
<p><img class="aligncenter size-full wp-image-194" title="picture-61" src="http://learnaws.com/wp-content/uploads/2009/04/picture-61.png" alt="picture-61" width="399" height="362" /></p>
<p>You can see that our reducer has done the correlation for us - there are some authors with 100+ comments!</p>
<p>Now the question becomes - how to visualize this data? I&#8217;m sure there are many different ways of visualizing a large data set. I chose a relatively simple one.</p>
<p>I decided to use a tag cloud type of interface.</p>
<p><img class="aligncenter size-full wp-image-195" title="tagcloudgenerator_screenshot" src="http://learnaws.com/wp-content/uploads/2009/04/tagcloudgenerator_screenshot.gif" alt="tagcloudgenerator_screenshot" width="317" height="236" /></p>
<p>I found one to use at <a href="http://www.phpclasses.org/browse/package/4158.html" target="_blank">http://www.phpclasses.org/browse/package/4158.html</a> written by a gentleman named <a href="http://www.rochakchauhan.com/" target="_blank">Er. Rochak Chauhan</a>.</p>
<p>This code can be configured to read from a CSV file; the format of the CSV is <strong>tag, url, count</strong></p>
<p>This is really close to the format that I already have from Amazon Elastic MapReduce; basically all we need to do is replace the TAB with a comma and put in a URL.</p>
<p>I used another Ruby script to do this.</p>
<p><img class="aligncenter size-full wp-image-196" title="picture-62" src="http://learnaws.com/wp-content/uploads/2009/04/picture-62.png" alt="picture-62" width="476" height="239" /></p>
<p>I didn&#8217;t feel like doing anything too fancy - all this script does is take our Amazon Elastic MapReduce output from standard input, convert the tabs to commas, put in a blank URL and spit the result to standard output.</p>
<p>I ran this script as:</p>
<p><img class="aligncenter size-full wp-image-197" title="picture-63" src="http://learnaws.com/wp-content/uploads/2009/04/picture-63.png" alt="picture-63" width="764" height="34" /></p>
<p>This produces 1 giant CSV file that we can use with the tag generator.</p>
<p>The tag generator is well written and easy to understand. It is PHP-based, so we just need to run it on a web server that supports PHP. I use <a href="http://www.apachefriends.org/en/xampp.html" target="_blank">XAMPP</a> on the Mac.</p>
<p>The only changes we need to make are to copy the CSV file to the same location as <strong>example.php </strong>and change the name of the CSV file being referenced.</p>
<p><img class="aligncenter size-full wp-image-198" title="picture-64" src="http://learnaws.com/wp-content/uploads/2009/04/picture-64.png" alt="picture-64" width="777" height="197" /></p>
<p>Then, we can request this page (i.e. http://localhost/comments/example.php) to produce our tag cloud (click on the image below to see it full size).</p>
<p style="text-align: center;"><a href="http://learnaws.com/wp-content/uploads/2009/04/picture-31.png"><img class="aligncenter size-thumbnail wp-image-199" title="picture-31" src="http://learnaws.com/wp-content/uploads/2009/04/picture-31-150x150.png" alt="picture-31" width="150" height="150" /></a></p>
<p style="text-align: left;">To summarize our application, we did the following:</p>
<ol>
<li>Use HTTrack to download our web site</li>
<li>Flattened out the resulting directory structure and gave each HTML file a unique name</li>
<li>Uploaded it all to S3</li>
<li>Wrote our Ruby mapper</li>
<li>Created an Amazon Elastic MapReduce job</li>
<li>Downloaded our resulting output</li>
<li>Found a handy tag cloud generator</li>
<li>Wrote a bit more Ruby to convert our output into a format our tag cloud generator understands</li>
</ol>
<p>That&#8217;s about it!</p>
<p>Amazon Elastic MapReduce makes doing this type of processing really easy - if you are using a streaming job, you are really just reading from standard input and printing to standard output. You can request as big of a cluster as you need, so no job is literally too big.</p>
<p>Everything we did from the web-based UI can also be done from an API. Like all of the Amazon Web Services, this new service has an XML web service based API. A Ruby client is included in the resources to get you started right away. Check out <a href="http://aws.amazon.com/elasticmapreduce/" target="_blank">http://aws.amazon.com/elasticmapreduce</a> for more details.</p>
<p>Thanks!</p>
<p>Eric.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/162/feed</wfw:commentRss>
		</item>
		<item>
		<title>Storing data in EC2 images</title>
		<link>http://learnaws.com/archives/159</link>
		<comments>http://learnaws.com/archives/159#comments</comments>
		<pubDate>Tue, 24 Mar 2009 20:15:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=159</guid>
		<description><![CDATA[In general, there are 3 ways of storing data in an EC2 instance that persists after terminating it:

Bundled AMIs
EBS volumes
S3

Most people use a combination of these 3; I&#8217;ll describe the basic use cases for each:
Let&#8217;s use a Windows EC2 instance as an example. Suppose you want to host a web site on your instance.
The first [...]]]></description>
			<content:encoded><![CDATA[<p>In general, there are 3 ways of storing data in an EC2 instance that persists after terminating it:</p>
<ol>
<li>Bundled AMIs</li>
<li>EBS volumes</li>
<li>S3</li>
</ol>
<p>Most people use a combination of these 3; I&#8217;ll describe the basic use cases for each:</p>
<p>Let&#8217;s use a Windows EC2 instance as an example. Suppose you want to host a web site on your instance.</p>
<p>The first thing you do is install IIS on your instance. As you probably know, if you terminate this instance, the installation you did prior will be gone.</p>
<p>In order to keep this installation, you need to bundle it into an AMI. As you&#8217;ve seen, the console makes quick work of this, you can right-click and in a few minutes you will have your AMI.</p>
<p>When you start up that AMI, the installation of IIS you made will still be there (note - only the C:\ is saved, not the D:\).</p>
<p>If you put your web files in the default IIS directory (i.e. C:\inetpub\wwwroot), then they will be saved as well.</p>
<p>So, you can save everything you need by just bundling. But, there are 2 drawbacks to only doing bundling:</p>
<ol>
<li>Bundles are limited to 10GB in total size. This includes the base operating system. So, you have a fixed limit to how much data you can put in your instance.</li>
<li>The only way to save changes to your instance is by bundling again. Bundling is pretty easy, but probably not something you want to often (i.e. daily) basis.</li>
</ol>
<p>What is really common to do is to bring EBS volumes into the mix. As you&#8217;ve seen, you can mount an EBS volume like a regular hard drive and see it as E:\ or something.</p>
<p>What a lot of people then do is use EBS volumes to store their data - so you could use set IIS to use E:\inetpub\wwwroot instead. Any change you make to data in an EBS volume is saved pretty much immediately.</p>
<p>It is probably more common to see databases being hosted on EBS - so I might configure SQL Server to store its databases on E:\ instead of C:\. Any change to the database is permanently saved.</p>
<p>So, EBS gives you a few advantages:</p>
<ol>
<li>No need to re-bundle to save instance data</li>
<li>No 10GB limit, you can store as much as you want.</li>
</ol>
<p>But there are a few drawbacks with EBS as well.</p>
<p>1. You pay for an EBS volume based on allocation. When you create an EBS volume of 100 GB for example, you immediately start paying for that space, whether you actually have data stored there are not.</p>
<p>2. EBS volumes are conceptually like USB-powered portable hard drives. They are easy to plug-into a computer (or instance), but you can&#8217;t share them with another computer simultaneously. You can duplicate the contents of an EBS volume by creating a snapshot and then creating a new volume based on that snapshot, but the sharing is not in real-time.</p>
<p>The last option is S3.</p>
<p>With S3, you put your data into buckets that are Internet-accessible. So, what you might do is put your web site contents in a .zip file in a S3 bucket. When an instance starts up, it is configured to pull down that data from S3 and unzip it onto its local (or EBS) volume.</p>
<p>With S3, you get a few advantages:</p>
<p>1. You only pay for the data you store; there is no concept like the pre-allocation in EBS, you just pay for what you upload into S3.</p>
<p>2. You can share data between instances in real-time (or near real-time, look up eventual consistency as it applies to AWS).</p>
<p>But, with S3 there are some drawbacks too:</p>
<p>1. You are making HTTP requests to get data, so it will be quite a bit slower relatively speaking than data in C:\ or in EBS.</p>
<p>2. Since you are making HTTP requests, it is not as simple as referencing a regular volume label like C:\ or E:\. Though, there are some plug-ins that map S3 buckets to volumes.</p>
<p>As you can probably see, each technology has its own level of convenience, cost and capability. Most people tend to use a combination of all 3 to get the results they are looking for.</p>
<p>Thanks!</p>
<p>Eric.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/159/feed</wfw:commentRss>
		</item>
		<item>
		<title>How I run this site&#8230;</title>
		<link>http://learnaws.com/archives/155</link>
		<comments>http://learnaws.com/archives/155#comments</comments>
		<pubDate>Tue, 24 Mar 2009 20:06:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=155</guid>
		<description><![CDATA[Recently I&#8217;ve had a few questions about how I host and run this site so I thought I would write it up and share.
My domain registration is with Dreamhost. I almost always start out with Dreamhost - they are really cheap, under $20/month and you get all kinds of good stuff (i.e. Jabber server, SVN, [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve had a few questions about how I host and run this site so I thought I would write it up and share.</p>
<p>My domain registration is with Dreamhost. I almost always start out with Dreamhost - they are really cheap, under $20/month and you get all kinds of good stuff (i.e. Jabber server, SVN, etc).</p>
<p>I actually ran learnaws.com from my Dreamhost account for a little while; I wasn&#8217;t getting much traffic and I just wanted to try the concept out.</p>
<p>But, when I felt I wanted something more serious, I decided to move from Dreamhost. I just changed my name servers, I didn&#8217;t bother changing my domain registration. All of my payment information is setup in Dreamshost already so it makes renewals easier.</p>
<p>I had to decide between running my web site on EC2 or on a higher-end, local web hosting company that I use for higher traffic sites.</p>
<p>What I had in mind with learnaws.com was to host a lot of video tutorials. I like creating the videos and I think it&#8217;s a format that people tend to like.</p>
<p>Given that, I decided to use S3/Cloudfront to serve up these videos - I figured this would give me the best performance.</p>
<p>IMHO, you get the biggest performance gain serving up progressive download media like this when you serve it from a geographically closer server.</p>
<p>Since S3/Cloudfront is doing the heavy-lifting on this site, I decided to just host the web content in my local web hosting company. It&#8217;ll just spit out the static text parts of my site, so I figured I didn&#8217;t need the added performance of a dedicated EC2 instance.</p>
<p>I&#8217;m still deciding what my next step will be.</p>
<p>My big concern is that I&#8217;m using WordPress as my content management system, and as you probably know, that uses MySQL as its backend.</p>
<p>I&#8217;m planning on customizing WordPress to use SimpleDB as its back-end database. I think conceptually it should be possible; we&#8217;ll see how that plays out.</p>
<p>I think once my experimentation with SimpleDB as a WordPress backend is done, I&#8217;ll start hosting in EC2. If all goes well, I&#8217;ll put a HAProxy in front of a set of EC2 servers running my web site and those instances will talk to a set of domains in SimpleDB.</p>
<p>If the SimpleDB doesn&#8217;t work out, then I&#8217;ll probably have to think about doing some MySQL replication or splurge for a big, central EC2 instance.</p>
<p>In any case, this is what I really like about AWS; it&#8217;s very easy to adopt it step by step.</p>
<p>Thanks!</p>
<p>Eric.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/155/feed</wfw:commentRss>
		</item>
		<item>
		<title>Integrating with SalesForce.com via SQS</title>
		<link>http://learnaws.com/archives/138</link>
		<comments>http://learnaws.com/archives/138#comments</comments>
		<pubDate>Fri, 06 Mar 2009 22:58:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Salesforce.com]]></category>

		<category><![CDATA[SQS]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=138</guid>
		<description><![CDATA[Hey guys,
I&#8217;ve found that Amazon&#8217;s Simple Queue Service is a really great way to &#8216;glue&#8217; a couple of applications together. My latest integration has been with Salesforce.com.
Just in case you aren&#8217;t familiar with it, Salesforce.com is a hosted customer relationship management (CRM) system. It was one of the first &#8216;cloud&#8217; services available commercially.
I&#8217;m building an [...]]]></description>
			<content:encoded><![CDATA[<p>Hey guys,</p>
<p>I&#8217;ve found that Amazon&#8217;s Simple Queue Service is a really great way to &#8216;glue&#8217; a couple of applications together. My latest integration has been with Salesforce.com.</p>
<p>Just in case you aren&#8217;t familiar with it, <a title="Salesforce.com" href="http://www.salesforce.com" target="_blank">Salesforce.com</a> is a hosted customer relationship management (CRM) system. It was one of the first &#8216;cloud&#8217; services available commercially.</p>
<p>I&#8217;m building an event management system where people can sign up for events. The client I&#8217;m working with wants to create a &#8216;Lead&#8217; in Salesforce.com for each person that signs up for an event.</p>
<p>I don&#8217;t want this operation to interfere too much with my customer&#8217;s sign-up experience so I&#8217;m going to do my integration Salesforce.com offline.</p>
<p>This is where Simple Queue Service (SQS) is so handy. What I can do is capture the information that I need to generate a lead for my customer.</p>
<p>The message body that I&#8217;m going to send will just be in query string format:</p>
<p><img class="aligncenter size-full wp-image-139" title="picture-48" src="http://learnaws.com/wp-content/uploads/2009/03/picture-48.png" alt="picture-48" width="736" height="89" />My <strong>sendMessage </strong>function is defined as follows:</p>
<p><img class="aligncenter size-full wp-image-140" title="picture-49" src="http://learnaws.com/wp-content/uploads/2009/03/picture-49.png" alt="picture-49" width="451" height="151" /> This function is obviously really simple, but I do find it really useful.</p>
<p>The great thing about SQS is that your messages persist for up to 4 days. So I&#8217;m really in no hurry to write the logic to process these messages.</p>
<p>To work with Salesforce.com from an integration perspective, the first thing you need (assuming you don&#8217;t have a full account already) is a developer account; you need a developer account in order to use the API. You can get one from <a href="http://developer.force.com/" target="_blank">http://developer.force.com/</a>.</p>
<p>Once you login, your next step is to enable the API integration feature. You can enable this from the <strong>Setup </strong>menu, which is at the very top of your screen.</p>
<p><img class="aligncenter size-full wp-image-141" title="picture-50" src="http://learnaws.com/wp-content/uploads/2009/03/picture-50.png" alt="picture-50" width="316" height="103" /></p>
<p>Your next step is to enable the API. This is done by downloading the enterprise WSDL file. As far as I can tell, you don&#8217;t actually need the file itself; the act of downloading it enables the API for your account.</p>
<p><img class="aligncenter size-full wp-image-143" title="picture-52" src="http://learnaws.com/wp-content/uploads/2009/03/picture-52.png" alt="picture-52" width="428" height="377" /></p>
<p>Your next step is to open up your <strong>Personal Setup</strong></p>
<p><strong><img class="aligncenter size-full wp-image-142" title="picture-51" src="http://learnaws.com/wp-content/uploads/2009/03/picture-51.png" alt="picture-51" width="234" height="285" /></strong>In order to access your account from the API, you have to append a security token to your password. Choose the <strong>Reset My Security Token </strong>to get this token for the first time.</p>
<p><img class="aligncenter size-full wp-image-144" title="picture-53" src="http://learnaws.com/wp-content/uploads/2009/03/picture-53.png" alt="picture-53" width="402" height="283" /></p>
<p>That&#8217;s it, your account is all set. Now we just need a library to work with the Salesforce.com API. There is a library available for a wide selection of languages - you can see them all at: <a href="http://wiki.apexdevnet.com/index.php/API" target="_blank">http://wiki.apexdevnet.com/index.php/API.</a></p>
<p>I chose the <a href="http://wiki.apexdevnet.com/index.php/API" target="_blank">PHP Toolkit library</a>; this library works really well, the only thing is that it depends on the SOAP module for PHP. You&#8217;ll get an error about not being able to find the SoapClient class if you don&#8217;t have it. If you don&#8217;t have it, you&#8217;ll need to install it (i.e. yum install php-soap).</p>
<p>I&#8217;m on a Mac and installing php-soap is a bit more complicated. I actually didn&#8217;t bother because I was planning on deploying my application to an EC2 server anyways. For my local development I use XAMPP. The version of PHP that is installed with XAMPP has soap installed so I just ran that php interpreter instead (i.e. /Applications/xampp/xamppfiles/bin/php).</p>
<p>Once you have your Salesforce.com account setup and your wrapper configured, the actually coding is pretty straighforward.</p>
<p>I&#8217;m using my <a href="http://learnaws.com/archives/124">adaptive poll class</a> to implement my Salesforce integration worker.</p>
<p>PHP makes it really easy to parse a query string with its parse_str function.</p>
<p><img class="aligncenter size-full wp-image-145" title="picture-54" src="http://learnaws.com/wp-content/uploads/2009/03/picture-54.png" alt="picture-54" width="694" height="228" />I store the name of the event in my system in SimpleDb, so I do a quick query to get that; and I instantiate my Salesforce client in the code listing below:</p>
<p><img class="aligncenter size-full wp-image-146" title="picture-55" src="http://learnaws.com/wp-content/uploads/2009/03/picture-55.png" alt="picture-55" width="678" height="159" />Lastly, it is just a matter of creating the <strong>Lead </strong>object and saving some information to it:</p>
<p><img class="aligncenter size-full wp-image-147" title="picture-56" src="http://learnaws.com/wp-content/uploads/2009/03/picture-56.png" alt="picture-56" width="408" height="191" /></p>
<p>Now when someone signs up for an event, I have an additional line of code to submit their information into my queue. This really doesn&#8217;t take very long (I actually do it with AJAX asynchronously) so there is no affect on the users&#8217;s experience.</p>
<p>I usually have 1 or more workers running, so as soon as that message ends up in the queue, it is processed and a lead is created in Salesforce.com.</p>
<p><img class="aligncenter size-full wp-image-148" title="picture-57" src="http://learnaws.com/wp-content/uploads/2009/03/picture-57.png" alt="picture-57" width="898" height="393" /></p>
<p>There are a few other places in my application where I am gathering user data - I can easily just make a call to my <strong>sendMessage </strong>function to put their data into Salesforce.com as well.</p>
<p>In my opinion, Salesforce.com and SQS make great partners. With Salesforce.com, you can run CRM without the usual CRM headaches and high costs. SQS gives me an easy, generic way to do offline processing. I simply just dump my information into SQS. I don&#8217;t even need to have anything reading from the queue right away; my messages will persist for 4 days. Once I have my worker up and running, I can read each message and process them accordingly. Even if I have applications written in other programming languages, I can still use SQS because all I am doing is making an HTTP request with a string formatted in some way that I have defined.</p>
<p>Thanks!</p>
<p>Eric.</p>
<p><strong><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/138/feed</wfw:commentRss>
		</item>
		<item>
		<title>Installing Windows Components (i.e. IIS) on Amazon EC2</title>
		<link>http://learnaws.com/archives/130</link>
		<comments>http://learnaws.com/archives/130#comments</comments>
		<pubDate>Tue, 24 Feb 2009 02:24:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[EC2]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=130</guid>
		<description><![CDATA[Hello,
One of the first things you are likely to do when using a Windows AMI in Amazon EC2 is install some Windows Components. The most obvious would be a web server - IIS.
What you&#8217;ll find is that you&#8217;ll get prompted for a Windows installation CD. The way you give your Windows instance access to this [...]]]></description>
			<content:encoded><![CDATA[<p>Hello,</p>
<p>One of the first things you are likely to do when using a Windows AMI in Amazon EC2 is install some Windows Components. The most obvious would be a web server - IIS.</p>
<p>What you&#8217;ll find is that you&#8217;ll get prompted for a Windows installation CD. The way you give your Windows instance access to this CD is by creating an EBS volume from an Amazon snapshot.</p>
<p>Please see the video below for steps on how to do this.</p>
<p><script type="text/javascript"><!--
	QT_WritePoster_XHTML('Click to Play', 'http://static.learnaws.com/install_iis/install_iis-poster.jpg',
		'http://static.learnaws.com/install_iis/install_iis.mov',
		'640', '416', '',
		'controller', 'true',
		'autoplay', 'true',
		'bgcolor', 'black',
		'scale', 'aspect');
// --></script><br />
<noscript>&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span class=&#8221;mceItemObject&#8221;  width=&#8221;640&#8243; height=&#8221;416&#8243; classid=&#8221;clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B&#8221; codebase=&#8221;http://www.apple.com/qtactivex/qtplugin.cab&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span  name=&#8221;src&#8221; value=&#8221;http://static.learnaws.com/install_iis/install_iis-poster.jpg&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span  name=&#8221;href&#8221; value=&#8221;http://static.learnaws.com/install_iis/install_iis.mov&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span  name=&#8221;target&#8221; value=&#8221;myself&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span  name=&#8221;controller&#8221; value=&#8221;false&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span  name=&#8221;autoplay&#8221; value=&#8221;false&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span  name=&#8221;scale&#8221; value=&#8221;aspect&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;span class=&#8221;mceItemEmbed&#8221;  width=&#8221;640&#8243; height=&#8221;416&#8243; type=&#8221;video/quicktime&#8221; pluginspage=&#8221;http://www.apple.com/quicktime/download/&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; 		src=&#8221;http://static.learnaws.com/install_iis/install_iis-poster.jpg&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		href=&#8221;http://static.learnaws.com/install_iis/install_iis.mov&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		target=&#8221;myself&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		controller=&#8221;false&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		autoplay=&#8221;false&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		scale=&#8221;aspect&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; </noscript></p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/130/feed</wfw:commentRss>
<enclosure url="http://static.learnaws.com/install_iis/install_iis.mov" length="278" type="video/quick" />
		</item>
		<item>
		<title>AWS artifacts - things you can and can&#8217;t lose</title>
		<link>http://learnaws.com/archives/128</link>
		<comments>http://learnaws.com/archives/128#comments</comments>
		<pubDate>Fri, 20 Feb 2009 22:26:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=128</guid>
		<description><![CDATA[There are a number of artifacts you have to keep track of when using Amazon Web Services. Here is a quick rundown of them, and what the consequences are if you lose them.

Amazon user name and password - not a big deal if you lose this; as long as you have access to the email [...]]]></description>
			<content:encoded><![CDATA[<p>There are a number of artifacts you have to keep track of when using Amazon Web Services. Here is a quick rundown of them, and what the consequences are if you lose them.</p>
<ol>
<li><strong>Amazon user name and password </strong>- not a big deal if you lose this; as long as you have access to the email account associated with your account, you can reset your account and get access again.</li>
<li><strong>Amazon key and secret</strong> - as long as you can get into your account, you can see your key and secret. If you ever suspect that your account has been compromised, you can reset your secret. Doing this means any application that is using your secret will need to be updated.</li>
<li><strong>X.509 Certificate associated with your account</strong> - you can always download your public certificate, but you only get one chance to get your private key. When you first create your certificate, you will be prompted to save your private key. If you don&#8217;t save the key then, or you lose the key, that&#8217;s it, you need to create a new public key and you&#8217;ll get a new secret. These certificates can be used to authenticate to AWS in an application you build, but I haven&#8217;t seen many people do that. The only real issue I&#8217;ve seen is that the EC2 command line tools use these certificates. So if you lose the private key, you&#8217;ll need to get a new private key and update your EC2 command line tool installation.</li>
<li><strong>keypair used to launch your instance </strong>- if you&#8217;re using Linux or Solaris EC2 images, you can&#8217;t lose this. If you do, you won&#8217;t be able to get access to your instance because you don&#8217;t know the root password. Amazon support may be able to help you, but that&#8217;s about it. If you are using Windows, then there is a chance you have the administrator password written down, or maybe you changed it to something you know. Otherwise, you&#8217;re stuck, you won&#8217;t be able to get access. Your only choice will be to terminate the instance and restart it. Of course, that means you will lose your instance data.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/128/feed</wfw:commentRss>
		</item>
		<item>
		<title>Adaptive Polling in PHP and SQS</title>
		<link>http://learnaws.com/archives/124</link>
		<comments>http://learnaws.com/archives/124#comments</comments>
		<pubDate>Fri, 20 Feb 2009 19:05:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Featured]]></category>

		<category><![CDATA[Add new tag]]></category>

		<category><![CDATA[SQS]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=124</guid>
		<description><![CDATA[When looking for messages in SQS, there is nothing wrong with your approach (read, sleep, read, etc).
But, for a more sophisticated approach, check out Joel&#8217;s sample at http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1941. His calls his approach &#8216;adaptive polling&#8217;.
The motivation for picking a different polling algorithm is efficiency and cost. SQS charges you for every operation (about 1 penny/10, 000 [...]]]></description>
			<content:encoded><![CDATA[<p>When looking for messages in SQS, there is nothing wrong with your approach (read, sleep, read, etc).</p>
<p>But, for a more sophisticated approach, check out Joel&#8217;s sample at <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1941">http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1941</a>. His calls his approach &#8216;adaptive polling&#8217;.</p>
<p>The motivation for picking a different polling algorithm is efficiency and cost. SQS charges you for every operation (about 1 penny/10, 000 requests), so if you poll every second when there are no messages, you are spending a bit more money than you need to.</p>
<p>Also, if you poll and sleep at regular intervals, you aren&#8217;t processing messages as quickly as you could be. For example, if there are 1000 messages in your queue, you don&#8217;t necessarily want to sleep for 1 second after reading each one, you might as well try to read them as fast as you can. Strike while the iron is hot as it were <img src='http://learnaws.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I&#8217;ve implemented a version of adaptive polling in PHP, I posted that (along with the functor sample) here: <a href="http://static.learnaws.com/sample_code/PHPFunctor.zip" target="_blank">http://static.learnaws.com/sample_code/PHPFunctor.zip</a></p>
<p>All of the polling is done in the AdaptivePoll class; to act on any given message, you simply have to define your <strong>bodyFunction </strong>method as shown below:</p>
<p><img class="aligncenter size-full wp-image-117" title="picture-46" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/picture-46.png" alt="picture-46" width="491" height="399" />Using this class lets me quickly create workers for any processing that I want to do. The example above is obviously pretty trivial, but using SQS-driven workers and adaptive polling, I can always be assured that I&#8217;ll be as scalable as possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/124/feed</wfw:commentRss>
		</item>
		<item>
		<title>Remember to transfer your CNAMEs when you change hosting providers</title>
		<link>http://learnaws.com/archives/122</link>
		<comments>http://learnaws.com/archives/122#comments</comments>
		<pubDate>Fri, 20 Feb 2009 18:09:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[CloudFront]]></category>

		<guid isPermaLink="false">http://learnaws.com/?p=122</guid>
		<description><![CDATA[This is an easy thing to forget. When you change hosting providers - or associate a hosting provider with a domain you have registered, usually it is just a matter of changing name servers. But, if you are using CNAMEs with a CloudFront distribution, remember to transfer those too.
Thanks!
Eric.
]]></description>
			<content:encoded><![CDATA[<p>This is an easy thing to forget. When you change hosting providers - or associate a hosting provider with a domain you have registered, usually it is just a matter of changing name servers. But, if you are using CNAMEs with a CloudFront distribution, remember to transfer those too.</p>
<p>Thanks!</p>
<p>Eric.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/122/feed</wfw:commentRss>
		</item>
		<item>
		<title>Distributed Functors with SQS and PHP</title>
		<link>http://learnaws.com/archives/112</link>
		<comments>http://learnaws.com/archives/112#comments</comments>
		<pubDate>Fri, 20 Feb 2009 07:48:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Featured]]></category>

		<category><![CDATA[SQS]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=112</guid>
		<description><![CDATA[A functor (or function object) is a really common programming pattern; it&#8217;s commonly used to implement callbacks. The idea is to pass an object that is invoked by the receiver.
The functor pattern is usually limited to a single process (i.e. wherever the code is executing), but SQS and PHP enable you to take this pattern [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://en.wikipedia.org/wiki/Function_object">functor</a> (or function object) is a really common programming pattern; it&#8217;s commonly used to implement callbacks. The idea is to pass an object that is invoked by the receiver.</p>
<p>The functor pattern is usually limited to a single process (i.e. wherever the code is executing), but SQS and PHP enable you to take this pattern to a distributed and scalable level.</p>
<p>Let&#8217;s illustrate this with an example. Consider a simple class defined in <strong>helloworld.php </strong></p>
<p><img class="aligncenter size-full wp-image-113" title="Hello World PHP" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/picture-43.png" alt="Hello World PHP" width="376" height="284" /></p>
<p>In our code, we will instantiate this class and pass in a message that our object will store.</p>
<p style="text-align: center;"><img class="size-full wp-image-114 aligncenter" title="picture-44" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/picture-44.png" alt="picture-44" width="375" height="75" /></p>
<p>Our <strong>$helloWorld </strong>object is going to be our functor; in theory, we should be able to pass this object to another recipient, they should be able to invoke methods on it (<strong>sayHello </strong>in our case). Before we start passing this object around, we need to be able to preserve its state. We can do that by calling the <strong>serialize </strong>function in PHP.</p>
<p>The <strong>serialize </strong>function takes our object and stores its state as a string; in many languages, the format used is XML. By default in PHP, it is just some string representation. Our serialized object string will look something like the following:</p>
<pre>O:10:"HelloWorld":1:{s:7:"message";s:14:"Hello World!!!";}</pre>
<p>This is where SQS comes into play; we will send this serialized string as the body of an SQS message. Whoever receives this message can de-serialize the string into an object again and invoke its functionality.</p>
<p>Before we send our serialized string, it is a good idea to urlencode it first. Some of the characters may interfere with the XML format of an SQS message.</p>
<p>The code to create the queue, serialize and urlencode the object and send it as an SQS message looks as shown below.</p>
<p><img class="aligncenter size-full wp-image-116" title="picture-451" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/picture-451.png" alt="picture-451" width="595" height="211" /></p>
<p>Notice that we are hiding the implementation of how we are sending the message behind our <strong>sendMessage</strong> function; all we are doing is constructing the send message request and setting the body to our serialized and urlencoded state.</p>
<p>Since we are using SQS, our code to receive these messages can live in another process. This really helps our scalability because we can run these worker processes on multiple machines if we need to process a large number of messages.</p>
<p>The entire code for our worker is listed below:</p>
<p><img class="aligncenter size-full wp-image-117" title="picture-46" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/picture-46.png" alt="picture-46" width="491" height="399" />We are using a class called <strong>AdaptivePoll </strong>to help us out here. I&#8217;ll explain this class in another post. For now, just know that it polls a given SQS queue and calls <strong>bodyFunction </strong>if it finds a message.</p>
<p>When we get a message, notice how we are url-decoding the message and then de-serializing it. When we execute <strong>sayHello</strong> we should see a <strong>Hello World!!! </strong>message get printed out - this is the same message we set in our earlier code</p>
<p>SQS is an elegantly simple solution to a wide range of problems; in this case, we can use it to implement a generic, distributed functor pattern.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/112/feed</wfw:commentRss>
		</item>
		<item>
		<title>Services and Training</title>
		<link>http://learnaws.com/archives/100</link>
		<comments>http://learnaws.com/archives/100#comments</comments>
		<pubDate>Thu, 19 Feb 2009 21:11:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Featured]]></category>

		<category><![CDATA[Services and Training]]></category>

		<category><![CDATA[Professional Services]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=100</guid>
		<description><![CDATA[We offer a variety of services to help you take full advantage of the Amazon Cloud. Our services include:

Architectural Consulting
Custom Development
Training (on-site and online)

We will publish more details about these services shortly; in the meantime, please contact us at learn@learnaws.com for more information.
]]></description>
			<content:encoded><![CDATA[<p>We offer a variety of services to help you take full advantage of the Amazon Cloud. Our services include:</p>
<ul>
<li>Architectural Consulting</li>
<li>Custom Development</li>
<li>Training (on-site and online)</li>
</ul>
<p>We will publish more details about these services shortly; in the meantime, please contact us at <strong>learn@learnaws.com</strong> for more information.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/100/feed</wfw:commentRss>
		</item>
		<item>
		<title>What we do</title>
		<link>http://learnaws.com/archives/90</link>
		<comments>http://learnaws.com/archives/90#comments</comments>
		<pubDate>Thu, 19 Feb 2009 21:05:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=90</guid>
		<description><![CDATA[What we do is pretty simple, we are excited about Amazon Web Services, so we try to get other people excited and educated about Amazon Web Services.
Have a look at our blog for some videos and tutorials about AWS.
We also offer customized, on-site training and development services; contact us at learn@learnaws.com for more information.
]]></description>
			<content:encoded><![CDATA[<p class="paragraph_style_2" style="padding-bottom: 0pt;">What we do is pretty simple, we are excited about Amazon Web Services, so we try to get other people excited and educated about Amazon Web Services.</p>
<p class="paragraph_style_2" style="padding-bottom: 0pt;">Have a look at our <strong><a href="/archives/category/blog">blog</a></strong> for some videos and tutorials about AWS.</p>
<p class="paragraph_style_2" style="padding-bottom: 0pt;">We also offer customized, on-site training and development services; contact us at <strong>learn@learnaws.com</strong> for more information.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/90/feed</wfw:commentRss>
		</item>
		<item>
		<title>What is AWS?</title>
		<link>http://learnaws.com/archives/88</link>
		<comments>http://learnaws.com/archives/88#comments</comments>
		<pubDate>Thu, 19 Feb 2009 21:03:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=88</guid>
		<description><![CDATA[AWS - or Amazon Web Services is changing the way people are thinking about the way we compute.
More specifically, Amazon Web Services is all about cloud computing. Cloud computing is getting to be a pretty over-used term nowadays.
The way we see it, cloud computing is pretty simple. Instead of running as many computers as you [...]]]></description>
			<content:encoded><![CDATA[<p>AWS - or Amazon Web Services is changing the way people are thinking about the way we compute.</p>
<p class="paragraph_style_2">More specifically, Amazon Web Services is all about <span class="style_4">cloud computing</span>. Cloud computing is getting to be a pretty over-used term nowadays.</p>
<p class="paragraph_style_2">The way we see it, cloud computing is pretty simple. Instead of running as many computers as you can afford, let someone else do it.</p>
<p class="paragraph_style_2">Amazon is doing exactly this with their Amazon Web Services initiative.</p>
<p class="paragraph_style_2"><span id="more-88"></span></p>
<p class="paragraph_style_2">Instead of you buying as many computers as you can afford and running them, Amazon Web Services gives you access to its vast data center - you can use as many computers as you want, for as long as you want, and you only pay by-the-hour for what you use.</p>
<p class="paragraph_style_2">The same goes for storage and communication - you pay for each gigabyte you store and you pay for each message that you send and receive. The cost is very small; literally fractions of pennies in most cases.</p>
<p class="paragraph_style_2">Amazon is well-suited to doing this. Over the last 10 years or so, Amazon has honed its computing, storage and messaging infrastructure expertise in the unforgiving world of e-commerce. Today, Amazon.com is one of the busiest, and most reliable web properties in the world. The same infrastructure that drives this site is what is being made available through Amazon Web Services.</p>
<p class="paragraph_style_2">What makes AWS really revolutionary is that it enables individuals and companies to offload the responsibilities of computing, storage and messaging to Amazon. This enables us to concentrate on our core business.</p>
<p class="paragraph_style_2" style="padding-bottom: 0pt;">Amazon Web Services truly offers computing as a utility - we can use as much as we want, and we only ever pay for what we use.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/88/feed</wfw:commentRss>
		</item>
		<item>
		<title>FTP and Windows EC2</title>
		<link>http://learnaws.com/archives/76</link>
		<comments>http://learnaws.com/archives/76#comments</comments>
		<pubDate>Thu, 19 Feb 2009 19:49:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Add new tag]]></category>

		<category><![CDATA[EC2]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=76</guid>
		<description><![CDATA[Another easy way to share data between your local machine and your EC2 instance is via FTP.
The video below illustrates how to do exactly that; for more details on how to setup FTP for your Windows installation, please see http://support.microsoft.com/kb/323384.





]]></description>
			<content:encoded><![CDATA[<p>Another easy way to share data between your local machine and your EC2 instance is via FTP.</p>
<p>The video below illustrates how to do exactly that; for more details on how to setup FTP for your Windows installation, please see <a href="http://support.microsoft.com/kb/323384">http://support.microsoft.com/kb/323384</a>.</p>
<p><script type="text/javascript"><!--
	QT_WritePoster_XHTML('Click to Play', 'http://static.learnaws.com/media_rdc_share_web-poster.jpg',
		'http://static.learnaws.com/media_rdc_share_web.mov',
		'640', '416', '',
		'controller', 'true',
		'autoplay', 'true',
		'bgcolor', 'black',
		'scale', 'aspect');
//-->
</script><br />
<noscript><br />
<object width="640" height="416" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="http://static.learnaws.com/media_rdc_share_web-poster.jpg" /><param name="href" value="http://static.learnaws.com/media_rdc_share_web.mov" /><param name="target" value="myself" /><param name="controller" value="false" /><param name="autoplay" value="false" /><param name="scale" value="aspect" /><embed width="640" height="416" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/"<br />
		src="http://static.learnaws.com/media_rdc_share_web-poster.jpg"<br />
		href="http://static.learnaws.com/media_rdc_share_web.mov"<br />
		target="myself"<br />
		controller="false"<br />
		autoplay="false"<br />
		scale="aspect"></embed></object><br />
</noscript></p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/76/feed</wfw:commentRss>
<enclosure url="http://static.learnaws.com/media_rdc_share_web.mov" length="302" type="video/quick" />
		</item>
		<item>
		<title>Sharing Disk Drives and Windows EC2</title>
		<link>http://learnaws.com/archives/74</link>
		<comments>http://learnaws.com/archives/74#comments</comments>
		<pubDate>Thu, 19 Feb 2009 19:47:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Add new tag]]></category>

		<category><![CDATA[EC2]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=74</guid>
		<description><![CDATA[This question comes up pretty often so I thought I would do a video for it.
When you first start out with Amazon EC2, one of the most obvious questions to ask is ‘How do I get data onto my shiny, new Amazon-run machine?’.
The answer is pretty straightforward, but not always obvious when you are first [...]]]></description>
			<content:encoded><![CDATA[<p>This question comes up pretty often so I thought I would do a video for it.</p>
<p>When you first start out with Amazon EC2, one of the most obvious questions to ask is ‘How do I get data onto my shiny, new Amazon-run machine?’.</p>
<p>The answer is pretty straightforward, but not always obvious when you are first starting out.</p>
<p>I’ve found that this is more of a problem with Windows EC2 users. Most Linux folks are used to wget and scp so they can get their data back and forth pretty easily. There are of course Windows ports of those tools, but I think it is more common for Windows folks to use things like FTP, WebDAV, etc.</p>
<p>In the next set of short videos, I’m going to explore a number of ways to copy data back and forth between a Windows EC2 instance and your local physical machine.</p>
<p>The first method we will examine is pretty straightforward - we can simply use Remote Desktop to share the drives of our local machine with our remote machine. In the video below - I’m able to share my local file system and DVD with my Windows EC2 instance. This is particularly handy if I need to add Windows components to my instance; I can just pop my Windows installation CD into my local machine and access it remotely.</p>
<p><script type="text/javascript"><!--
	QT_WritePoster_XHTML('Click to Play', 'http://static.learnaws.com/media_rdc_share_web-poster.jpg',
		'http://static.learnaws.com/media_rdc_share_web.mov',
		'640', '416', '',
		'controller', 'true',
		'autoplay', 'true',
		'bgcolor', 'black',
		'scale', 'aspect');
//-->
</script><br />
<noscript><br />
<object width="640" height="416" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="http://static.learnaws.com/media_rdc_share_web-poster.jpg" /><param name="href" value="http://static.learnaws.com/media_rdc_share_web.mov" /><param name="target" value="myself" /><param name="controller" value="false" /><param name="autoplay" value="false" /><param name="scale" value="aspect" /><embed width="640" height="416" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/"<br />
		src="http://static.learnaws.com/media_rdc_share_web-poster.jpg"<br />
		href="http://static.learnaws.com/media_rdc_share_web.mov"<br />
		target="myself"<br />
		controller="false"<br />
		autoplay="false"<br />
		scale="aspect"></embed></object><br />
</noscript></p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/74/feed</wfw:commentRss>
<enclosure url="http://static.learnaws.com/media_rdc_share_web.mov" length="302" type="video/quick" />
		</item>
		<item>
		<title>ElasticFox on Mac OS X</title>
		<link>http://learnaws.com/archives/71</link>
		<comments>http://learnaws.com/archives/71#comments</comments>
		<pubDate>Thu, 19 Feb 2009 19:44:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[EC2]]></category>

		<category><![CDATA[ElasticFox]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=71</guid>
		<description><![CDATA[In our earlier videos, we configured the Amazon EC2 command line tools. The command line tools are great, but sometimes it is also nice to use a graphical user interface.
ElasticFox is a handy tool that provides exactly that. In the video below, we will illustrate how to configure this tool for Mac OS X.





]]></description>
			<content:encoded><![CDATA[<p>In our earlier videos, we configured the Amazon EC2 command line tools. The command line tools are great, but sometimes it is also nice to use a graphical user interface.</p>
<p>ElasticFox is a handy tool that provides exactly that. In the video below, we will illustrate how to configure this tool for Mac OS X.</p>
<p><script type="text/javascript"><!--
	QT_WritePoster_XHTML('Click to Play', 'http://static.learnaws.com/elasticfox_mac_web-poster.jpg',
		'http://static.learnaws.com/elasticfox_mac_web.mov',
		'640', '416', '',
		'controller', 'true',
		'autoplay', 'true',
		'bgcolor', 'black',
		'scale', 'aspect');
//-->
</script><br />
<noscript><br />
<object width="640" height="416" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="http://static.learnaws.com/elasticfox_mac_web-poster.jpg" /><param name="href" value="http://static.learnaws.com/elasticfox_mac_web.mov" /><param name="target" value="myself" /><param name="controller" value="false" /><param name="autoplay" value="false" /><param name="scale" value="aspect" /><embed width="640" height="416" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/"<br />
		src="http://static.learnaws.com/elasticfox_mac_web-poster.jpg"<br />
		href="http://static.learnaws.com/elasticfox_mac_web.mov"<br />
		target="myself"<br />
		controller="false"<br />
		autoplay="false"<br />
		scale="aspect"></embed></object><br />
</noscript></p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/71/feed</wfw:commentRss>
<enclosure url="http://static.learnaws.com/elasticfox_mac_web.mov" length="299" type="video/quick" />
		</item>
		<item>
		<title>ElasticFox on Windows</title>
		<link>http://learnaws.com/archives/67</link>
		<comments>http://learnaws.com/archives/67#comments</comments>
		<pubDate>Thu, 19 Feb 2009 19:37:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Featured]]></category>

		<category><![CDATA[EC2]]></category>

		<category><![CDATA[ElasticFox]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=67</guid>
		<description><![CDATA[In our earlier videos, we configured the Amazon EC2 command line tools. The command line tools are great, but sometimes it is also nice to use a graphical user interface.
ElasticFox is a handy tool that provides exactly that. In the video below, we will illustrate how to configure this tool for Window Server 2003.

&#38;amp;lt;br /&#38;amp;gt; [...]]]></description>
			<content:encoded><![CDATA[<p class="Body" style="padding-top: 0pt;">In our earlier videos, we configured the Amazon EC2 command line tools. The command line tools are great, but sometimes it is also nice to use a graphical user interface.</p>
<p>ElasticFox is a handy tool that provides exactly that. In the video below, we will illustrate how to configure this tool for Window Server 2003.</p>
<p><script type="text/javascript"><!--
	QT_WritePoster_XHTML('Click to Play', 'http://static.learnaws.com/elasticfox_windows_web-poster.jpg',
		'http://static.learnaws.com/elasticfox_windows_web.mov',
		'640', '416', '',
		'controller', 'true',
		'autoplay', 'true',
		'bgcolor', 'black',
		'scale', 'aspect');
// --></script><br />
<noscript>&amp;amp;lt;br /&amp;amp;gt; &amp;amp;lt;span class=&#8221;mceItemObject&#8221;  width=&#8221;640&#8243; height=&#8221;416&#8243; classid=&#8221;clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B&#8221; codebase=&#8221;http://www.apple.com/qtactivex/qtplugin.cab&#8221;&amp;amp;gt;&amp;amp;lt;/p&amp;amp;gt; &amp;amp;lt;span  name=&#8221;src&#8221; value=&#8221;http://static.learnaws.com/elasticfox_windows_web-poster.jpg&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt; &amp;amp;lt;span  name=&#8221;href&#8221; value=&#8221;http://static.learnaws.com/elasticfox_windows_web.mov&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt; &amp;amp;lt;span  name=&#8221;target&#8221; value=&#8221;myself&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt; &amp;amp;lt;span  name=&#8221;controller&#8221; value=&#8221;false&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt; &amp;amp;lt;span  name=&#8221;autoplay&#8221; value=&#8221;false&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt; &amp;amp;lt;span  name=&#8221;scale&#8221; value=&#8221;aspect&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt; 	&amp;amp;lt;span class=&#8221;mceItemEmbed&#8221;  width=&#8221;640&#8243; height=&#8221;416&#8243; type=&#8221;video/quicktime&#8221; pluginspage=&#8221;http://www.apple.com/quicktime/download/&#8221;&amp;amp;lt;br /&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt; 		src=&#8221;http://static.learnaws.com/elasticfox_windows_web-poster.jpg&#8221;&amp;amp;lt;br /&amp;amp;gt; 		href=&#8221;http://static.learnaws.com/elasticfox_windows_web.mov&#8221;&amp;amp;lt;br /&amp;amp;gt; 		target=&#8221;myself&#8221;&amp;amp;lt;br /&amp;amp;gt; 		controller=&#8221;false&#8221;&amp;amp;lt;br /&amp;amp;gt; 		autoplay=&#8221;false&#8221;&amp;amp;lt;br /&amp;amp;gt; 		scale=&#8221;aspect&#8221;&amp;amp;gt;&amp;amp;lt;br /&amp;amp;gt; 	&amp;amp;lt;br /&amp;amp;gt; &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;br /&amp;amp;gt; </noscript></p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/67/feed</wfw:commentRss>
<enclosure url="http://static.learnaws.com/elasticfox_windows_web.mov" length="311" type="video/quick" />
		</item>
		<item>
		<title>SimpleDb and the iPhone - Part 3</title>
		<link>http://learnaws.com/archives/63</link>
		<comments>http://learnaws.com/archives/63#comments</comments>
		<pubDate>Thu, 19 Feb 2009 19:34:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[SimpleDB]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=63</guid>
		<description><![CDATA[To use my SimpleDb wrapper, your code should look something like the following:

In the code above, I’m calling the QueryByAttributes method with no query expression, so I will get back all of my items with all of their attributes.
My SimpleDb class has a number of delegates that you can implement - one for each of [...]]]></description>
			<content:encoded><![CDATA[<p>To use my SimpleDb wrapper, your code should look something like the following:</p>
<p><img class="aligncenter size-full wp-image-64" title="iphone8" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/iphone8.png" alt="iphone8" width="390" height="222" /></p>
<p>In the code above, I’m calling the QueryByAttributes method with no query expression, so I will get back all of my items with all of their attributes.</p>
<p>My SimpleDb class has a number of delegates that you can implement - one for each of the SimpleDb methods that it implements - as listed below.</p>
<p><img class="aligncenter size-full wp-image-65" title="iphone9" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/iphone9.png" alt="iphone9" width="393" height="85" /></p>
<p>Well those are the highlights. Again, the code that I posted is not a complete implementation for the SimpleDb API. As I work on it more, I’ll post updates.</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/63/feed</wfw:commentRss>
		</item>
		<item>
		<title>SimpleDb and the iPhone - Part 2</title>
		<link>http://learnaws.com/archives/19</link>
		<comments>http://learnaws.com/archives/19#comments</comments>
		<pubDate>Sun, 01 Feb 2009 02:40:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[SimpleDB]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/archives/19</guid>
		<description><![CDATA[Generating the hash with CommonCrypto didn’t turn out to be as difficult as I had imagined.
The ‘salt’ value that you use in the hash is your AWS secret. Amazon will calculate the same type of hash with your secret on its end - if the two values match, you are in business.
My code to generate [...]]]></description>
			<content:encoded><![CDATA[<p>Generating the hash with CommonCrypto didn’t turn out to be as difficult as I had imagined.</p>
<p>The ‘salt’ value that you use in the hash is your AWS secret. Amazon will calculate the same type of hash with your secret on its end - if the two values match, you are in business.</p>
<p>My code to generate the hash as follows.:</p>
<p><img class="aligncenter size-full wp-image-53" title="iphone5" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/iphone5.png" alt="iphone5" width="542" height="506" /></p>
<p>Once this signature is generated, it is just a matter of tacking it onto the query string and parsing the XML coming back as shown below.</p>
<p><img class="aligncenter size-full wp-image-54" title="iphone6" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/iphone6.png" alt="iphone6" width="629" height="167" /></p>
<p class="paragraph_style"><strong>Parsing the Response</strong></p>
<p>Parsing Amazon’s response is just a matter of parsing the incoming XML. There are a few different ways of parsing XML on the iPhone. I chose to use their <span class="style_3">NSXMLParser</span>, which does SAX-style XML parsing. Again, the scratchpad is a handy of having a look at what that XML looks like. Below is a snippet from a <span class="style_3">QueryWithAttributes</span> response.</p>
<p><img class="aligncenter size-full wp-image-55" title="iphone7" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/02/iphone7.png" alt="iphone7" width="456" height="480" /></p>
<p class="Body">Building up the rest of the SimpleDb library is just a matter of parsing all of the various responses. I’ve posted my code at <a title="http://static.learnaws.com/SimpleDb_Archive.zip" href="http://static.learnaws.com/SimpleDb_Archive.zip">http://static.learnaws.com/SimpleDb_Archive.zip</a> with the caveat that I did not implement the full SimpleDb API. I’m implementing as much as I need for the various iPhone applications that I’m building. As I flesh out this implementation, I’ll post updates.</p>
<p>Please see ‘Part 3’ for an example of how to use this wrapper&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/19/feed</wfw:commentRss>
		</item>
		<item>
		<title>Amazon EC2 command-line tools on Windows</title>
		<link>http://learnaws.com/archives/6</link>
		<comments>http://learnaws.com/archives/6#comments</comments>
		<pubDate>Sat, 31 Jan 2009 02:32:37 +0000</pubDate>
		<dc:creator>ericlee</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[CLI]]></category>

		<category><![CDATA[EC2]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/archives/6</guid>
		<description><![CDATA[Setting up the Amazon EC2 command-line tools can be tricky the very first time you do it.
The video below illustrates how you do this for the Windows operating system.
If you look closely, I actually captured this screen cast on a Mac - the Windows ‘machine’ that I used is an EC2 instance running Windows Server [...]]]></description>
			<content:encoded><![CDATA[<p>Setting up the Amazon EC2 command-line tools can be tricky the very first time you do it.<br />
The video below illustrates how you do this for the Windows operating system.</p>
<p>If you look closely, I actually captured this screen cast on a Mac - the Windows ‘machine’ that I used is an EC2 instance running Windows Server 2003.</p>
<p><script type="text/javascript"><!--
	QT_WritePoster_XHTML('Click to Play', 'http://static.learnaws.com/ec2_windows_web-poster.jpg',
		'http://static.learnaws.com/ec2_windows_web.mov',
		'640', '416', '',
		'controller', 'true',
		'autoplay', 'true',
		'bgcolor', 'black',
		'scale', 'aspect');
//-->
</script><br />
<noscript><br />
<object width="640" height="416" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="http://static.learnaws.com/ec2_windows_web-poster.jpg" /><param name="href" value="http://static.learnaws.com/ec2_windows_web.mov" /><param name="target" value="myself" /><param name="controller" value="false" /><param name="autoplay" value="false" /><param name="scale" value="aspect" /><embed width="640" height="416" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/"<br />
		src="http://static.learnaws.com/ec2_windows_web-poster.jpg"<br />
		href="http://static.learnaws.com/ec2_windows_web.mov"<br />
		target="myself"<br />
		controller="false"<br />
		autoplay="false"<br />
		scale="aspect"></embed></object><br />
</noscript></p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/6/feed</wfw:commentRss>
<enclosure url="http://static.learnaws.com/ec2_windows_web.mov" length="290" type="video/quick" />
		</item>
		<item>
		<title>Amazon EC2 command-line tools on Mac OS X</title>
		<link>http://learnaws.com/archives/4</link>
		<comments>http://learnaws.com/archives/4#comments</comments>
		<pubDate>Sat, 31 Jan 2009 02:16:43 +0000</pubDate>
		<dc:creator>ericlee</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Featured]]></category>

		<category><![CDATA[CLI]]></category>

		<category><![CDATA[EC2]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/archives/4</guid>
		<description><![CDATA[In this video, we will setup the Amazon EC2 command line tools on Mac OS X.]]></description>
			<content:encoded><![CDATA[<p>In this video, we will setup the Amazon EC2 command line tools on a Mac OS X. </p>
<p>Mac OS X makes our job relatively straightforward since it has a terminal and a Java runtime already installed.</p>
<p>Please see below for the video.</p>
<p><script type="text/javascript"><!--
	QT_WritePoster_XHTML('Click to Play', 'http://static.learnaws.com/mac_ec2tools_web-poster.jpg',
		'http://static.learnaws.com/mac_ec2tools_web.mov',
		'640', '416', '',
		'controller', 'true',
		'autoplay', 'true',
		'bgcolor', 'black',
		'scale', 'aspect');
// --></script><br />
<noscript>&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span class=&#8221;mceItemObject&#8221;  width=&#8221;640&#8243; height=&#8221;416&#8243; classid=&#8221;clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B&#8221; codebase=&#8221;http://www.apple.com/qtactivex/qtplugin.cab&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span  name=&#8221;src&#8221; value=&#8221;http://static.learnaws.com/mac_ec2tools_web-poster.jpg&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span  name=&#8221;href&#8221; value=&#8221;http://static.learnaws.com/mac_ec2tools_web.mov&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span  name=&#8221;target&#8221; value=&#8221;myself&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span  name=&#8221;controller&#8221; value=&#8221;false&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span  name=&#8221;autoplay&#8221; value=&#8221;false&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;span  name=&#8221;scale&#8221; value=&#8221;aspect&#8221; class=&#8221;mceItemParam&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; 	&amp;amp;amp;amp;lt;span class=&#8221;mceItemEmbed&#8221;  width=&#8221;640&#8243; height=&#8221;416&#8243; type=&#8221;video/quicktime&#8221; pluginspage=&#8221;http://www.apple.com/quicktime/download/&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt; 		src=&#8221;http://static.learnaws.com/mac_ec2tools_web-poster.jpg&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		href=&#8221;http://static.learnaws.com/mac_ec2tools_web.mov&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		target=&#8221;myself&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		controller=&#8221;false&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		autoplay=&#8221;false&#8221;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 		scale=&#8221;aspect&#8221;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; 	&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;br /&amp;amp;amp;amp;gt; </noscript></p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/4/feed</wfw:commentRss>
<enclosure url="http://static.learnaws.com/mac_ec2tools_web.mov" length="293" type="video/quick" />
		</item>
		<item>
		<title>SimpleDb and the iPhone - Part 1</title>
		<link>http://learnaws.com/archives/1</link>
		<comments>http://learnaws.com/archives/1#comments</comments>
		<pubDate>Sat, 31 Jan 2009 02:00:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Blog]]></category>

		<category><![CDATA[Featured]]></category>

		<guid isPermaLink="false">http://learnaws.adhostclient.com/?p=1</guid>
		<description><![CDATA[The iPhone was arguably the hottest development platform of 2008 and likely to get only hotter in 2009.
The natural scalability that you get with AWS and the Internet-connectivity that the iPhone has makes the two an ideal pair.
That being the case, I was wondering what it would take to use Amazon Web Services in an [...]]]></description>
			<content:encoded><![CDATA[<p>The iPhone was arguably the hottest development platform of 2008 and likely to get only hotter in 2009.</p>
<p>The natural scalability that you get with AWS and the Internet-connectivity that the iPhone has makes the two an ideal pair.</p>
<p>That being the case, I was wondering what it would take to use Amazon Web Services in an iPhone application. The first service I decided to tackle was SimpleDb.</p>
<p class="Body" style="padding-top: 0pt;">It’s really not that important for this post, but the context of my experiment is snow reports - it’s winter time in the Northwest so I thought I would use a SimpleDb domain as sort of a clearing house for snow reports from the various ski resorts in the area. My iPhone application would pull down data from this domain and display it in a table.</p>
<p class="paragraph_style">The decision I had was how to access SimpleDb. The Amazon Web Services all expose themselves through a combination of REST, Query and SOAP.</p>
<p class="paragraph_style"><strong>Accessing SimpleDb - SOAP or REST?</strong></p>
<p class="Body">SOAP is a great option when you’re using .NET, Java or any other language that has a nice SOAP stack. The added advantage of SOAP is that you can use it with WS-Security, which means you can authenticate with a X.509 certificate, rather than passing around your secret and key.</p>
<p class="Body">But, the iPhone doesn’t really have a mature SOAP implementation. I did a little bit of searching and I found some experimental stuff, but nothing that I felt comfortable using. I’m pretty much a beginner with Objective-C and iPhone development.</p>
<p class="Body">I considered writing my own minimal SOAP stack, but that would involve creating the XML requests and parsing the XML response. Regardless of what method I use, I would have to parse the XML response. However, if I use REST, I am just putting together a URL request, so I can save myself 1/2 of the XML work. So, my choice was to use the SimpleDb REST API.</p>
<p class="paragraph_style"><strong><span class="style_3">REST Authentication</span></strong></p>
<p class="Body">This is actually where I ran into the most trouble. When using REST with Amazon Web Services, you have to pass along a authentication signature. Creating this signature is in concept well described by the Amazon documentation - it is just a matter of sorting your query parameters, capturing a time stamp and using your AWS secret as the key in a HMAC-SHA hash function.</p>
<p>The devil is in the details however. Let’s start from the beginning. The first thing I did was use a <span class="style_4">NSMutableDictionary </span>to store my parameter values as you can see below.</p>
<div id="attachment_46" class="wp-caption aligncenter" style="width: 461px"><img class="size-full wp-image-46" title="iphone1" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/01/iphone1.png" alt="Parameter Values" width="451" height="167" /><p class="wp-caption-text">Parameter Values</p></div>
<p>The snippet of code shown is actually for any generic SimpleDb call.</p>
<p class="Body">The parameters being added are required for all of the SimpleDb API calls.</p>
<p class="Body">After I’ve added these required parameters, I just need to add the parameters that are specific to the method that I’m calling.</p>
<p class="Body">Once that is done, to make the signature, the first step is to condense these parameters into a canonical form. The Amazon documentation does a more complete job of explaining this, but the general idea is that Amazon will take your parameters, your key, your time stamp and basically run the same hash algorithm. If the hashes are the same, then you are authenticated.</p>
<p>The canonical form is pretty straightforward, it is basically your parameters (both names and values) concatenated into a string. The parameters are in ascending order by their names first.</p>
<p><img class="aligncenter size-full wp-image-47" title="iphone2" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/01/iphone2.png" alt="iphone2" width="801" height="208" /></p>
<p class="Body">The <span class="style_4">NSMutableDictionary </span>class has a nice method (or I guess message in Objective-C parlance) that does the sort for me - I can even indicate that I want a case insensitive comparison.</p>
<p>Getting this canonical string correct is absolutely crucial. If you make a mistake here, then your hash will be wrong and you will not be authenticated. I found what really helped was using the <a title="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1137" onclick="window.open(this.href); return false;" onkeypress="window.open(this.href); return false;" href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1137">Amazon JavaScript ScratchPad for SimpleDb</a>. This tool has a correct implementation of the signature creation algorithm, and there is an option to conveniently show the canonical string.</p>
<p><img class="aligncenter size-full wp-image-48" title="iphone3" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/01/iphone3.png" alt="iphone3" width="801" height="143" /></p>
<p class="Body">Having a reference implementation really helped to make sure that I was creating the right canonical string. You’ll notice that this scratch pad also has an option to see the signed URL. This helpful, but this value is not synchronized with the time stamp that was generated for the canonical string.</p>
<p><strong>HMAC-SHA1 on the iPhone</strong></p>
<p>Once I was able to generate canonical string, it was time to generate the hash value for it. This was actually the hardest part for me. Most languages like .NET, PHP, Java, etc have good encryption libraries, so generating this hash is trivial. On Mac OS X, I believe most people use the Open SSL library to do this type of work. However, Open SSL was not ported to the iPhone SDK. Apparently it was there in the early betas, but it was pulled out at some point.</p>
<p><img class="aligncenter size-full wp-image-49" title="iphone4" src="http://learnaws.adhostclient.com/wp-content/uploads/2009/01/iphone4.png" alt="iphone4" width="257" height="72" /></p>
<p>I ended up making do with the CommonCrypto framework that is available for the iPhone.</p>
<p>Please see ‘Part 2’ for more details about this implementation&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://learnaws.com/archives/1/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
