Skip to content
April 25, 2012 / ahriman hpc mode

Windows Azure Building Blocks. Сервис Caching.

Несмотря на то, что сервис кэширования является не менее интересным, нежели его “коллеги по цеху” (Access Control Service, Service Bus), написано о нём мало. Этой статьёй открывается цикл, посвящённый практическому использованию Windows Azure Building Blocks. Первая статья – о сервиса Caching.

Сервис Caching позволяет реализовать кэширование на уровне хранения в памяти. Кэшируя частоиспользуемую информацию в памяти, мы можем увеличить производительность системы, так как информация при каждом запросе не считывается с диска, а считывается из гораздо более быстрой памяти. Разумеется, не вся частоиспользуемая информация должна храниться в кэше – лучшим кандидатом для кэширования будет информация, частоиспользуемая и редкоизменяемая. Типичными сценариями использования сервиса являются сохранение состояния сессии и кэширования вывода для ASP.NET. При этом информация хранится в памяти множества серверов. Конкретно для платформы Windows Azure сервис может быть выгоден также сокращением расходов на количество транзакций-обращений к базе данных.

Сервис Caching характеризуется:

  • Распределенным механизмом, хранящим информацию в памяти для использования приложениями, запущенными в Windows Azure;
  • Простым управлением – пользователю нет необходимости беспокоиться о конфигурации, развертывании и управлении;
  • Масштабируемостью;
  • Низкими задержками;
  • Высокой пропускной способностью;
  • Основа – Windows Server AppFabric Caching. Поддерживается основная функциональность, не поддерживаются notifications, настройка истечения срока хранения кэшированных данных (в кэше Windows Azure кэш истекает через 48 часов, и поменять это значение нельзя), High Availability и созданные пользователем регионы.
  • Windows Azure Caching позволяет кэшировать любой управляемый объект – XML, CLR-объекты и так далее.

К функциональности сервиса относятся (список неполон):

  • Доступность из любого приложения .NET, находящегося в Windows Azure;
  • Самоуправляемость;
  • Провайдеры ASP.NET для сохранения состояния сессии и кэширования вывода;
  • Конфигурационные файлы, которые можно настраивать из приложения;
  • Оптимистичная/пессимистичная модель;
  • Локальный кэш;
  • Компрессия кэшированных объектов;
  • Возможность обеспечения безопасности и аутентификации с использованием Windows Azure Access Control Service.

Так называемую пирамиду задержек можно увидеть на рис.1.

image

Рис. 1. Пирамида задержек.

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

Название хранилища Время доступа
Регистры 1-2нс
Кэш 1 уровня (8-64кб) 3-10нс
Кэш 2 уровня (64кб-2мб) 25-50нс
Общая память 30-90нс
Диск 5-20мс
Оптический диск 100мс-5сек
Магнитная лента 10сек-3мин

Естественно, что, чем ниже время доступа, тем “дороже” это хранилище. Однако большая часть из этого списка недоступна, но разработчик может всегда использовать общую память или диск. Время доступа у них различается достаточно серьезно, поэтому вопроса о том, кэшировать или не кэшировать, стоять не должно.

 

Начало работы

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

1) Перейдите на вкладку Service Bus, Access Control & Caching (рис. 2).

image

Рис. 2. Вкладка Service Bus, Access Control & Caching.

2) Выберите Caching в списке сервисов.

3) Нажмите кнопку New в верхнем меню, чтобы открылся диалог создания нового пространства имен для сервиса кэширования (рис. 3).

image

Рис. 3.

4) Введите название пространства имен, выберите страну-регион (учитывайте ближайшее к вашему сервису расположение!) и размер кэша. Четко планируйте размер кэша и не выбирайте больше чем надо, иначе можно заплатить выше планируемого, и существенно выше (подробнее – https://www.windowsazure.com/en-us/pricing/calculator/advanced/) (рис. 4). Нажмите Create Namespace.

image

Рис. 4. Настройка пространства имен для сервиса кэширования.

Теперь, выбрав созданное пространство имён, верхняя функциональная панель перестанет быть серой (рис. 5).

image

Рис. 5.

В этой панели доступна основная функциональность по работе с пространством имен сервиса кэширования. Нажмите на Change Cache Size, чтобы получить диалоговое окно с возможностью увеличить или уменьшить размер кэша (рис. 6).

image

Рис. 6. Диалоговое окно управления размером кэша.

Обратите внимание, что вы можете менять размер кэша раз в день, и при этом вы не можете менять его размер в тот же день, в который вы создали это пространство имен.

Нажав на кнопку View Client Configuration, вы можете получить код, который необходимо вставить в app.config или web.config вашего приложения для начала использования этого пространства имен (рис. 7).

image

Рис. 7. Конфигурация пространства имен сервиса кэширования.

Ваше пространство имен автоматически защищается сервисом Access Control Service и вам выдается токен, который и используется для аутентификации ваших запросов в системе.

Использование в приложении

При создании (или после создания) проекта (в нашем случае это ASP.NET MVC 3 проект) вы можете пойти двумя путями – либо работать с конфигурацией вручную, либо установить с помощью NuGet специальный плагин для Windows Azure Caching. Разумеется, гораздо удобнее второй способ, и именно им мы и воспользуемся.

Для установки:

1) Открыв решение, перейдите в соответствующую вкладку – Tools->Library Package Manager и нажмите Manage NuGet Packages for Solution (рис. 8).

image

Рис. 8. Открытие NuGet-менеджера для решения.

2) Введите в строку поиска windowsazure.caching (рис. 9) и нажмите Install.

image

Рис. 9. Найденный проект Windows Azure Caching.

Что произойдёт после установки плагина? Ничего особенного – за вас сделают всю работу по прописыванию boilerplate code везде, где необходимо. Давайте посмотрим, что же произошло (и где) после установки плагина.

Первое, и самое главное, изменение – добавление конфигурационного кода в web.config (того самого, который доступен по кнопку View Client Configuration).

 

<dataCacheClients>
    <dataCacheClient name="default">
      <hosts>
        <host name="[Insert Cache EndPoint]" cachePort="22233" />
      </hosts>
      <securityProperties mode="Message">
        <messageSecurity authorizationInfo="[Encrypted ACS token goes here]"></messageSecurity>
      </securityProperties>
    </dataCacheClient>
    <dataCacheClient name="SslEndpoint">
      <hosts>
        <host name="[Insert Cache EndPoint]" cachePort="22243" />
      </hosts>
      <securityProperties mode="Message" sslEnabled="true">
        <messageSecurity authorizationInfo="[Encrypted ACS token goes here]"></messageSecurity>
      </securityProperties>
    </dataCacheClient>
  </dataCacheClients>

Данные для “болванок” в квадратных скобках берутся из панели Properties при выборе пространства имен на портале управления Windows Azure.

Также в web.config добавляются настройки кэширования для сохранения состояния сессии и кэширования вывода. Они стандартны и изменять в них ничего не требуется. Если не надо сохранять состояние сессии и кэшировать вывод – можно закомментировать эти куски кода или вообще удалить.

<sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider">
      <providers>
        <add name="AppFabricCacheSessionStoreProvider" type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache" cacheName="default" useBlobMode="true" dataCacheClientName="SslEndpoint" />
      </providers>
    </sessionState>
    <caching>
      <outputCache defaultProvider="DistributedCache">
        <providers>
          <add name="DistributedCache" type="Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider, Microsoft.Web.DistributedCache" cacheName="default" dataCacheClientName="default" />
        </providers>
      </outputCache>
    </caching>

Перейдём к программированию. Конкретно это приложение будет просто забирать блоб сначала из хранилища, потом из кэша. Представим, что в хранилище блобов у нас уже есть один контейнер и один блоб размером 25 мб (рис. 10). На скриншоте изображен Azure Storage Explorer, удобнейшее средство для управления аккаунтом хранилища. Его можно скачать по ссылке http://azurestorageexplorer.codeplex.com/ .

image

Рис. 10. Содержимое контейнера.

Подставьте соответствующие значения в болванки в web.config – собственно, там необходимо вставить только наименование пространства имен и токен для Access Control Service. Всё это находится в панели Properties для выбранного пространства имен (рис. 11).

image

Рис. 11. Панель Properties для выбранного пространства имён.

Добавьте соответствующие библиотеки в ваш проект. Библиотеки находятся в папке Windows Azure SDK (рис. 12).

image

Рис. 12. Расположение библиотек для сервиса кэширования.

В моем проекте создано два дополнительных класса – CachingLayer.cs и BlobExample.cs (рис. 13). Ниже приведен код обоих классов, а также класса HomeController.cs и представления Index для действия Index контроллера Home с комментариями.

image

Рис 13. Структура проекта ASP.NET MVC3, привязанного к проекту Windows Azure.

Код класса CachingLayer, реализующего создание одного объекта DataCacheFactory, синглтона, так как создание этого объекта – достаточно тяжелое и дорогостоящая операция для того, чтобы выполнять его при каждой необходимости использовать кэш.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.ApplicationServer.Caching;

namespace MvcWebRole1.CachingLogic
{

        public static class CachingLayer
        {
            private static readonly DataCacheFactory factory = new DataCacheFactory(new DataCacheFactoryConfiguration("default"));

            public static DataCache GetCache()
            {
                return factory.GetDefaultCache();
            }

        }
    }

Итак, сначала импортируется необходимое пространство имён Microsoft.ApplicationServer.Caching. Далее в статическом классе CachingLayer создаётся синглтон-объект factory и определяется метод GetCache(), возвращающий объект типа DataCache. При этом мы используем метод GetDefaultCache, то есть возвращаем кэш по умолчанию, определенный в администраторской панели на портале управления. Windows Server AppFabric позволяет иметь несколько именованных кэшей, однако его брат на платформе Windows Azure – Только один. Что касается создания объекта factory – в конструктор DataCacheFactory передается имя конфигурации для использования. При этом, если использовать конструктор без параметра, он опять же загрузит конфигурацию по умолчанию. Если же необходимо загрузить конфигурацию с другим именем, нужно явно указать это имя в параметре.

Код класса BlobExample.cs, реализующего одну операцию – получение блоба – в двух вариантах, из хранилища блобов и из кэша.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.ApplicationServer.Caching;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;

namespace MvcWebRole1.CachingLogic
{
    public static class BlobExample
    {
        private static readonly CloudStorageAccount storageAccount =
            CloudStorageAccount.Parse(
                "DefaultEndpointsProtocol=https;AccountName=[];AccountKey=[]);
        public static byte[] getBlob()
        {
            CloudBlobClient cloudBlobClient = new CloudBlobClient(storageAccount.BlobEndpoint, storageAccount.Credentials);
            CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("mycontainer");
            return cloudBlobContainer.GetBlobReference("text.txt").DownloadByteArray();
        }

        public static byte[] getBlobFromCache()
        {
            var data = CachingLayer.GetCache().Get("text.txt");
            if (data == null)
            {
                byte[] blob = getBlob();
                CachingLayer.GetCache().Put("text.txt", blob, TimeSpan.FromMinutes(10));

            }
            return (byte[])data;

        }
    }
}

В данном классе два метода и немного конфигурации. По конфигурации все прозрачно и понятно – согласно разложенному аргументу метода Parse() создается экземпляр типа CloudStorageAccount. В методе getBlob() создаётся облачный клиент блоба, который и содержит основную функциональность по управлению контейнерами и блобами, затем создаётся контейнер (либо получается ссылка на него), после чего получается ссылка на блоб text.txt и сам блоб скачивается в виде массива байт (один из методов скачивания блобов). Во втором методе getBlobFromCache(), сначала из кэша получается объект, затем проверяется, есть ли в кэше данный объект и, если нет, кладётся туда с указанием имени, собственно, контента блоба и временем, на которое будет закэширован данный объект (не более 48 часов – ограничение, накладываемое реализацией Caching для Windows Azure).

Объект DataCache содержит в себе следующие методы:

1. Get: Получение объекта из кэша с указанным именем (ключом).

2. Add: Добавление объекта с указанным ключом в кэш. Данного объекта с данным ключом не должно существовать, иначе будет выброшено исключение.

3. Put: Добавление объекта с указанным ключом в кэш либо замена уже существующего объекта с этим ключом.

4. Remove: Удаление объекта с указанным ключом из кэша.

5. GetCacheItem: Получение объекта из кэша вместе с метаданными и версией этого объекта в виде экземпляра типа DataCacheItem.

 

Код контроллера HomeController, где происходит вызов созданных ранее методов.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.WindowsAzure.StorageClient;

namespace MvcWebRole1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Stopwatch stopWatch = Stopwatch.StartNew();
            byte[] blobFromBlobStorage =
            CachingLogic.BlobExample.getBlob();
            stopWatch.Stop();
            ViewData["blobStorageCount"] = stopWatch.ElapsedMilliseconds;

            stopWatch = Stopwatch.StartNew();
            byte[] blobFromCachingService =
            CachingLogic.BlobExample.getBlobFromCache();
            stopWatch.Stop();
            ViewData["blobCacheCount"] = stopWatch.ElapsedMilliseconds;
            return View();
        }

        public ActionResult About()
        {
            return View();
        }
    }
}

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

@{
    ViewBag.Title = "Home Page";
}

Прошло времени в процессе получения блоба из хранилища: @ViewData["blobStorageCount"]
Прошло времени в процессе получения блоба из кэша: @ViewData["blobCacheCount"]

Обратите внимание, что выгода в кэшировании будет ярко видна при объектах больших размеров, с объектами маленьких размеров время доступа к кэшу может быть даже больше, чем к хранилищу.

Результаты, полученные при развертывании приложения в Windows Azure, весьма показательны. Напоминаю, что размер блоба – 25 мб. (рис.14).

image

Рис. 14. Результаты выполнения приложения.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: