Welcome to Azure. Blobs. Containers

Капля никотина убивает пять минут рабочего времени.

Правда жизни


Вчера мы с Вами обсудили как хранить данные в случае системы в которой хранится много данных. Мы вскольз поговорили с Вами о блобах, теперь давайте обратим на них более пристальное внимание, потому как фича преотличнейшая!

Как хранятся блобы?
Блобы живут в контейнерах, Вы в своем аккаунте можете создавать большое количество контейнеров. Воспринимайте это как папка в которой Вы храните свои файлы, но в такой папке в которой нельзя создаваит другие папки. Тоесть Вы не сможете создать контейнер в контейнере. Не стоит бояться того что Вы не сможете создать аналог файловой системы — хоть я и не понимаю зачем Вам это может понадобиться — но блобы в собсвенных именах могут содержать знак «\» потому Вы сможете сэмулировать файловую систему.

Как доступаться к блобам?
Как уже в прошлом посте я говорил — доступ к любому сервису хранения данных совершается по HTML через REST комманды. Тоесть если у Вас есть контейнер под названием Container1 и в нем файл file1.mpg то аддресс к вашему блобу может выглядеть так:

http://thisisanameofyourstorageservice.blob.core.windows.net/Container1/file1.mpg

В тоже время ваш блоб может называться: folder1/subfolder1/file2.mpg и тогда путь к блобу будет выглядеть так:

http://thisisanameofyourstorageservice.blob.core.windows.net/Container1/folder1/subfolder1/file2.mpg

Но, не беспокойтесь, Вам не прийдется досутпаться к блобам через урлу:) Есть куда более цивилизованные методы о которых мы поговорим немного позже.

А давайте заведет свой аккаунт хранения данных!
Теперь давайте залогинемся на наш ажур портал и создадим новые сервисы хранения данных:


Нажимаем «New Storage Account», тут мы даем название сервису хранения данных а так же выбираем географический регион в котором наши данные будут размещенны. Тоесть, если мы выберем регион Европу — то все наши данные будут сохраненны в датацентре который размещен в Европе.
По умолчанию аддресс к сервисам хранения данных выглядит так:

http://.blob.core.windows.net/
http://.queue.core.windows.net/
http://.table.core.windows.net/

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

http://newstoragename.blob.core.windows.net/
http://newstoragename.queue.core.windows.net/
http://newstoragename.table.core.windows.net/

Теперь давайте поговорим немного о контейнерах. К контейнеру надо относиться как к папке самого высшего уровня — или как к диску. Вы не можете создать блоб напрямую в сервисы хранения данных — это возможно сделать только в контейнер. Вообще не очень круто будет, если любой сможет доступаться к нашим блобам, а устанавливать права доступа к каждому блобу — это ещё тот «мартышкин труд», потому права доступа к блобам выставляются на уровне контейнеров. Контейнеры бывают двух видов:
1. Приватные контейнеры. Для того чтобы считать данные с этого блоба — необходимо знать ключ с помощью которого можна доступаться к данным этого контейнера.
2. Только чтение для контейнера и только чтение для блоба. Если выставить только чтение для контейнера — любой сможет доступаться и читать данные блобов в контейнере. Если поставить только чтение для блоба — пользователи смогут читать данные блоба, но не смогут смотреть какие блобы вообще есть в контейнере.

Помните, как для разработки интсрументарий Ажура эмулирует для нас сервисы хранения данных?

Важно понимать — что сервисы хранения данных эмулированные и сервисы хранения данных на Ажуре — две разные вещи. С эмулятором, кроме ограничений которые я приводил раньше -у нас отсутствует репликация. Ну и ещё много вкусностей. Замечательное в этом все то, что если мы тестируем наше приложение на эмуляторе, то чтобы наше приложения заработало в продакшене — нам стоит всего лишь поменять одну строчку в настройках сервиса. Но об этом попозже:)

Эмулятор может запустить как сама студия, так и вы руками. Сделать это можно с помощью такой комманды:

C:\Program Files\Windows Azure SDK\v1.3\bin\devstore\DSService.exe

Чтобы выключить, можна использовать такую комманду:

C:\Program Files\Windows Azure SDK\v1.3\bin\devstore\DSService.exe /shutdown

Естественно расположения может меняться в зависимости от установки Azure SDK.
А теперь немного покодим!
Естественно чтобы начать кодить, нам необходимо каким то образом доступаться к сервисам хранения данных. Делается это очень просто — мы всего лишь обязанны задать компоненте корректный конекшен стринг к нашим сервисам. Так как пока мы не работаем в реальной среде , мы будем использовать эмулятор. Для того чтобы доступиться к эмулятору — есть всего лишь один аккаунт, и он одинаковый для всех:

storage account name: devstoreaccount1
Shared Key:Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGM
Gw==

Эти два парметра будут одинаковы во всех случаях и на любом компьютере. Естественно когда вы будете использовать сервисы хранения данных на Ажуре — эти параметры будут совершенно другие, но пока что есть — то есть:)

Путь к нашему блобу с использыванием эмулятора будет иметь такой вид:
http://127.0.0.1:10000/devstoreaccount1/Container1/file1.mpg
Формализировать его можно так:

http://127.0.0.1:10000/<StorageAccountName>/<Container>/<BlobName&gt;

Для того чтобы доступаться к сервисам хранения данных с веб роли, нам вначале необходимо иметь конекшен стрингу к этому сервису. Для того чтобы создать такую строчку, давайте посмотрим на настройки веб роли. В настройках веб роли, выберите добавить настройку, и задайте ей тип — ConnectionString. После чего, в значение этой настройки выберите UseDevelopmentStorage. Все, настройка есть!

Если посмотреть на xml файл, то Вы увидите что-то вроде такого:

 <Role name="TestRole">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
      <Setting name="testConnectionString" value="UseDevelopmentStorage=true" />
    </ConfigurationSettings>
  </Role>

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

 <Role name="TestRole">
    <Instances count="2" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
      <Setting name="testConnectionString" value="DefaultEndpointsProtocol=https;AccountName=accountname;AccountKey=accountKey" />
    </ConfigurationSettings>
  </Role>

Только вместо accountname и accountkey — название ваших сервисов хранения данных и ключ доступа к ним же.

Итак, настройка с конекшен стрингом к нашым сервисам хранения данных есть — давайте туда что нибудь запишем!
Для разогрева создадим обычную веб роль, и на страничке по умочанию добавим кнопку. Выглядит это приблизительно так:


<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
        
        <ContentTemplate>

        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="ButtonClick" />
        </ContentTemplate>
</asp:Content>

В обработке клика на кнопку, давайте добавим функционал создания каталога:

        /// <summary>
        /// Handles the Click event of the Button1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Button1_Click(object sender, EventArgs e)
        {
            SetConfiguration();
            CloudStorageAccount account = CloudStorageAccount.FromConfigurationSetting("testConnectionString");
            CloudBlobClient blobClient = account.CreateCloudBlobClient();
            CloudBlobContainer container = blobClient.GetContainerReference("newcontainer");
            container.Create();
        }

Как Вы заметили, я вызываю метод SetConfiguration(), выглядит он так:

        /// <summary>
        /// Sets the configuration.
        /// </summary>
        private void SetConfiguration()
        {
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
            {
                // Provide the configSetter with the initial value
                configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

                RoleEnvironment.Changed += (sender, arg) =>
                {
                    if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                        .Any((change) => (change.ConfigurationSettingName == configName)))
                    {
                        // The corresponding configuration setting has changed, propagate the value
                        if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
                        {
                            // In this case, the change to the storage account credentials in the
                            // service configuration is significant enough that the role needs to be
                            // recycled in order to use the latest settings. (for example, the 
                            // endpoint has changed)
                            RoleEnvironment.RequestRecycle();
                        }
                    }
                };
            });
        }

Это большая загадка для меня, почему я должен его дергать каждый раз, но если не использовать этот метод то получить досутп к сервисам хранения данных неполучиться. В идеале, получать настройки лучше через хелпер класс, в котором будет реализован этот метод и вызываться будет только один раз. Только для демонстрации я его ичпользовал таким некрасивым образом.
Итак, давайте теперь разберемся что мы сделали:)

CloudStorageAccount account = CloudStorageAccount.FromConfigurationSetting("testConnectionString");

Тут мы создали объект который может работать с сервисами хранения данных в Ажуре или на эмуляторе. Как видим конекшен стрингу он подтягивает с файла конфигурации веб роли.

Дальше нам необходимо создать клиент который умеет работать с блобами:

CloudBlobClient blobClient = account.CreateCloudBlobClient();

Вообще с этим объектом мы можем делать много интересных вещей, таких как:
— Возвращение списка контейнеров
— Получение ссылки на специфический контейнер
— Список блобов
— Ссылка на спецефический блоб

После этого нам нужно получить ссылку на контейнер, даже если он не существует:

CloudBlobContainer container = blobClient.GetContainerReference("newcontainer");

Вот тут будьте внимательны — контейнер может иметь в своем названии только буквы в нижнем регистре. У меня поиск решения почему моя аппликация не работает украло пол часа времени:) Не повторяйте моих ошибок.

Ну и последнюю строчку я думаю объяснять не иммет смысла, так как и так все понятно. Кстати, если запустите приложение ещё раз — получите ошибку что такой контейнер уже существует. Потому будьте аккуратней.

При создании контейнера — автоматически приватные разрешения установлены на контейнер, поэтому если вы хотите оставить возможность пользователям которые не знают ключа к контейнеру смотреть в нем файлы — настройка должны быть установлена на публичное чтение.

А ещё с этим объектом можно совершать такие действия:
-Создание контейнера
-Удаление контейнера
-Метаданные
-Свойства контейнера
-Получить или установить разрешнеия на контейнер
-Получить список блобов
-получение специфического блоба

Давайте посмотрим как мы можем получить лист контейнеров:

        /// <summary>
        /// Handles the Click event of the Button1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Button1_Click(object sender, EventArgs e)
        {
            SetConfiguration();
            CloudStorageAccount account = CloudStorageAccount.FromConfigurationSetting("testConnectionString");
            CloudBlobClient blobClient = account.CreateCloudBlobClient();
            var list = blobClient.ListContainers();
        }

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

        /// <summary>
        /// Handles the Click event of the Button1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Button1_Click(object sender, EventArgs e)
        {
            SetConfiguration();
            CloudStorageAccount account = CloudStorageAccount.FromConfigurationSetting("testConnectionString");
            CloudBlobClient blobClient = account.CreateCloudBlobClient();
            CloudBlobContainer container = blobClient.GetContainerReference("newcontainer");
            container.Delete();
        }

В следующем посты мы с Вами наконец-то поговорим именно про блобы:)

2 комментария на “Welcome to Azure. Blobs. Containers

  1. Уведомление: ??????????? ????????? ?? ????????? ? ???????? Microsoft ?? ??????? ????? – ?????? 2011 - MSDN Blogs

  2. Уведомление: Технические материалы по продуктам и решениям Microsoft на русском языке – апрель 2011 | Alexander Knyazev: блог

Оставьте комментарий