Skip to content
March 11, 2012 / ahriman hpc mode

Основы хранилища Windows Azure. Блобы.

Компонент хранилища “облачной” платформы Windows Azure предоставляет масштабируемое хранилище. Компонент хранилища не имеет возможности использовать реляционную модель и является альтернативой (либо дополняющим решением) SQL Azure – масштабируемой “облачной” версией SQL Server.

В хранилище Windows Azure существует четыре абстракции, отвечающих за сервисы хранилища:

1) Блобы – простые именованные файлы + метаданные

2) Диски– долговечные тома NTFS, используемые приложениями Windows Azure. Основаны на блобах

3)Таблицы– структурированное хранилище. Таблица – множество сущностей, сущность – множество свойств

4)Очереди – надежное хранение и доставка сообщений для приложения

 

image

 

Блобы

На изображении представлена концептуальная архитектура и адресация ссылок на блобы.

image

 

    • Аккаунт– весь доступ к хранилище происходит через аккаунт хранилища, и имя аккаунта является первым сегментом в ссылке на блоб.
    • Контейнер блобов:
        • Аналогично папке верхнего уровня
        • Может содержать до 100Тб файлов
        • Может содержать только блобы
        • Каждый контейнер имеет права доступа:

      -Приватные

          -По умолчанию, для доступа нужен ключ аккаунта

      -Полное публичное чтение

      -Публичное только чтение

      • Контейнер содержит множество блобов
      • Много контейнеров на аккаунт
      • Специальный корневой контейнер $root
      • Можно определить права доступа на уровне контейнера
      • Можно привязать к контейнеру метаданные
      • Нет поисковых запросов типа WHERE MetadataValue = ?
  • Блоб –  Блобы могут иметь ассоциированные с ними метаданные в виде пар ключ-значение  и размером до 8 килобайт на блоб.

 

Существует два типа блобов:

  • Блочный блоб– для потоковых нагрузок.
    • Каждый блоб – последовательность блоков.
    • Каждый блок определяется Block ID. Размер ограничен 200Гб на блоб
    • Оптимистичный параллелизм через ETags. Модификация блоба – двухэтапный процесс. Сначала блоки загружаются в хранилище как неподтвержденные блоки для конкретного блоба, после чего для создания обновленного блоба используется метод PutBlockList.

image

 

  • Страничный блоб – для операций случайного чтения и записи.
    • Каждый блоб – массив страниц.
    • Каждая страница определяется отступом от начала блоба.  Размер ограничен 1Тб на блоб
    • Оптимистичный или пессимистичный (блокировка) параллелизм через Leases. Обновление происходит сразу же по завершению запроса на запись последовательного набора страница, поэтому блоки не надо подтверждать (commit).

 

image

 

Операции, доступные для управления блобами в хранилище Windows Azure:

Синхронное создание контейнера блобов:

        public static void CreateBlobContainer(string container)
        {

//получение настройки конфигурации хранилища
            var blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();

//создание ссылки на контейнер
            var blobContainer = blobClient.GetContainerReference(container);

//создание контейнера
            blobContainer.CreateIfNotExist();
        }

Сначала создается blobClient типа CloudBlobClient, необходимый для предоставления операций, доступных для управления блобами и контейнерами блобов, после чего получается ссылка на контейнер блобов и с помощью метода CreateIfNotExists контейнер создается, если его ранее не было. Доступен также метод Create, однако в случае существования контейнера с таким именем будет выброшено исключение, поэтому безопаснее использовать CreateIfNotExists.

При создании контейнера блобов необходимо учитывать следующие ограничения:

– Имя контейнера должно начинаться с буквы или цифры, и может содержать только буквы, цифры и символы дефиса.

– Все буквы должны быть низшего регистра.

– Длина имени должна быть от 3 до 63 символов.

– Имя не может содержат дефис после точки.

Таким образом, у вас не получится создать контейнер с именем myContainer – только mycontainer.

Асинхронное создание контейнера блобов:

        public static void CreateBlobContainerAsync(string container)
        {

//получение настройки конфигурации хранилища
            var blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();

//получение ссылки на контейнер
            var blobContainer = blobClient.GetContainerReference(container);

//начало процесса создания контейнера
            blobContainer.BeginCreateIfNotExist(EndCreateCloudBlobContainer, blobContainer);
        }
        public static void EndCreateCloudBlobContainer(IAsyncResult asyncResult)
        {
            var blobContainer = (CloudBlobContainer)asyncResult.AsyncState;
            blobContainer.EndCreateIfNotExist(asyncResult);
        }

Удаление контейнера блобов:

       protected void DeleteBlobContainer(string containerName)
        {
//получение настройки конфигурации хранилища            

CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();

//получение ссылки на контейнер
            var blobContainer = blobClient.GetContainerReference(containerName);

//удаление контейнера
            blobContainer.Delete();

        }

Создание блоба

Для создания блоба в указанном контейнере достаточно воспользоваться методом GetBlobReference объекта контейнера, передав ему наименование блоба. После этого будет создан пустой блоб, который необходимо чем-либо заполнить.

        protected void AddBlob()
        {
            try{

//получение настройки конфигурации хранилища
            CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();

//получение ссылки на контейнер mycontainer
            var blobContainer = blobClient.GetContainerReference("mycontainer");

//получение ссылки на блоб newblob
            var blob = blobContainer.GetBlobReference("newblob");

//загрузка в блоб файла Untitled.wmv
            blob.UploadFile(@"c:\Untitled.wmv");
            }
            catch (StorageClientException e)
            {
                Console.WriteLine("Storage client error encountered: " + e.Message);   System.Environment.Exit(1);
            }
        }

Удаление блоба

       protected void DeleteBlob(string blobName)
        {

//получение настройки конфигурации хранилища
            CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();

//получение ссылки на блоб
            var blob = blobClient.GetBlobReference(blobName);

//удаление блоба в случае его существования
            blob.DeleteIfExists();

        }

Создание и привязка метаданных к контейнеру блобов и блобу

Блобы могут иметь ассоциированные с ними метаданные. Заголовки метаданных могут быть определены по запросу при создании нового контейнера или блоба, или при «привязке» метаданных к уже существующим ресурсам

       protected void AssociateMetadata(string containerName)
        {

//создание коллекции значений ключ-значение

NameValueCollection metadata = new NameValueCollection();

//получение настройки конфигурации хранилища
            CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();

//получение ссылки на контейнер
            var blobContainer = blobClient.GetContainerReference(containerName);

//определение метаданных
            metadata["id"] = "1";
            metadata["name"] = "mycontainer";

//добавление метаданных в словарь метаданных для контейнера
            blobContainer.Metadata.Add(metadata);

//”коммит” метаданных
            blobContainer.SetMetadata();
//получение ссылки на блоб
            var blob = blobContainer.GetBlobReference("newblob");

//добавление метаданных в словарь метаданных для блоба
            blob.Metadata.Add(metadata);

//”коммит” метаданных
            blob.SetMetadata();

        }

Получение метаданных и свойств контейнера блобов и блоба

        protected void GetMetadata(string containerName)
    {

            CloudBlobClient blobClient =
                CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();
            var blobContainer = blobClient.GetContainerReference(containerName);
        blobContainer.FetchAttributes();
        var metadataContainer = blobContainer.Metadata;
        System.Diagnostics.Trace.WriteLine(metadataContainer["id"]);
        //метаданные для блоба
        var blob = blobContainer.GetBlobReference("newblob");
        blob.FetchAttributes();
        var metadata = blob.Metadata;
        System.Diagnostics.Trace.WriteLine(string.Format("content-type: {0}", blob.Properties.ContentType));
        blob.Properties.ContentType = "image/jpeg";
        System.Diagnostics.Trace.WriteLine(string.Format("content-type after changing: {0}", blob.Properties.ContentType));

    }

Определение прав доступа для контейнера

Класс BlobContainerPublicAccessType является enumeration, состоящим из следующих возможных значений прав доступа:

  • Blob: Публичный доступ на уровне блоба. Анонимные пользователи могут получать контент и метаданные блобов внутри этого контейнера, но не могут получать метаданные контейнера и список блобов внутри него.
  • Container: Публичный доступ на уровне контейнера. Анонимные пользователи могут получать контент и метаданные блоба и контейнера и список блобов внутри контейнера.
  • Off: Анонимный доступ отключен, только владелец аккаунта имеет доступ к каким-либо ресурсам внутри этого контейнера.
    protected void SetBlobContainerPermissions(BlobContainerPublicAccessType publicAccess)
    {
   var blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();
        var blobContainer = blobClient.GetContainerReference("mycontainer"); 

//определение разрешений путем создания легковесного объекта
        blobContainer.SetPermissions
            (new BlobContainerPermissions()
                 {
                     PublicAccess = publicAccess
                 });
    }

Управление доступом с помощью Shared Access Signatures и Shared Access Policies

Shared Access Policies и Shared Access Signatures  позволяют создать некоторые правила доступа к блобу или контейнеру, определяющие права доступа и период доступа.

Shared Access Policy: Политика определяет время начала действия политики, время истечения и набор разрешений для Shared Access Signatures.

Shared Access Signature: URL, предоставляющий доступ к контейнеру и блобу.

   protected void SetSAS()
    {

        var blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();
        var blobContainer = blobClient.GetContainerReference("mycontainer");
//создание объекта разрешений на контейнер
        var permissions = new BlobContainerPermissions();

//добавление политики на “только чтение”
        permissions.SharedAccessPolicies.Add("readonly", new SharedAccessPolicy()
        {
            SharedAccessStartTime = null,
            Permissions = SharedAccessPermissions.Read
        });

//добавление политики на “только запись”
        permissions.SharedAccessPolicies.Add("writeonly", new SharedAccessPolicy()
        {
            SharedAccessStartTime = null,
            Permissions = SharedAccessPermissions.Write
        });

//”коммит” разрешений
        blobContainer.SetPermissions(permissions);

     var blob = blobClient.GetBlobReference("mycontainer/Untitled.wmv");

//получение сигнатуры
        var sas = blob.GetSharedAccessSignature(new SharedAccessPolicy()
                                                    {
                                                        SharedAccessExpiryTime = DateTime.UtcNow.AddDays(5)
                                                    }, "readonly");
        System.Diagnostics.Trace.WriteLine(string.Format("Shared Access Signature for blob {0} is {1}, full link is {0}{1}", blob.Uri.AbsoluteUri, sas));

    }

Копирование и создание снапшотов блобов

Сервис блобов Windows Azure имеет поддержку копирования существующих блобов. Кроме этого сервис блобов Windows Azure поддерживает создание снапшотов блобов. Разница между снапшотом и копией блоба состоит в том, что снапшоты являются read-only и блоб-источник поддерживает связь со своими снапшотами; копии же можно изменять. После создания снапшота блоба блоб-источник не может быть удален до тех пор, пока существует хотя бы один его снапшот.

      protected void CopyAndSnapshotBlob()
        {
            CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient();
            var blobContainer = blobClient.GetContainerReference("mycontainer");
            var srcBlob = blobContainer.GetBlobReference("newblob");

            var newBlob = blobContainer.GetBlobReference("newblobcopy"); ;

            newBlob.CopyFromBlob(srcBlob);

            newBlob.FetchAttributes(new BlobRequestOptions { BlobListingDetails = BlobListingDetails.Metadata });

            newBlob.Metadata["id"] = "2";
            newBlob.Metadata["name"] = "copy of blob"+srcBlob.Metadata["name"];
            newBlob.SetMetadata();
            System.Diagnostics.Trace.WriteLine("Скопированный блоб имеет имя"+newBlob.Metadata["name"]);

            var snapshot = srcBlob.CreateSnapshot();

            System.Diagnostics.Trace.WriteLine("Был создан снапшот для:" + srcBlob.Uri + " в момент времени: " + snapshot.SnapshotTime);

        }

Всё вместе

Учитываем, что у вас уже созданы аккаунт хранилища и сервис для выполнения вашего приложения, а также создан ASP.NET проект с ассоциированным для него Windows Azure облачным проектом.

При программировании собственного облачного проекта не забудьте определить провайдера конфигурации в методе Application_Start (global.asax):

        void Application_Start(object sender, EventArgs e)
        {
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) =>
            {
                var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName);
                configSettingPublisher(connectionString);
            }
    );

А также строку подключения к хранилищу. Для этого:

1. Измените в описании сервиса настройки конфигурации, необходимые для доступа к сервису таблиц Windows Azure: откройте в облачном проекте папку Roles, щелкните правой кнопкой мыши на WebRole и выберите Properties.

image

 

2. Перейдите на вкладку Settings, нажмите Add Setting и создайте новую настройку конфигурации с именем DataConnectionString. Укажите её тип как Connection String, после чего нажмите на кнопку с троеточием и настройте строку подключения к хранилищу на использование локального эмулятора хранилища – Use storage emulator.

image

3. Нажмите CTRL-S для сохранения изменений.

Примечание: Библиотека StorageClient использует эти настройки для доступа к хранилищу Windows Azure.

DataConnectionString: Это строка подключения к аккаунту Windows Azure, программно используя которую, мы можем осуществить доступ к хранилищу данных и другой функциональности Windows Azure. Эта строка подключения может использовать либо аккаунт Windows Azure в «облаке», либо локальный эмулятор.

Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString: Это строка подключения к серверу Windows Azure, аналогичная DataConnectionString, но отведённая под нужды диагностики.

После этого поместите все вышеприведенные методы в файл Default.aspx.cs (либо любой другой code-behind файл, который хотите) и вставьте следующий код в обработчик события Page_Load:

        protected void Page_Load(object sender, EventArgs e)
        {
            CreateBlobContainer("mycontainer");
            CreateBlobContainerAsync("mycontainerasync");
            DeleteBlobContainer("mycontainerasync");
            DeleteBlob("newblob");
            AddBlob();
            AssociateMetadata("mycontainer");
            GetMetadata("mycontainer");
            SetBlobContainerPermissions(BlobContainerPublicAccessType.Blob);
            SetSAS(); 

            CopyAndSnapshotBlob();         

        }

После запуска в локальном эмуляторе обратите внимание на лог трассировки – в нём вы увидите все сведения, которые выводятся в методах. Кроме этого, вы можете воспользоваться Server Explorer в Visual Studio 2010 для просмотра содержимого вашего локального сервиса хранилища.

image

Диаграмма класса для наглядности того, что должно было получиться в результате:

image

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: