Accessing Windows Azure Read Access – Geo Redundant Storage (RA-GRS)

Around one month ago, the Windows Azure Team announced the possibility to access a geo-replicated Windows Azure Storage account in read-only mode (Read Access – Geo Redundant Storage | RA-GRS). This option is particularly interesting for those customers that require the highest level of business continuity, having data replicated in two regions hundred of kilometers apart from each other, with the possibility to read eventually consistent data from the secondary site.

In this post, I will demonstrate how to enable it and I will do some tests.

First thing to do is activate the feature, which is currently in preview. To do that, you can visit the subscription area in the Windows Azure portal.

Once your request will be submitted, it will be placed in a queue, and you will receive an email to inform you that the activation is complete.

For the purpose of this post, I have created a storage account, called francedstoragetest. To enable RA-GRS, there is a new option called Read Access Geo-Redundant (1 Locally redundant, 2 Geo-Redundant, 3 Read Access Geo-Redundant). In my example, I am using a new storage account, but you can also enable RA-GRS on an existing account.

The process will take a couple of minutes to complete. The dashboard now includes a few additional information.

First, we now have a Secondary Endpoint, in my case francedstoragetest-secondary. A column called LAST SYNC TIME shows the Last Sync Time completion between the primary and the secondary endpoints.

Francedstoragetest resides in Western Europe, while the secondary endpoint has been automatically placed in North Europe (see image below). This will change depending on the primary datacenter of your choice.

Not all storage tools are currently capable to access secondary replicas. I have installed Azure Storage Explorer on my laptop, and it is not been updated yet.

The Windows Azure Storage client library, which uses REST API version 2013-08-15, has been updated to talk with GA-GRS

I have slightly modified a console application written a few months ago to demo Windows Azure Storage to customers.

Using the Update-Package nuget command, the version of the library in my solution has been updated from 2.0.1.0 to 3.0.2.0

I have added a method called ListGeoRedundantBlobs. This method lists blob files, now from the secondary replica, and downloads a blob file to my local disk.

First thing to do is to create a StorageCredential object, where I have specified the storage account name (please note that you have to use the primary storage account name. We will specify which replica to use) and the storage key. You can get the storage key from the Windows Azure portal. Primary or secondary access key are both good.

Nothing new so far, but there a couple of interesting additions that give us the possibility to access the secondary region.

I have added a line of code to specify the secondary location, setting the LocationMode property, and thanks to this we will be able to execute queries on the secondary location. There are other options available in the enumerator, the product team post explains them very well.

In addition, we can also get information about the last sync between the two datacenters, using the ServiceStats class.

Then, we can either get the list of the blobs

or, for example, download a blob to the local disk. In my case I am downloading a pdf document. In case of a disaster on the primary location, we could write something more sophisticated to get all the data we need querying the secondary location.

Of course, trying to insert a new blob in the secondary replica will generate an exception.

You can find the code of the method below. I have also attached it in the txt file at the bottom of the post.

   1: static void ListGeoRedundantBlobs()

   2:         {

   3:             //set storage credentials

   4:             StorageCredentials sc = new StorageCredentials("francedstoragetest", "[access key here]");

   5:             CloudStorageAccount storageAccount = new CloudStorageAccount(sc, true);

   6: 

   7:             //Sets the blob client

   8:             CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

   9: 

  10:             //set the replica as the target for (read-only) queries

  11:             blobClient.LocationMode = Microsoft.WindowsAzure.Storage.RetryPolicies.LocationMode.SecondaryOnly;

  12: 

  13:             //get info about sync time

  14:             ServiceStats stats = blobClient.GetServiceStats();

  15:             string sLastSyncTime = stats.GeoReplication.LastSyncTime.HasValue ? stats.GeoReplication.LastSyncTime.Value.ToString() : "empty value";

  16:             Console.WriteLine("Status = {0} and SyncTime = {1}", stats.GeoReplication.Status, sLastSyncTime);

  17: 

  18:             CloudBlobContainer container = blobClient.GetContainerReference("[container name]");

  19: 

  20:             //List blobs

  21:             foreach (IListBlobItem item in container.ListBlobs(null, true))

  22:             {

  23:                 if (item.GetType() == typeof(CloudBlockBlob))

  24:                 {

  25:                     Console.WriteLine("block:" + item.Uri.ToString());

  26:                 }

  27:                 else if (item.GetType() == typeof(CloudPageBlob))

  28:                 {

  29:                     Console.WriteLine("page: " + item.Uri.ToString());

  30:                 }

  31:                 else if (item.GetType() == typeof(CloudBlobDirectory))

  32:                 {

  33:                     Console.WriteLine("dir: " + item.Uri.ToString());

  34:                 }

  35:             }

  36: 

  37:             //download a file locally from the replica

  38:             CloudBlockBlob blob = container.GetBlockBlobReference(@"[URI of the blob file here]");

  39: 

  40:             blob.DownloadToFile(

  41:             @"[local path]",

  42:             FileMode.OpenOrCreate,

  43:             null,

  44:             new BlobRequestOptions()

  45:             {

  46:                 LocationMode = Microsoft.WindowsAzure.Storage.RetryPolicies.LocationMode.SecondaryOnly,

  47:                 ServerTimeout = TimeSpan.FromMinutes(3)

  48:             });

  49: 

  50:             Console.ReadLine();

  51:            

  52:         }

 

Francesco

francedit

code.txt