The indie publisher moving to Azure, part 1: migration

I've been a big fan of cloud-based infrastructure for a long time. I was fortunate enough to be on a small team of developers who built the reputation system for MSDN back in 2010, on Microsoft's Azure platform. Back then, there was a serious learning curve because Azure was barely a product. At the end of the day, we built something that easily could handle millions of transactions per month without sweating, and that was a sweet opportunity. Most people never get to build stuff to that scale.

My personal projects, specifically CoasterBuzz and PointBuzz, have been on everything from shared hosting in the early days to dedicated servers at my house and in various data centers. These sites are pretty modest in terms of traffic (low millions of requests per month), and the forum engine I wrote (POP Forums) is pretty efficient for the most part, so they don't require a ton of horsepower. That said, the overall cost of the various cloud services were still too high, or in some cases just didn't make a lot of sense to use. Bandwidth was the biggest cost problem. Even then, some services, like Amazon, might have been roughly equivalent on price, but if it's mostly just replacing a server with a virtual machine, that's a lateral move.

I've been a fan of Azure because the toolbox is so big. More specifically, their platform-as-a-service (PaaS) options take a lot of the nonsense out of running and administering stuff, which is a lot more fun. The Azure Web Sites and Cloud Service products, essentially purpose-built virtual machines, are really fantastic. Throw in the storage, queues, caches, etc., there's a lot to love.

With the recent price cuts, it was time to make the switch. The daily use and monitoring is a different topic to write about, and certainly I want to wait a few weeks until I have some experience with it. I want to talk about the migration effort here, which was relatively easy, but I do see a pretty big flaw that frankly should have been addressed years ago.

There isn't anything horribly exotic about my sites. They range from ASP.NET Webforms to MVC. There are also some other minor sites that are a little scary and do suboptimal things, mostly because they haven't changed in many years. As is typical, the little stuff ends up causing the most work. For example, the old CoasterBuzz blog site writes its MP3's to the file system. That, as it turns out, is a little tricky to handle because you can't just RDP into the server and set file permissions. Instead, you have to do that as part of the deployment. I haven't totally figured that out, so I can't share how that's done just yet. We have a similar function where we FTP up photos and bulk import them to photo albums.

Microsoft recently introduced the concept of a "hosting plan," which is roughly equivalent to a virtual server (or many instances thereof) that has all of the sites you want to group together. You can scale these up (server and CPU) and out (multiple instances behind a load balancer) as a group. This is cool, but it's also something of a minor liability. My sites tend to do a ton of caching, but that caching happens in the local memory. Therefore, I can't scale out, because the memory isn't shared across instances, and cache invalidation would be broken. I've actually done some prototyping on POP Forums that makes this easy to fix, but the older sites, especially PointBuzz, aren't ready for that. Fortunately, I don't expect to have to scale out any time soon. My stuff isn't built for multiple instances.

Setting up the sites in the Azure portal is super easy. Most of the default settings are good, though you have to open up web sockets for your SignalR stuff (the forums use it). Beyond that, there are some backup options to enable, and this requires you to be on the standard tier. Deployment is super easy as well from Visual Studio, as it performs web.config transforms as necessary and connects right up to the platform.

The one thing that has required a bit of work is the weekly execution of a stored procedure. I calculate the top 100 roller coasters by running a sproc (those who know me will find that odd, because I so don't like doing this sort of thing with SQL). What I ended up doing was firing this from an MVC action that looks for a certain request body over SSL. Azure has a scheduler that handles this call. The problem is that the scheduler won't update via the management portal to include the text you want to send in that body, so that's borken. I reached out on the forums and found someone else with the same problem. No MSFT response so far.

As I expected, SQL is still a big mess. On one hand, I am so endlessly impressed with the way that Microsoft is iterating quickly with the web products and frameworks, and open sourcing much of it on top of that. Ditto with the ever expanding Azure toolbox. Moving stuff to Azure has been pretty easy for the most part, even into PaaS components, despite much of my stuff being written for traditional n-tier server scenarios.

But SQL Azure still has the worst migration story ever. I understand most of the other constraints that the platform has when compared to the on-premise version of SQL Server. You basically have two ways to get your data into SQL Azure. You can use the sync framework, which will junk up your database with triggers and stuff (as far as I remember... I haven't looked at it in years). The other alternative is you can import a BACPAC file that you have uploaded into blob storage. I chose the latter, and here's what happened.

The CoasterBuzz database weighs in over 8 gigs. Yes, I'm storing image data in there, but that only accounts for around a gig, maybe two, of that data. I created the BACPAC on my old dedicated server, and it took about an hour and 15 minutes. I should also mention that using SQL Studio caused it to lock up, but the command line version worked fine. It's an old box with slow disks, so whatever. I can hydrate the resulting BACPAC on my MacBook Air in less than 10 minutes. Restoring it to a SQL Azure database, using the "business" tier, took about 2 hours and 15 minutes. That's pretty terrible. What was even more terrible, however, was trying to import it into one of the new basic or standard tiers, which will eventually replace web and business. In the basic tier, I did test runs for the much smaller PointBuzz database (around 2 gigs in size), and I gave up after 6 hours. Reading the MSDN forums, this is a widespread problem, in that people with even a slightly large database can't get the data in fast enough to avoid significant down time. I get throttling the database under normal use conditions, but importing really shouldn't be neutered like that.

All told, it took me four hours to move the database, which for something that isn't trivial like a site for roller coaster nerds, would be totally unacceptable. A lot of the reason comes down to the fact they won't support two tried and true methods that would minimize, if not eliminate, down time. In the old world of dedicated servers, we had two options. We could turn on replication between databases (ignoring licensing for a moment, because an indie publisher like me certainly wouldn't have two licenses). Then you have a near-real-time copy of the database, and you can mostly just flip the DNS switch to the new location and/or connection strings and you're done. Alternatively, you can do a full back up, as in .bak files, and hydrate the database in the new location. When you're ready to cut over, you take down the site, do an incremental backup, then apply that backup that to the new location. This is what I did on my last move back in 2010, and it worked like a champ. I was down for 10 minutes, late at night when I had minimal traffic anyway.

I'm super enthusiastic about Azure, but if this were some bigger thing related to a "day job" project, I would not be OK with this crappy migration story. With all of this magic and innovation, it's weird that the SQL story is so poor. It has been that way since the beginning. (Disclaimer: I have some context about why that might be from my time working in Redmond, so that may color my discontent.) Considering how important the SQL part is of the Microsoft stack, you would think this would be a great priority. I mean, they still have an awful Silverlight based management portal for SQL Azure that doesn't even work in Chrome.

Putting all of that complaining aside, I can say that I'm super happy to be migrated and done. I love the idea that I no longer have to feed and care for a dedicated server. No more shipping transaction logs or patching or configuring. Stuff mostly just works now, and whenever I need something new, it can be created in a matter of seconds. That's where the magic is. Where we would not, once upon a time, ever think about using things like queues and table storage and service buses, now we can. That's so powerful, and it's not expensive.

No Comments

Add a Comment

As it will appear on the website

Not displayed

Your website