ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 21.04.2024
Просмотров: 280
Скачиваний: 1
получает новую версию. Эта новая версия возвращается клиенту как заголовок ETag.
5. Если версия сущности на сервере отличается от ETag в заголовке If-Match, изменение отклоняется, и клиенту возвращается HTTP-ошибка «precondition failed» (необходимое условие не выполнено).
При получении ошибки «precondition failed» типовым поведением клиентского приложения будет повторение всей операции, как показано в фрагменте кода ниже.
1.Приложение должно извлечь этот объект снова, т.е. получить его последнюю версию.
2.Обновить объект локально и вернуть его на сервер.
При использовании клиентской библиотеки .NET приложение получает HTTP-код ошибки в виде исключения DataServiceRequestException.
В примере ниже два разных клиента выполняют один и тот же код для изменения текста. Эти два клиента пытаются задать Text разные значения.
1.Они извлекают сущность. При этом для каждой сущности извлекается ETag, например, «v1». Оба клиента полагают, что предыдущая версия сущности
– «v1».
2.Каждый клиент локально обновляет свойство Text.
3.Каждый клиент вызывает методы UpdateObject и SaveChanges.
4.Каждый клиент отправляет на сервер HTTP-запрос с заголовком «If-Match: v1».
5.Запрос одного из клиентов попадает на сервер первым.
a.Сервер сравнивает заголовок If-Match с версией сущности. Они совпадают.
b.Сервер применяет изменение.
c.Версия сущности на сервере обновляется и становится «v2».
d.В качестве ответа клиенту отправляется новый заголовок «ETag:v2».
6.Далее на сервер поступает запрос другого клиента. На этот момент изменения первого клиента уже применены.
a.Сервер сравнивает заголовок If-Match с версией сущности. Они не совпадают, поскольку версия сущности уже изменена на «v2», тогда как в запросе указывается версия «v1».
b.Сервер отклоняет запрос.
//Задаем такой вариант объединения, который обеспечивает
//сохранение обновлений, но позволяет обновление etag.
//По умолчанию применяется значение AppendOnly, при котором
//уже отслеживаемая сущность не перезаписывается значениями,
//полученными с сервера, в результате чего в случае изменения
//сущности на сервере используется недействительный etag. context.MergeOption = MergeOption.PreserveChanges;
Blog blog =
(from blog in context.CreateQuery<Blog>("Blogs") where blog.PartitionKey == "Channel9"
&& blog.RowKey == "Oct-29"
select blog).FirstOrDefault(); blog.Text = "Hi there again"; try
{
context.UpdateObject(blog);
87
DataServiceResponse response = context.SaveChanges();
}
catch (DataServiceRequestException e)
{
OperationResponse response = e.Response.First();
if (response.StatusCode == (int)HttpStatusCode.PreconditionFailed)
{
//выполняем запрос объекта повторно, чтобы получить
//последний etag, и проводим обновление
}
}
Для безусловного обновления сущности приложение выполняет следующее:
1.Создает новый объект DataServiceContext или, в случае использования существующего контекста, отсоединяет объект, как демонстрирует пример ниже.
2.Присоединяем сущность к контексту и используем «*» как новое значение
ETag.
3.Обновляем сущность.
4.Вызываем SaveChanges.
//задаем опцию объединения, разрешающую перезапись,
//чтобы обеспечить возможность обновления отслеживаемой сущности context.Detach(blog);
//Присоединяем сущность к контексту, используя имя таблицы, сущность,
//которая должна быть обновлена, и "*" как значение etag. context.AttachTo("Blogs", blog, "*");
blog.Text = "Hi there again"; try
{
context.UpdateObject(blog);
DataServiceResponse response = context.SaveChanges();
}
catch (DataServiceRequestException e)
{
//Обработка ошибки, но в данном случае формировнаие ошибки PreCondition невозможно
}
Для запросов, которые могут возвращать большое количество результатов, система обеспечивает два механизма:
1.Возможность получать первые N сущностей, используя LINQ-функцию
Take(N).
2.Маркер продолжения, который обозначает место начала следующего множества результатов.
Система поддерживает функцию возвращения первых N соответствующих запросу сущностей. Например, если программа разрабатывается на .NET, для извлечения первых N сущностей (в данном примере это первые 100 сущностей) можно использовать LINQ-
функцию Take(N).
serviceUri = new Uri("http://<account>.table.core.windows.net"); DataServiceContext svc = new DataServiceContext(serviceUri);
88
var allBlogs = context.CreateQuery<Blog>("Blogs"); foreach (Blog blog in allBlogs.Take(100))
{
// выполняем некоторые операции с каждым блогом
}
Аналогичная функциональность поддерживается в интерфейсе REST через опцию строки запроса $top=N. Например, запрос «GET http://<UriСервиса>/Blogs?$top=100»
обеспечил бы возвращение первых 100 сущностей, соответствующих запросу. Фильтрация выполняется на сервере, поэтому в ответе клиенту может быть передано максимум 100 сущностей.
1.В запросе указывается максимальное число сущностей, которое должно быть возвращено.
2.Количество сущностей превышает максимально разрешенное сервером число сущностей в ответе (в настоящее время это 1000 сущностей).
3.Общий размер сущностей в ответе превышает максимально допустимый размер ответа (в настоящее время это 4МБ, включая имена свойств, но исключая xml-теги, используемые для REST).
4.На выполнение запроса требуется больше времени, чем заданный период
ожидания сервера (в настоящее время это 60 секунд)
В любом из этих случаев ответ будет включать маркер продолжения в виде специального заголовка. Для запроса к вашим сущностям используются такие заголовки:
x-ms-continuation-NextPartitionKey
x-ms-continuation-NextRowKey
Если клиент получил эти значения, он должен передать их со следующим запросом в виде опций HTTP-запроса; во всем остальном запрос остается неизменным. Это обеспечит возвращение следующего набора сущностей, начинающегося с места, обозначенного маркером продолжения.
Последующий запрос выглядит следующим образом: http://<UriСервиса>/Blogs?<исходныйЗапрос>&NextPartitonKey=<некотороеЗначен
ие>&NextRowKey=<другоеЗначение>
Это повторяется до тех пор, пока клиентом не будет получен ответ без маркера продолжения, что свидетельствует об извлечении всех соответствующих запросу результатов.
Маркер продолжения должен рассматриваться как непрозрачное значение. Оно указывает на точку начала следующего запроса и может не соответствовать фактической сущности в таблице. Если в таблицу добавляется новая сущность, так что Key(новая сущность) > Key(последняя сущность, извлеченная запросом), но Key(новая сущность) < «Маркера продолжения», тогда эта новая сущность не будет возвращена повторным запросом, использующим маркер продолжения. Но новые сущности, добавленные так, что Key(новая сущность) > «Маркера продолжения», войдут в результаты, возвращаемые последующими использующими маркер продолжения запросами.
Теперь рассмотрим модель согласованности, обеспечиваемую Windows Azure
Table.
В рамках одной таблицы система обеспечивает гарантии транзакции ACID для всех операций вставки/обновления/удаления для одной сущности.
Для запросов в рамках отдельной секции выполняется изоляция моментального снимка. Запрос обеспечивается согласованным представлением секции с момента его начала и в течение всей транзакции. Моментальный снимок обеспечивает следующее:
1. Отсутствие «грязного считывания». Транзакция не будет видеть незафиксированные изменения, вносимые другими транзакциями,
89
которые выполняются параллельно. Будут представлены только те изменения, которые были завершены до начала выполнения запроса на сервере.
2. Механизм изоляции моментального снимка позволяет производить чтение параллельно с обновлением секции без блокирования этого обновления.
Изоляция моментального снимка поддерживается только в рамках секции и в рамках одного запроса. Система не поддерживает изоляцию моментального снимка для нескольких секций таблицы или других фаз запроса.
Приложения отвечают за сохранение согласованности между множеством таблиц.
Впримере MicroBlogging использовалось две таблицы: Channels и Blogs. Приложение выполняет согласование таблиц Channels и Blogs. Например, когда канал удаляется из таблицы Channels, приложение должно удалить соответствующие блоги из таблицы Blogs.
Сбои могут возникать в моменты синхронизации состояния множества таблиц. Приложение должно уметь обрабатывать такие сбои и иметь возможность возобновлять работу с момента, на котором она была прервана.
Впредыдущем примере, когда канал удаляется из таблицы каналов, приложение должно также удалить все блоги этого канала из таблицы Blogs. В ходе этого процесса могут возникать сбои приложения. Для обработки таких сбоев приложение может сохранять транзакцию в Windows Azure Queues, что позволяет пользователю возобновить операцию удаления канала и всех его блогов даже в случае сбоя.
Вернемся к примеру с таблицами Channels и Blogs. Channels имеет следующие свойства: Name (Имя) как PartitionKey, пустая строка как RowKey, Owner (Владелец), CreatedOn (Дата создания). И Blogs имеет свойства Channel Name (Имя канала) как
PartitionKey, CreatedOn как RowKey, Title (Название), Blog, UserId. Теперь, когда канал удален, необходимо обеспечить, чтобы все ассоциированные с ним блоги также были удалены. Для этого выполняем следующие шаги:
1.Создаем очередь для обеспечения согласованности таблиц, назовем ее
«DeleteChannelAndBlogs» (Удаление каналов и блогов).
2.При поступлении запроса на удаление канала от роли веб-интерфейса, ставим в созданную выше очередь элемент, определяющий имя канала.
3.Создаем рабочие роль, которые будут ожидать событие добавления элемента в очередь «DeleteChannelAndBlogs».
4.Рабочая роль изымает элемент из очереди DeleteChannelAndBlogs, задавая для извлеченного элемента очереди время невидимости в течение N секунд. При этом элемент, определяющий имя канала, который должен быть удален, изымается. Если роль работника удаляет элемент очереди в течение этих N секунд, данный элемент будет удален из очереди. Если нет, элемент станет вновь видимым и доступным для использования рабочей ролью. При извлечении элемента рабочая роль делает следующее:
a.В таблице Channels помечает канал как недействительный, чтобы с этого момента никто не мог выполнять чтение из него.
b.Удаляет из таблицы Blogs все записи, для которых PartitionKey = “имени канала”, указанному в элементе очереди.
c.Удаляет канал из таблицы Channels.
d.Удаляет элемент из очереди.
e.Возвращается.
Если в ходе выполнения, например, шага 4, возникает какой-либо сбой, производится аварийное завершение рабочего процесса, при этом элемент очереди не удаляется из нее. Таким образом, как только соответствующий элемент очереди станет
90
снова видимым (т.е. когда истечет время, заданное как время ожидания видимости), это сообщение будет вновь извлечено из очереди рабочим процессом, и процесс удаления возобновится с шага 4. Более подробно обработка очередей рассматривается в документации Windows Azure Queue.
Ключевые термины:
Windows Azure Table – абстракция данных, которая обеспечивает структурированное хранилище состояний сервиса.
Windows Azure Blob – абстракция данных, которая обеспечивает хранилище больших элементов данных.
Windows Azure Queue – абстракция данных, которая обеспечивает диспетчеризацию асинхронных заданий для реализации обмена данными между сервисами
Литература:
1.ВикторШатохин www.way2cloud.com
2.Windows Azure Platform Training Kit - January 2011 Update
91
Лекция 7. Azure Services Platform. Часть 2
Azure Blob Services
Для работы с Windows Azure Storage пользователь должен создать учетную запись хранилища. Выполняется это через веб-интерфейс портала Windows Azure Portal. При создании учетной записи пользователь получает 256-разрядный секретный ключ, который впоследствии используется для аутентификации запросов этого пользователя к системе хранения. В частности, с помощью этого секретного ключа создается подпись HMAC SHA256 для запроса. Эта подпись передается с каждым запросом данного пользователя для обеспечения аутентификации через проверку достоверности подписи HMAC
Благодаря Windows Azure Blob приложения получают возможность хранения в облаке больших объектов, до 50 ГБ каждый. Он поддерживает высоко масштабируемую систему больших двоичных объектов (blob), в которой наиболее часто используемые blob распределяются среди множества серверов для обслуживания необходимых объемов трафика. Более того, эта система характеризуется высокой надежностью и длительностью хранения. Данные доступны в любой момент времени из любой точки планеты и продублированы, по крайней мере, трижды для повышения надежности. Кроме того, обеспечивается строгая согласованность, что гарантирует немедленную доступность объекта при его добавлении или обновлении: все изменения, внесенные в предыдущей операции записи, немедленно видны при последующем чтении.
Рассмотрим модель данных Azure Blob. На рисунке ниже представлено пространство имен Windows Azure Blob.
Учетная запись хранилища – Любой доступ к Windows Azure Storage осуществляется через учетную запись хранилища.
o Это самый высокий уровень пространства имен для доступа к объектам blob.
o Учетная запись может иметь множество контейнеров Blob.
Рисунок 7.1 Общее представление хранилища Blob
Контейнер Blob – Контейнер обеспечивает группировку набора объектов blob. Область действия имени контейнера ограничена учетной записью.
o Политики совместного использования задаются на уровне контейнера. В настоящее время поддерживаются «Public READ» (Открытое чтение) и «Private» (Закрытый). Если для контейнера определена политика «Public READ», все его содержимое открыто доступно для чтения без необходимости аутентификации. Политика «Private» означает доступ с аутентификацией, т.е. только владелец
92