Неструктурированное хранилище BLOB-объектов (создание Real-World облачных приложений с помощью Azure)
Рик Андерсон(Rick Anderson),Том Дайкстра (Tom Dykstra)
Скачать проект fix it или скачать электронную книгу
Электронная книга Building Real World Cloud Apps with Azure (Создание реальных облачных приложений с помощью Azure ) основана на презентации, разработанной Скоттом Гатри. В ней описано 13 шаблонов и методик, которые помогут вам успешно разрабатывать веб-приложения для облака. Сведения об электронной книге см. в первой главе.
В предыдущей главе мы рассмотрели схемы секционирования и объяснили, как приложение Fix It хранит образы в службе BLOB-объектов службы хранилища Azure и другие данные задач в базе данных Azure SQL. В этой главе мы более подробно рассмотрим службу BLOB-объектов и покажем, как она реализована в коде проекта Fix It.
Что такое хранилище BLOB-объектов?
Служба BLOB-объектов службы хранилища Azure предоставляет способ хранения файлов в облаке. Служба BLOB-объектов имеет ряд преимуществ по сравнению с хранением файлов в локальной сетевой файловой системе:
- Он очень масштабируемый. В одной учетной записи хранения могут храниться сотни терабайт, а у вас может быть несколько учетных записей хранения. Некоторые из крупнейших клиентов Azure хранят сотни петабайт. Microsoft SkyDrive использует хранилище BLOB-объектов.
- Он прочный. Резервное копирование каждого файла, храняемого в службе BLOB-объектов, выполняется автоматически.
- Он обеспечивает высокий уровень доступности. Соглашение об уровне обслуживания для службы хранилища гарантирует 99,9 % или 99,99 % времени доступности в зависимости от выбранного варианта геоизбыточности.
- Это функция PaaS (платформа как услуга) Azure. Это означает, что вы просто храните и извлекаете файлы, оплачивая только фактический объем используемого хранилища, а Azure автоматически выполняет настройку и управление всеми виртуальными машинами и дисками, необходимыми для службы.
- Доступ к службе BLOB-объектов можно получить с помощью REST API или API языка программирования. Пакеты SDK доступны для .NET, Java, Ruby и других.
- При хранении файла в службе BLOB-объектов можно легко сделать его общедоступным через Интернет.
- Вы можете защитить файлы в службе BLOB-объектов, чтобы к ним могли получить доступ только авторизованные пользователи, или предоставить временные маркеры доступа, которые делают их доступными кому-либо только в течение ограниченного периода времени.
Каждый раз, когда вы создаете приложение для Azure и хотите хранить большое количество данных, которые в локальной среде будут передаваться в файлы, такие как изображения, видео, PDF-файлы, электронные таблицы и т. д. — рассмотрим службу BLOB-объектов.
Создание учетной записи хранения
Чтобы приступить к работе со службой BLOB-объектов, создайте учетную запись хранения в Azure. На портале щелкнитеБыстрое созданиенового -- хранилища -- служб -- данных, а затем введите URL-адрес и расположение центра обработки данных. Расположение центра обработки данных должно совпадать с расположением веб-приложения.
Вы выбираете основной регион, в котором требуется хранить содержимое, и при выборе варианта георепликации Azure создает реплики всех данных в другом центре обработки данных в другой части страны или региона. Например, если вы выберете центр обработки данных в западной части США, при хранении файла он отправляется в центр обработки данных западной части США, но в фоновом режиме Azure также копирует его в один из других центров обработки данных в США. Если авария происходит в одной части страны или региона, ваши данные по-прежнему остаются в безопасности.
Azure не будет реплицировать данные через географические границы: если основное расположение находится в США, ваши файлы реплицируются только в другой регион в США; Если основное расположение — Австралия, файлы реплицируются только в другой центр обработки данных в Австралии.
Конечно, вы также можете создать учетную запись хранения, выполнив команды из скрипта, как мы видели ранее. Ниже приведена команда Windows PowerShell для создания учетной записи хранения.
# Create a new storage account
New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose
Получив учетную запись хранения, вы можете сразу же приступить к хранению файлов в службе BLOB-объектов.
Использование хранилища BLOB-объектов в приложении "Исправить"
Приложение Fix It позволяет отправлять фотографии.
При нажатии кнопки Создать FixIt приложение отправляет указанный файл изображения и сохраняет его в службе BLOB-объектов.
Настройка контейнера BLOB-объектов
Для хранения файла в службе BLOB-объектов требуется контейнер для его хранения. Контейнер службы BLOB-объектов соответствует папке файловой системы. Сценарии создания среды, рассмотренные в разделе Автоматизация всего , создают учетную запись хранения, но не создают контейнер. Поэтому целью CreateAndConfigure
метода PhotoService
класса является создание контейнера, если он еще не существует. Этот метод вызывается из Application_Start
метода в Global.asax.
public async void CreateAndConfigureAsync()
{
try
{
CloudStorageAccount storageAccount = StorageUtils.StorageAccount;
// Create a blob client and retrieve reference to images container
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("images");
// Create the "images" container if it doesn't already exist.
if (await container.CreateIfNotExistsAsync())
{
// Enable public access on the newly created "images" container
await container.SetPermissionsAsync(
new BlobContainerPermissions
{
PublicAccess =
BlobContainerPublicAccessType.Blob
});
log.Information("Successfully created Blob Storage Images Container and made it public");
}
}
catch (Exception ex)
{
log.Error(ex, "Failure to Create or Configure images container in Blob Storage Service");
}
}
Имя учетной записи хранения и ключ доступа хранятся в appSettings
коллекции файла Web.config , а код в методе StorageUtils.StorageAccount
использует эти значения для создания строки подключения и установки подключения:
string account = CloudConfigurationManager.GetSetting("StorageAccountName");
string key = CloudConfigurationManager.GetSetting("StorageAccountAccessKey");
string connectionString = String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", account, key);
return CloudStorageAccount.Parse(connectionString);
Затем CreateAndConfigureAsync
метод создает объект , представляющий службу BLOB-объектов, и объект , представляющий контейнер (папку) с именем images в службе BLOB-объектов:
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("images");
Если контейнер с именем "images" еще не существует ( что будет верно при первом запуске приложения в новой учетной записи хранения), код создает контейнер и задает разрешения, чтобы сделать его общедоступным. (По умолчанию новые контейнеры BLOB-объектов являются частными и доступны только пользователям, у которых есть разрешение на доступ к вашей учетной записи хранения.)
if (await container.CreateIfNotExistsAsync())
{
// Enable public access on the newly created "images" container
await container.SetPermissionsAsync(
new BlobContainerPermissions
{
PublicAccess =
BlobContainerPublicAccessType.Blob
});
log.Information("Successfully created Blob Storage Images Container and made it public");
}
Сохранение отправленной фотографии в хранилище BLOB-объектов
Для отправки и сохранения файла изображения приложение использует IPhotoService
интерфейс и реализацию интерфейса в PhotoService
классе . Файл PhotoService.cs содержит весь код в приложении Fix It, который взаимодействует со службой BLOB-объектов.
Следующий метод контроллера MVC вызывается, когда пользователь нажимает кнопку Создать FixIt. В этом коде photoService
ссылается на экземпляр PhotoService
класса , а fixittask
— на экземпляр FixItTask
класса сущностей, в котором хранятся данные для новой задачи.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "FixItTaskId,CreatedBy,Owner,Title,Notes,PhotoUrl,IsDone")]FixItTask fixittask, HttpPostedFileBase photo)
{
if (ModelState.IsValid)
{
fixittask.CreatedBy = User.Identity.Name;
fixittask.PhotoUrl = await photoService.UploadPhotoAsync(photo);
await fixItRepository.CreateAsync(fixittask);
return RedirectToAction("Success");
}
return View(fixittask);
}
Метод UploadPhotoAsync
в PhotoService
классе сохраняет отправленный файл в службе BLOB-объектов и возвращает URL-адрес, указывающий на новый BLOB-объект.
public async Task<string> UploadPhotoAsync(HttpPostedFileBase photoToUpload)
{
if (photoToUpload == null || photoToUpload.ContentLength == 0)
{
return null;
}
string fullPath = null;
Stopwatch timespan = Stopwatch.StartNew();
try
{
CloudStorageAccount storageAccount = StorageUtils.StorageAccount;
// Create the blob client and reference the container
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("images");
// Create a unique name for the images we are about to upload
string imageName = String.Format("task-photo-{0}{1}",
Guid.NewGuid().ToString(),
Path.GetExtension(photoToUpload.FileName));
// Upload image to Blob Storage
CloudBlockBlob blockBlob = container.GetBlockBlobReference(imageName);
blockBlob.Properties.ContentType = photoToUpload.ContentType;
await blockBlob.UploadFromStreamAsync(photoToUpload.InputStream);
// Convert to be HTTP based URI (default storage path is HTTPS)
var uriBuilder = new UriBuilder(blockBlob.Uri);
uriBuilder.Scheme = "http";
fullPath = uriBuilder.ToString();
timespan.Stop();
log.TraceApi("Blob Service", "PhotoService.UploadPhoto", timespan.Elapsed, "imagepath={0}", fullPath);
}
catch (Exception ex)
{
log.Error(ex, "Error upload photo blob to storage");
}
return fullPath;
}
Как и в методе CreateAndConfigure
, код подключается к учетной записи хранения и создает объект, представляющий контейнер больших двоичных объектов images, за исключением того, что он предполагает, что контейнер уже существует.
Затем он создает уникальный идентификатор для изображения, которое будет отправлено, путем объединения нового значения GUID с расширением файла:
string imageName = String.Format("task-photo-{0}{1}",
Guid.NewGuid().ToString(),
Path.GetExtension(photoToUpload.FileName));
Затем код использует объект контейнера BLOB-объектов и новый уникальный идентификатор для создания объекта BLOB-объекта, задает атрибут для этого объекта, указывающий, какой файл это, а затем использует объект BLOB-объекта для хранения файла в хранилище BLOB-объектов.
CloudBlockBlob blockBlob = container.GetBlockBlobReference(imageName);
blockBlob.Properties.ContentType = photoToUpload.ContentType;
blockBlob.UploadFromStream(photoToUpload.InputStream);
Наконец, он получает URL-адрес, который ссылается на большой двоичный объект. Этот URL-адрес будет храниться в базе данных и может использоваться на веб-страницах исправления для отображения отправленного изображения.
fullPath = String.Format("http://{0}{1}", blockBlob.Uri.DnsSafeHost, blockBlob.Uri.AbsolutePath);
Этот URL-адрес хранится в базе данных как один из столбцов таблицы FixItTask.
public class FixItTask
{
public int FixItTaskId { get; set; }
public string CreatedBy { get; set; }
[Required]
public string Owner { get; set; }
[Required]
public string Title { get; set; }
public string Notes { get; set; }
public string PhotoUrl { get; set; }
public bool IsDone { get; set; }
}
Благодаря только URL-адресу в базе данных и изображениям в хранилище BLOB-объектов приложение Fix It сохраняет базу данных маленькой, масштабируемой и недорогой, а образы хранятся там, где хранилище является дешевым и может обрабатывать терабайты или петабайты. В одной учетной записи хранения могут храниться сотни терабайт фотографий исправления, и вы платите только за то, что используете. Таким образом, вы можете начать с небольшой оплаты 9 центов за первый гигабайт, и добавить больше изображений за копейки за дополнительный гигабайт.
Отображение отправленного файла
Приложение Fix It отображает отправленный файл изображения при отображении сведений о задаче.
Чтобы отобразить изображение, все, что нужно сделать в представлении MVC, — это включить PhotoUrl
значение в HTML-код, отправляемый в браузер. Веб-сервер и база данных не используют циклы для отображения изображения, а лишь несколько байтов к URL-адресу изображения. В следующем коде Model
Razor ссылается на экземпляр класса сущностей FixItTask
.
<fieldset>
<legend>@Html.DisplayFor(model => model.Title)</legend>
<dl>
<dt>Opened By</dt>
<dd>@Html.DisplayFor(model => model.CreatedBy)</dd>
<br />
<dt>@Html.DisplayNameFor(model => model.Notes)</dt>
<dd>@Html.DisplayFor(model => model.Notes)</dd>
<br />
@if(Model.PhotoUrl != null) {
<dd><img src="@Model.PhotoUrl" title="@Model.Title" /></dd>
}
</dl>
</fieldset>
Если взглянуть на HTML-код отображаемой страницы, вы увидите URL-адрес, указывающий непосредственно на изображение в хранилище BLOB-объектов, что-то вроде следующего:
<fieldset>
<legend>Brush the dog again</legend>
<dl>
<dt>Opened By</dt>
<dd>Tom</dd>
<br />
<dt>Notes</dt>
<dd>Another dog brushing task</dd>
<br />
<dd>
<img src="http://storageaccountname.blob.core.windows.net/images/task-photo-312dd635-ba87-4542-8b15-767032c55f4e.jpg"
title="Brush the dog again" />
</dd>
</dl>
</fieldset>
Сводка
Вы узнали, как приложение Fix It хранит образы в службе BLOB-объектов и только URL-адреса изображений в базе данных SQL. Использование службы BLOB-объектов позволяет значительно уменьшить размер базы данных SQL, что позволяет масштабироваться до почти неограниченного количества задач и может выполняться без написания большого объема кода.
У вас могут быть сотни терабайт в учетной записи хранения, и стоимость хранения гораздо дешевле, чем хранилище База данных SQL, начиная с 3 центов за гигабайт в месяц плюс небольшая плата за транзакции. И помните, что вы платите не за максимальную емкость, а только за сумму, которую вы фактически храните, поэтому ваше приложение готово к масштабированию, но вы не платите за всю дополнительную емкость.
В следующей главе мы поговорим о важности создания облачного приложения, способного корректно обрабатывать сбои.
Ресурсы
Дополнительные сведения см. в следующих ресурсах:
- Использование службы Хранилище BLOB-объектов Azure в .NET. Официальная документация на сайте MicrosoftAzure.com. Краткое введение в хранилище BLOB-объектов и примеры кода, демонстрирующие подключение к хранилищу BLOB-объектов, создание контейнеров, отправку и скачивание BLOB-объектов и т. д.
- FailSafe: создание масштабируемых, устойчивых Облачные службы. Серия видео из девяти частей Ульрих Хоманн, Марк Меркури и Марк Симмс. Представляет высокоуровневые концепции и принципы архитектуры очень доступным и интересным способом, на основе историй, взятых из опыта группы технической поддержки Майкрософт (CAT) с реальными клиентами. Сведения о службе хранилища Azure и больших двоичных объектах см. в эпизоде 5, начиная с 35:13.
- Шаблоны и методики Майкрософт — руководство по Azure. См. раздел Шаблон ключа камердинера.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по