Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια

Νοέμβριος 2009 - Δημοσιεύσεις


In general, there are two kind of updates you’ll mainly perform on Windows Azure. One of them is changing your application’s logic (or so called business logic) e.g. the way you handle/read queues, or how you process data or even protocol updates etc and the other is schema updates/changes. I’m not referring to SQL Azure schema changes, which is a different scenario and approach but in Table storage schema changes and to be more precise only on specific entity types because, as you already now, Table storage is schema-less. As in In-Place upgrades, the same logic applies here too. Introduce a hybrid version, which handles both the new and the old version of your entity (newly introduced properties) and then proceed to your “final” version which handles the new version of your entities (and properties) only. It’s a very easy technique and I’m explaining how to add new properties and of course remove although it’s a less likely scenario.

During my presentation at Microsoft DevDays “Make Web not War”, I’ve created an example using a Weather service and an entity called WeatherEntry, so let’s use it. My class looks like this:

   1: [DataServiceKey("PartitionKey","RowKey")]
   2: public class WeatherEntry : TableServiceEntity
   3: {
   4:     public WeatherEntry()
   5:     {
   6:         PartitionKey = "athgr";
   7:         RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
   8:     }
   9:     public DateTime TimeOfCapture{ get; set; }
  10:     public string Temperature{ get; set; }
  11: }

There is nothing special at this class. I use two custom properties, TimeOfCapture and Temperature and I’m going to make small change and I’ll add “SchemaVersion” which is needed to achieve the functionality I want. When I want to create a new entry, all I do now is instantiate a WeatherEntry, set the values and use a helper method called AddEntry to persist my changes.

   1: public void AddEntry(string temperature, DateTime timeofc)
   2: {
   3:    this.AddObject("WeatherData", new WeatherEntry { TimeOfCapture = timeofc, Temperature = temperature, SchemaVersion = "1.0" });
   4:    this.SaveChanges();
   5: }

I’m using TableServiceContext from the newly released StorageClient and methods like UpdateObject, DeleteObject, AddObject etc, exist in my data service context where AddEntry helper method relies. At the moment my Table schema looks like this:

schema-before-change  

It’s pretty obvious there is no special handling during saving of my entities but this is about to change in my hybrid version.

The hybrid

I did some changes at my base class and I’ve added a new property. It’s holding the temperature sample area, in my case Spata where Athens International Airport is.

My class looks like this now:

   1: [DataServiceKey("PartitionKey","RowKey")]
   2: public class WeatherEntry : TableServiceEntity
   3: {
   4:     public WeatherEntry()
   5:     {
   6:         PartitionKey = "athgr";
   7:         RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
   8:     }
   9:     public DateTime TimeOfCapture{ get; set; }
  10:     public string Temperature{ get; set; }
  11:     public string SampleArea{ get; set; }
  12:     public string SchemaVersion{ get; set;}
  13: }

So, this hybrid client has somehow to handle entities from version 1 and entities from version 2 because my schema is already on version 2. How do you do that? The main idea is that you retrieve an entity from table storage and you check if SampleArea and SchemaVersion have a value. If they don’t, put a default value and save them. In my case my schema version number has to be 1.5 as this is the default schema number for this hybrid solution. One key point to this procedure is before you upgrade your client to this hybrid, you roll-out an update enabling “IgnoreMissingProperties” flag on your TableServiceContext. If IgnoreMissingProperties is true, when a version 1 client is trying to access your entities which are on version 2 and have those new properties, it WON’T raise an exception and it will just ignore them.

   1: var account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
   2: var context = new WeatherServiceContext(account.TableEndpoint.ToString(), account.Credentials);
   3:  
   4: /* Ignore missing properties on my entities */
   5: context.IgnoreMissingProperties = true;

Remember, you have to roll-out an update BEFORE you upgrade to this hybrid.

Whenever I’m updating an entity to Table Storage, I’m checking its version Schema and if it’s not “1.5” I update it and put a default value on SampleArea:

   1: public void UpdateEntry(WeatherEntry wEntry)
   2: {
   3:     if (wEntry.SchemaVersion.Equals("1.0"))
   4:     {
   5:         /* If schema version is 1.0, update it to 1.5 
   6:          * and set a default value on SampleArea */
   7:         wEntry.SchemaVersion = "1.5";
   8:         wEntry.SampleArea = "Spata";
   9:     }
  10:     /* Put some try catch here to 
  11:      * catch concurrency exceptions */
  12:     this.UpdateObject(wEntry);
  13:     this.SaveChanges();
  14: }

My schema now looks like this. Notice that both versions of my entities co-exist and are handled just fine by my application.

schema-after-change

Upgrading to version 2.0

Upgrading to version 2.0 is now easy. All you have to do is change the default schema number when you create a new entity to version 2.0 and of course update your “UpdateEntry” helper method to check if version is 1.5 and update the value to 2.0.

   1: this.AddObject("WeatherData", new WeatherEntry { TimeOfCapture = timeofc, Temperature = temperature, SchemaVersion = "2.0" });

and

   1: public void UpdateEntry(WeatherEntry wEntry)
   2: {
   3:    if (wEntry.SchemaVersion.Equals("1.5"))
   4:    {
   5:        /* If schema is version 1.5 it already has a default
   6:         value, all we have to do is update schema version so 
   7:         our system won't ignore the default value */
   8:        wEntry.SchemaVersion = "2.0";
   9:    }
  10:    /* Put some try catch here to 
  11:     * catch concurrency exceptions */
  12:    this.UpdateObject(wEntry);
  13:    this.SaveChanges();
  14: }

Whenever you retrieve a value from Table Storage, you have to check if it’s on version 2.0. If it is, you can safely use its SampleArea value which is not the default any more. That’s because schema version is changed when you actually call “UpdateEntry” which means you had the chance to change SampleArea to a non-default value. But if it’s on version 1.5 you have to ignore it or update it to a new, correct value.

If you do want to use the default value anyway, you can create a temporary worker role which will scan the whole table and update all of your schema version numbers to 2.0.

How about when you remove properties

That’s a really easy modification. If you remove a property, you can use a SaveChangesOption called ReplaceOnUpdate during SaveChanges() which will override your entity with the new schema. Don’t forget to update your schema version number to something unique and put some checks into your application to avoid failures when trying to read non-existent properties due to newer schema version.

   1: this.SaveChanges(SaveChangesOptions.ReplaceOnUpdate);


That’s all for today! Smile

P.K

0 σχόλια
Δημοσίευση στην κατηγορία: , ,


In a previous post I’ve described what a VIP Swap is and how you can use it as an updating method to avoid service disruption. This particular method doesn’t apply to all possible scenarios and if not always, most of the times, during protocol updates or schema changes you’ll need to upgrade your service when its still running, chunk-by-chunk and without any downtime or disruption. By In-Place, I mean upgrades that take place during which both versions (old version and new version) are running side-by-side. In order to better understand the process below, you should read my “Upgrade domains” post in which there is a detailed description of what Upgrade domains are, how they affect your application, how you can configure the number of domains etc.

To avoid service disruption and outage Windows Azure is upgrading your application domain per domain (upgrade domain that is). That will result in a particular state where your Upgrade Domain 0 (UD0) is running a newer version of your client/service/what_have_you and your UD1, UD2 etc will run an older version. The best approach is to have a two-step phase upgrade.

Let’s call our old protocol version V1 and our new version V2. At this point, you should consider introducing a new client version called 1.5 which is a hybrid. What this version does is understanding both protocols used in both versions but always use protocol V1 by default and only respond by protocol V2 if they request is on V2. You can now start pushing your upgrades either by Service Management API or using Windows Azure Developer portal to completely automate the procedure. By the end of this process, you’ll achieve a seamless upgrade to your service without any disruption and all of your clients will upgrade to this hybrid. As soon as your first step is done and all of your domains are running version 1.5, you can proceed to step two (2).

In your second step you’ll be repeating the same process but this time your version 2 clients will use protocol V2 by default. Remember, your 1.5 clients DO understand protocol V2 and they respond to it properly once called upon with. To make it simple, this time you’re deploying version 2 of your client which uses version 2 of your protocol only. Old legacy code for version 1 is removed completely. As your upgrade domains complete the second step you’ll be having all your roles using version 2 of your protocol, again without any service disruption or downtime.

Schema changes have a similar approach but I’ll make a different post and actually put some code on it to demonstrate that behavior.

0 σχόλια
Δημοσίευση στην κατηγορία: , , ,


Windows Azure automatically divides your role instances into some “logical” domains called upgrade domains. During upgrade, Azure is updating these domains one by one. This is a by design behavior to avoid nasty situations. Some of the last feature additions and enhancements on the platform was the ability to notify your role instances in case of “environment” changes, like adding or removing being most common. In such case, all your roles get a notification of this change. Imagine if you had 50 or 60 role instances, getting notified all at once and start doing various actions to react to this change. It will be a complete disaster for your service.

logical-upgrade-domain 
Source: MSDN

The way to address this problem is upgrade domains. As I said, during upgrade Windows Azure updates them one by one and only the associated role instances to a specific domain get notified of the changes taking place. Only a small number of your role instances will get notified, react and the rest will remain intact providing a seamless upgrade experience and no service disruption or downtime.

role-upgrade
Source: MSDN

There is no control on how Windows Azure divides your instances and roles into upgrade domains. It’s a completely automated procedure and it’s being done on the background. There are two ways to perform an upgrade on a domain. Using Service Management API or the Windows Azure Developer portal. On the Developer Portal there are two more options. Automatic and manual. If you select automatic, Windows Azure will upgrade your domains without any hassle about what is going on. If you select manual, you’ll have to upgrade all of your domains one by one.

This is some of the magic provided by Windows Azure operating system and Windows Azure platform to provide scalability, availability and high reliability for your service.

PK.

0 σχόλια
Δημοσίευση στην κατηγορία: , ,


Today, during my presentation at Microsoft DevDays “Make Web not War” I had a pretty nice question about concurrency and I left the question somehow blurry and without a straight answer. Sorry, but we were changing subjects so fast that I missed it and I only realized it on my way back.

The answer is yes, there is concurrency. If you examine a record on your table storage you’ll see that there is a Timestamp field or so called “ETag”. Windows Azure is using this field to apply optimistic concurrency on your data. When you retrieve a record from the database, change a value and then call “UpdateObject”, Windows Azure will check if timestamp field has the same value on your object as it does on the table and if it does it will update just fine. If it doesn’t, it means someone else changed it and you’ll get an Exception which you have to handle. One possible solution is retrieve the object again, update your values and push it back. The final approach to concurrency is absolutely up to the developer and varies between different types of applications.

As I mentioned during my presentation, there a lot of different approaches to handle concurrency on Windows Azure Table Storage. There is a very nice video on the “How to” section on MSDN about Windows Azure Table Storage concurrency which can certainly give you some ideas.

PK.

0 σχόλια
Δημοσίευση στην κατηγορία: , ,


Performing an in-place upgrade on Windows Azure to change your service definition file it’s not possible unless you stop the service, upgrade and then start it again. Otherwise you can do a VIP Swap. VIP stands for Virtual IP and VIP swaps can be either done by the Developer portal or using the Service Management API by calling “Swap Deployment” method.

If you use VIP Swap and as long as you the endpoints between the old and new service definition are identical, the upgrade process is seamless and pretty straightforward without any service interruption. But if, for example, you introduce a new endpoint or delete and older one, then this process is not possible and you have to stop, upgrade, start.

So, how can you perform this operation from the Developer portal. Simply logon to your account, go to Summary page, open your target project, open the service and then upload the new service definition file on Staging. Now, if you click Run on Staging, both versions of your service will work just fine (one in Production, one in Staging). When you hit the Upgrade button (the one with arrows in the middle) then Azure will upgrade your service from Staging to Production, changing the service definition file and complete the process just fine thus performing a VIP swap in the background.

You can perform the same operation using Service Management API and “Swap Deployment” method as I mentioned before.

For more information about VIP Swap using Service Management API, go here –> MSDN, Azure Service Management API, VIP Swap

PK.

0 σχόλια
Δημοσίευση στην κατηγορία: , ,
It’s been a while since Windows Azure caught the attention of a broader audience rising all kinds of questions from the most simple “How do I access my table storage” to the most complex and generic “How do I optimize my code to pay less”. Although there Διαβάστε περισσότερα
0 σχόλια
Δημοσίευση στην κατηγορία: , , ,


Its been a while since Windows Azure caught the attention of a broader audience rising all kinds of questions from the most simple “How do I access my table storage” to the most complex and generic “How do I optimize my code to pay less”. Although there is a straight answer on the first one, that’s not the case on the second. Designing an application has always been a fairly complex scenario when it comes to high scale enterprise solutions or even on mid-sized businesses.

There are a few things to consider when you’re trying to “migrate” your application to the Azure platform.

You should have in mind that, you literally pay for your mistakes. As long as you’re not a developer account, which by the way you “pay” but in a different way, you are on a pay as you go model for various things, like Transactions, Compute hour, Bandwidth and of course storage. Oh and database size on SQL Azure. So every mistake that you make, let’s say un-optimized code producing more messages/transactions that necessary, you pay for it.

What’s a Compute hour? Well, it’s the number of instances multiplied by “consumed” (service) hours. And what’s a consumed (service) hour? It’s a simple medium size Azure instance having an average of 70% CPU peak, on a 1.60 GHZ CPU with 1.75 GB of RAM and 155 GB of non-persistent data. That means it’s not “uptime” as many of you think it is. So, when it comes to compute hours, you should measure how many hours does your application consume and optimize your code to consume less. Disable any roles, either Worker or Web when you don’t need them, it will cost you less.

SQL Azure as your database server. There are some catches here also. You should consider re-designing and re-writing the parts where your application is using BLOBs, specially when they are big ones, to use Azure table storage. That’s because of two reasons. First, there are only 2 editions of SQL Azure available as of now, 1GB and 10GB database size limit. You can pretty easily hit the limit when you have large amounts of BLOBs (images, documents etc). The second reason is that you don’t take advantage of the Azure CDN (Content Delivery Network) which means all your clients are served by the server(s) hosting your database even if this is slower because of the network latency. If you use Azure CDN , your content is distributed at various key points all around the world (Europe, Asia, USA etc) and your clients are served by the fastest available server nearby their location. And that’s not only that. Azure storage is using REST which means your content is also cached by various proxies increasing the performance even more.

Any thoughts?

PK.

0 σχόλια
Δημοσίευση στην κατηγορία: , ,
It's been a interesting week for Windows Azure. Since last Friday (13th of November) the latest Windows Azure Tools was released and strangely the installer was marked to be a 1.0 release although I'm not sure it really is one. Project Dallas has been Διαβάστε περισσότερα
2 σχόλια
Δημοσίευση στην κατηγορία: , , , ,
It's been a interesting week for Windows Azure. Since last Friday (13th of November) the latest Windows Azure Tools was released and strangely the installer was marked to be a 1.0 release although I'm not sure it really is one.
  • Project Dallas has been announced which is a MarketPlace for Vendors to publish their Azure Services for consuming and start making money out of it.
  • SQL Azure Data Sync Beta 1 was released. You can use it to synchronize cached data on your offline client with SQL Azure on the cloud just like using any other Synchronization Adapter/Manager on Microsoft Sync Framework. In order to install it and mess around with samples you need Microsoft Sync Framework 2.0 SDK.
  • .NET Services was renamed to Windows Azure AppFabric to match terms with Windows Server AppFabric which includes former named projects Velocity and Dublin in one single product. .NET Services consist of Access Control (Claims based authentication) and a Service bus to communicate with other applications.
  • New APIs were released to provision and manage Windows Azure Services.
  • There have been various enhancements on the platform and the Web UI like how many seconds does it take to switch from Staging to Production, a TCO Calculator has been introduced on the main website etc.

More to come, stay tuned.

0 σχόλια
Δημοσίευση στην κατηγορία: , , ,