Опубликован: 28.01.2014 | Доступ: свободный | Студентов: 2264 / 264 | Длительность: 14:33:00
Лекция 6:

Хранение и обработка данных с Windows Azure Storage и Windows Azure SQL Databases

Аннотация: Сценарий приложения Cloud Services, использующего для хранения данных блобы, таблицы и очереди Windows Azure. Сценарий приложения Cloud Services с хранением данных в базе данных. Краткое введение в масштабирование баз данных Windows Azure – федерации, шардинг.
Ключевые слова: Windows, storage, HTTP, кроссплатформенность, универсальность, SQL, server, петабайт, ПО, абстракция, NTFS, программная модель, класс, контейнер, параллелизм, массив, блокировка, запись, COMMIT, оплата, операции, ссылка, исключение, метаданные, заголовки, enumeration, права доступа, URL, доступ, первичный ключ, ключ, LINQ, API, Data, ADO, net, определение, значение, account, table, core, контекст, объект, создание таблицы, удаление таблицы, множества, аргумент, Web, cloud, очередь, опрос, интервал, онлайн, время выполнения, разбиение, архитектура, поле, FE, аутентификация, маршрутизация, partition, layer, балансировка нагрузки, файловая система, distributed, system, DFS, сервер, минимум, fabric, controller, виртуальное, таблица, масштабируемость, производительность, диапазон, запрос, redundant, GEO, domain, опция, транзакция, service, foo, BAR, полное имя, затраты, статистика, ID, IP, адрес, E2E, полоса пропускания, информация, HTTPS, signature, пользователь, SAS, контроль, механизмы, параметр, приложение, GET, BLOB, имя таблицы, ISO, сигнатура, Add, DELETE, SDK, URI, базы данных, database, AS, развертывание, TDS, интерфейс, БД, функция, management, CPU, RAM, латентность, preview, хранилище данных, администратор, права, брандмауэр, sync, база данных, высокая доступность, поддержка, secure, SSL, authentication, стандартный протокол, tabular data, stream, шифрование данных, transparent, encryption, шифрование, порт, список, модель данных

Сервис платформы Windows Azure Storage предоставляет масштабируемое хранилище, доступно как сервис REST – таким образом взаимодействие с сущностями, хранящимися в Windows Azure Storage, может быть произведено с любой платформы, которая поддерживает HTTP, что обеспечивает кроссплатформенность и универсальность. Сервис Windows Azure Storage может выступать как альтернативой, так и дополняющим решением для SQL Azure Databases, масштабируемой "облачной" версией SQL Server. Каждая сущность в Windows Azure Storage хранится в трёх экземплярах: сущности, хранящиеся в сервисах таблиц и блобов, записываются в еще один триплет в другом датацентре в этом же регионе. Все сущности трёх сервисов хранятся в едином контейнере первого уровня, который называется аккаунтом хранилища. На одну подписку Windows Azure можно создать до 20 аккаунтов, каждый из которых может содержать до 200 ТБ данных. Максимальное количество аккаунтов может быть расширено обращением в техническую поддержку на портале управления Windows Azure. Необходимо отметить, что подписка Windows Azure имеет собственное ограничение в 10 петабайт данных (200 ТБ * максимальное количество аккаунтов на подписку, равное 50).

Каждый аккаунт хранилища защищается от несанкционированного доступа двумя (первичным и резервным) 512-битными ключами доступа, с помощью которых сервис аутентифицирует входящие запросы. Ключи могут быть регенерированы в любом момент по запросу пользователя.

При хранении данных Windows Azure Storage использует одну из трех абстракций:

  1. Блобы (Blobs, Binary Large Objects) – простые именованные файлы + метаданные. В блобах могут храниться любые бинарные данные: изображения, текстовые файлы, и т.д.
  2. Таблицы – структурированное хранилище.
  3. Очереди – сервис-брокер, предоставляющий надежное хранение и доставку сообщений для приложения.

В Windows Azure Storage есть еще одна абстракция, которая является надстройкой над хранилищем блобов – диски – долговечные тома NTFS, используемые приложениями Windows Azure. Диски хранятся в блобах.

Программная модель Windows Azure Storage состоит из следующих классов:

  • CloudStorageAccount: класс, ассоциирующийся с аккаунтом хранилища, является точкой вхождения в сервисы хранилища.
  • Cloud[Service]Client: класс, содержащий функциональность, относящуюся к одному из трёх сервисов: CloudTableClient, CloudQueueClient, CloudBlobClient.
  • Cloud[Object]: класс, отображающий конкретную сущность одного из трёх сервисов, например, CloudBlob, CloudQueue.

Сервис блобов также имеет дополнительный класс CloudBlobContainer, отображающий контейнер блобов, в котором находятся сами блобы.

Блобы

Сервис блобов в Windows Azure Storage имеет простую структуру. Будучи REST-сервисом, хранилище предоставляет к каждой из хранимых сущностей гиперссылку, которая состоит из нескольких сегментов:

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

Блобы делятся на два типа – блочные и страничные.

Блочные блобы используются для потоковых нагрузок. Блочный блоб выглядит как логическая последовательность блоков, каждый из которых определяется специальным идентификатором и максимальным размером 200Гб на один блоб. Для блочного блоба используется оптимистичный параллелизм через ETags. Модификация блочного блоба состоит из двух этапов: сначала блоки должны быть загружены в хранилище как неподтвержденные блоки для конкретного блоба, после чего для создания обновленного блоба используется метод PutBlockList.

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

К сценариям использования блобов можно отнести:

  • Доставка статического контента в браузер.
  • Хранение контента для распределенного и глобального доступа.
  • Стриминг видео и аудио.
  • Резервирование данных.

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

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

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

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

  • Имя контейнера должно начинаться с буквы или цифры, и может содержать только буквы, цифры и символы дефиса.
  • Все буквы должны быть низкого регистра.
  • Длина имени должна быть от 3 до 63 символов.
  • Имя не может содержат дефис после точки.

Асинхронный вариант операции создания использует метод BeginCreateIfNotExist.

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

Для выполнения операции удаления должен быть создан экземпляр класса CloudBlobClient, необходимый для предоставления операций, доступных для управления блобами и контейнерами блобов, после чего, на основе этого экземпляра, получается ссылка на контейнер блобов (ссылка на контейнер может быть получена даже в том случае, если его не существовало ранее). Контейнер может быть удален с помощью метода Delete.

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

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

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

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

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

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

  • Blob: Публичный доступ на уровне блоба. Анонимные пользователи могут получать контент и метаданные блобов внутри этого контейнера, но не могут получать метаданные контейнера и список блобов внутри него.
  • Container: Публичный доступ на уровне контейнера. Анонимные пользователи могут получать контент и метаданные блоба и контейнера и список блобов внутри контейнера.
  • Off: Анонимный доступ отключен, только владелец аккаунта имеет доступ к каким-либо ресурсам внутри этого контейнера.

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

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

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

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

Таблицы

Данные в сервисе таблиц Windows Azure хранятся в виде коллекций сущностей. Сущность имеет первичный ключ и набор свойств. Свойства являются парами ключ-значения, что аналогично столбцам. Сервис таблиц в Windows Azure не является реляционным, поэтому нельзя выполнять следующие операции:

  1. Создание внешних ключей между таблицами.
  2. Выполнение операции объединения на стороне сервера
  3. Создание произвольных индексов.
  4. Выполнение таких функций, как, например, Count(), на стороне сервера.

Сервис таблиц подходит тогда, когда разработчику не требуется реляционное хранилище или не нужны операции объединения (joins) на стороне сервера, а также в тех случаях, когда набор данных не очень велик и операции объединения можно обрабатывать на стороне клиента с помощью LINQ. Для доступа к сервису таблиц разработчик может использовать REST API, совместимый с WCF Data Services (ранее ADO.NET Data Services Framework).

Сущность в таблицах состоит из следующих компонентов:

  • Свойство (столбец) – значение сущности. Имена свойств чувствительны к регистру. Свойства эквивалентны столбцам в классических СУБД, одна сущность может иметь до 255 свойств.
  • PartitionKey – первое обязательное свойство каждой таблицы, используемое системой для автоматической балансировки нагрузки и распределения сущностей таблицы между серверами.
  • RowKey – второе обязательное свойство каждой таблицы, являющееся уникальным ID сущности внутри партиции, в которой оно расположено, и являющееся вторым компонентом в комбинации с RowKey, уникально идентифицирующей сущность в таблице.
  • Timestamp – каждая сущность имеет версию, управляемую системой, необходимую для оптимистического параллелизма.

Для того, чтобы создать модель в клиентском приложении, которая будет отображаться из хранилища таблиц, необходимо создать класс, реализующий TableServiceEntity. Приведенный ниже код содержит определение класса, реализующего TableServiceEntity.

public class MyClass : TableServiceEntity
        {
            public MyClass()
            {
                base.PartitionKey = "Clients";
                base.RowKey = Guid.NewGuid().ToString();
            }
            public MyClass(string PartitionKey, string RowKey)
            {
                base.PartitionKey = PartitionKey;
                base.RowKey = RowKey;
            }
            public string FName { get; set; }
            public string LName { get; set; }
        }

Класс TableServiceEntity определяет системные свойства PartititionKey, RowKey и TimeStamp, необходимые для каждой сущности в таблице Windows Azure. В примере выше для свойства PartitionKey было определено фиксированное значение. В реальной ситуации необходимо выбирать такое значение, которое обеспечит балансировку нагрузки между узлами хранилища, динамическое вычисляемое значение, например, день добавления сущности.

Характерные особенности сервиса таблиц включают в себя:

  • Порядок сортировки – есть единственный индекс в таблицах, когда таблицы сортируются по сначала PartitionKey, после чего по RowKey, что означает, что записи, указывающие эти ключи, будут более эффективны, и результаты будут сортироваться сначала по PartitionKey и потом по RowKey.
  • ТипыPartitionKey и RowKey должны быть типа string, остальные свойства: Binary, Bool, DateTime, Double, GUID, Int, Int64, String.
  • Нет фиксированной схемы – в таблицах Windows Azure Storage нет схем, поэтому все свойства хранятся в парах ключ-типизированное значение, что означает, что две сущности в одной таблице могут иметь разные свойства. Например, в таблице может быть два свойства с одинаковым имене, но разными типами для значения свойства. В пределах одной сущности имена свойств должны быть уникальными.

Ссылка на таблицу выглядит стандартно для именования сущностей в сервисах хранилища Windows Azure:

http://<account>.table.core.windows.net/<TableName>

Рекомендация: так как используется локальный контекст данных, то таблицы данных должны создаваться только один раз. Обычно этот процесс выполняется на стадии подготовки и реже – в коде приложения. Application_Start в классе Global является рекомендуемым местом для помещения логики инициализации.

Для использования и управления содержимым таблицы необходимо создать объект типа CloudTableClient, предоставляющий следующие базовые методы:

CreateTableсоздание таблицы с определенным именем. В случае наличия таблицы с таким именем будет выброшено исключение StorageClientException. Наиболее предпочитаемым способом создания таблиц является их создание с помощью класса контекста.

CloudTableClient.CreateTablesFromModel(typeof(MyClassDataContext),
             account.TableEndpoint.AbsoluteUri, account.Credentials);
        }

CreateTableIfNotExistсоздание таблицы с определенным именем только в том случае, если ее не существует.

DoesTableExist – проверка на существование таблицы с определенным именем.

DeleteTableудаление таблицы и ее содержимого из хранилища. если этой таблицы не существует, будет выброшено исключение StorageClientException.

DeleteTableIfExistудаление таблицы и содержимого из хранилища только в том случае если она существует.

ListTables – получение списка всех таблиц. Возможно указание префикса для фильтрации имен таблиц.

AddObject – добавление сущности в таблицу.

В том случае, если в приложении происходит создание множества сущностей, дешевле (с позиции количества транзакций) и быстрее будет выполнить пакет запросов. Для этого необходимо передать в SaveChangesWithRetries соответстующий аргумент SaveChangesOptions.Batch. При этом необходимо учитывать, что в пакете можно совершать запросы update, delete и insert; один пакет может содержать до 100 сущностей; все сущности в одном пакете должны иметь одно значение PartitionKey.

Получение объектов может быть реализовано с помощью LINQ-утверждения. Для возвращения всех записей в пределах одной партиции и имеющих определенное значение поля, можно воспользоваться следующим LINQ-утверждением:

CloudTableQuery<MyClass> qry =
    (from e in ctx.CreateQuery<MyClass>("mytable")
     where e.PartitionKey == "Belotserkovskiy" && 
e.FName == "Alexander"
     select e).AsTableServiceQuery<MyClass>();

foreach (MyClass unit in qry)
{
    Console.WriteLine("{0}, {1}",  unit.PartitionKey, unit.FName);
}

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

MyClass unit = (from e in ctx.CreateQuery<MyClass>("mytable") 
where e.PartitionKey == "Belotserkovskiy" && e.FName == "Alexander"
 select e).AsTableServiceQuery<MyClass>().FirstOrDefault();
unit.FName= "Alex";
ctx.UpdateObject(unit); 
ctx.SaveChangesWithRetries(); 
ctx.DeleteObject(unit);
ctx.SaveChangesWithRetries();
Руслан Муравьев
Руслан Муравьев

Сайт dreamspark пишет что код истек :(

Andriy Zymenko
Andriy Zymenko

Этот курс требует оновления https://portal.azure.com/#create/hub здесь нет пункта Web Site в разделе Compute. К тому же для создание трубуется подписка