Многие примеры использования Windows Azure Storage, с которыми я сталкиваюсь, довольно просты и просто демонстрируют основы чтения и записи. Умение читать и писать обычно недостаточно для распределенного приложения с несколькими экземплярами. Для приложений, которые запускают более одного экземпляра (т.е. практически все, что вы запускаете в облаке), обычно важна обработка одновременных записей в общий ресурс.
К счастью, таблицы и BLOB-объекты Windows Azure поддерживают одновременный доступ через ETag. ETag являются частью спецификации HTML 1.1 и работают следующим образом:
- Вы запрашиваете ресурс (сущность таблицы или большой двоичный объект), а когда получаете ресурс, вы также получаете значение ETag. Это значение является уникальным значением для текущей версии ресурса; версия, которую вы только что передали.
- Вы вносите некоторые изменения в данные и пытаетесь сохранить их обратно в облако. В качестве части запроса вы указываете условный заголовок HTTP-запроса, например, If-Match HTTP, вместе со значением ETag, полученным на шаге 1.
-
Если указанный вами ETag совпадает с текущим значением ресурса в облаке, происходит сохранение. Если значение в облаке отличается, кто-то изменил данные между шагами 1 и 2 выше, и возвращается ошибка.
Примечание : Если вам все равно и вы хотите всегда записывать данные, вы можете указать значение ‘*’ для ETag в заголовке If-Match .
К сожалению, я не могу найти централизованный документ ETag для Windows Azure Storage. Вместо этого это обсуждается для конкретных API, которые его используют. См. Справочник по API REST служб хранения Windows Azure в качестве отправной точки для дальнейшего чтения.
Это все низкоуровневый HTTP, и большинство людей предпочитают использовать обертку вокруг API Azure, чтобы их было проще использовать.
Упаковщики
Так как это работает с оберткой? Ну, это действительно зависит от того, какую оболочку вы используете. Например, модуль Azure для Node.js позволяет вам указывать необязательные параметры, которые работают с ETag. Например, при хранении табличных сущностей вы можете указать checkEtag: true. Это преобразуется в заголовок HTTP-запроса «If-Match», что означает «выполнять операцию, только если указанный мной ETag совпадает с указанным на этом ресурсе в облаке». Если параметр отсутствует, по умолчанию используется значение ETag ‘*’ для перезаписи. Вот пример использования checkEtag:
tableService.updateEntity('tasktable',serverEntity, {checkEtag: true}, function(error, updateResponse) { if(!error){ console.log('success'); } else { console.log(error); } });
Обратите внимание, что я не указываю значение ETag где-либо выше. Это потому, что это часть serverEntry, которую я ранее читал с сервера. Вы можете увидеть значение, посмотрев на serverEntry [‘etag’]. Если значение ETag в serverEntity совпадает со значением на сервере, операция завершается ошибкой, и вы получите сообщение об ошибке, подобное следующему:
{ code: 'UpdateConditionNotSatisfied', message: 'The update condition specified in the request was not satisfied.\nRequestId:a5243266-ac68-4c64-bc55-650da40bfba0\nTime:2012-02-14T15:04:43.9702840Z' }
BLOB-объекты немного отличаются: они могут использовать больше условий, чем If-Match, а также комбинировать условия. Указание условных заголовков для операций службы BLOB- объектов содержит список поддерживаемых условных выражений, обратите внимание, что вы можете использовать условные выражения DateTime, а также ETag. Поскольку вы можете делать комбинации условных выражений, синтаксис немного отличается; Вы должны указать условия как часть accessConditions. Например:
var options = { accessConditions: { 'If-None-Match': '*'}}; blobService.createBlockBlobFromText('taskcontainer', 'blah.txt', 'random text', options, function(error){ if(!error){ console.log('success'); } else { console.log(error); } });
Для этого я просто использовал одно условие — If-None-Match — но при необходимости я мог бы добавить другое в коллекцию accessConditions. Обратите внимание, что я использовал подстановочный знак вместо фактического значения ETag. Это создает только блоб «blah.txt», если он еще не существует.
Резюме
Для облачных приложений, которым требуется одновременный доступ к файловым ресурсам, таким как большие двоичные объекты и таблицы, Windows Azure Storage предоставляет эту функцию через ETag. Если вы не программируете напрямую с помощью API REST хранилища Windows Azure, убедитесь, что используемая вами библиотека-оболочка / вспомогательная библиотека предоставляет эту функцию, если вы планируете ее использовать.