Сегодня сложно представить какую-либо высоконагруженную систему, в которой можно было бы обойтись без кеширования данных. Поэтому практически всегда используются те или иные механизмы кеширования. В контексте облачных решений это даёт следующие преимущества:
  • увеличение скорости чтения/записи данных, что позволяет уменьшить время отклика системы;
  • обеспечения «общей памяти» для различных экземпляров, что является одним из необходимых условий горизонтального масштабирования
  • снижение стоимости, за счёт более редкого обращения к базе данных (чтение из БД является более дорогой операцией, по сравнению со чтением значения из кеша)

В данной публикации я хотел бы рассмотреть, что доступно на сегодняшний день для разработчиков платформы Azure в качестве механизмов кеширования данных. Для тех кто давно работает со службами кеша тут будет мало интересного, так как всё будет рассмотрено поверхностно, но для тех кто только начинает с этим работать, я постараюсь дать хорошую стартовую точку для дальнейшего более глубокого знакомства с темой.

Azure предлагает несколько моделей организации кеширования:


Кеш в роли (In-Role Cache)


В данной модели кэш входит в состав облачной службы, внутри которой выбирается роль для размещения кеша. Все экземпляры выбранной роли объединяют ресурсы памяти и образуют кластер кеша (*).
(*) кластер кеша
Так как роли Azure могут быть представлены несколькими экземплярами (виртуальными машинами), то в случае более одного экземпляра будет сформирована распределённая служба кеша, которая будет использовать объединенную память всех машин обслуживающих роль.

Поддерживается две топологии развертывания:
  • Совместное расположение (co-located) – роль обслуживает не только кеш, но и код других приложений; в настройках роли необходимо указать % от общего объёма памяти роли, который будет отдан для нужд кеширования
  • Выделенное расположение (dedicated) – выделяется отдельная Worker роль, все ресурсы которой будут использоваться для обслуживания кеша

Так же данная модель поддерживает концепцию именованных кешей, позволяющая задать индивидуальные политики кеширования для каждого именованного кеша. Кеш с именем Default создаётся по умолчанию и не может быть удалён. Ниже представлен пример настроек параметров на вкладке Кэширование в параметрах роли в Visual Studio:

Для того, чтобы воспользоваться созданной службой кеша, клиенты должны выполнить следующие шаги:
  1. Добавить Nuget пакет, в проект, который будет использовать кеш. Это добавит все необходимые библиотеки а также обновит файл web.config, добавив в него новые секции <dataCacheClients/> и <cacheDiagnostics/>.

  2. Указать имя роли (identifier), обслуживающей кластер кеша, в соответствующей секции файла web.config:

  3. Создать экземпляр DataCache в коде

    или

  4. Воспользоваться методами созданного экземпляра



К преимуществам данного подхода можно отнести простоту и гибкость настройки при развёртывании приложения (application deployment), а также более низкую стоимость по сравнению с другими. К недостаткам – необходимость самостоятельного управления сервисом (в случае с Managed Cache Service или Azure Radis Cache управление на себя берёт компания Microsoft).
Для более подробного знакомства можно обратиться к следующей странице на сайте документации Azure.

Управляемая служба кеша (Managed Cached Service)


Несмотря на то, что еще в конце 2013 года данная модель находилась в режиме предварительного просмотра (preview), сегодня её использование перестало быть рекомендованным. Вместо неё Microsoft предлагает использование Azure Redis Cache. На момент написания статьи (апрель 2015) вы не сможете создать управляемую службу кеша через Azure Management Portal, но при необходимости, можно воспользоваться Azure Powershell SDK и создать сервис из Powershell консоли.
Т.к. данная модель перестала быть рекомендованной, я не буду на ней подробно останавливаться. При необходимости можно обратиться к следующей странице на сайте документации Azure. В случае необходимости обновить существующую управляемую службу кеша на более новый тип кеша (Azure Redis Cache) можно обратиться к следующей инструкции.

Кеш Azure Redis (Azure Redis Cache)


Что такое Redis

Redis (REmote DIctionary Server) – сетевое журналируемое хранилище данных. По сути это сверхбыстрая база данных, которая по умолчанию хранится в оперативной памяти, но также может быть настроена для дополнительного хранения данных на жестком диске. Все данные представлены в виде словаря, в котором ключи связаны со своими типизированными значениями. Поддерживаются следующие типы данных: строки, списки (lists), множества (sets), хеш-таблицы (hashsets) и упорядоченные множества (sorted sets).

Установка Redis

Установка Redis сервера возможна на всех основных операционных системах (Linux, OSX, BSD family, Windows). Сделать это можно согласно инструкции на официальном сайте. Стоит отметить, что официально для Windows поддержки нет, но «Microsoft Open Tech group» создала порт, который практически не отличается от оригинала и отлично подходит для ознакомления. Для использования в продакшене он не рекомендован и в нём как правило отсутствуют самые последние новшества, которые есть в официальных релизах.

Быстрый старт с Redis

Если вы никогда прежде не пробовали использовать Redis и не хотите возиться с установкой, то есть великолепный туториал, который является веб эмуляцией консольного клиента — где внизу у вас есть возможность печатать команды, а в самом окне видеть результаты их выполнения. Набрав слово TUTORIAL в командной строке, вы увидите ряд подсказок, которые проведут вас через основы использования Redis. Ниже приведён screenshot этого сайта, на котором создаётся строковое значение “Hellow World!”, доступ к которому возможен по ключу MyKey.


Клиенты Redis

В основе общения с сервером лежит очень простой механизм: клиент устанавливает TCP соединение на порт 6379 (по умолчанию) и посылает команды согласно специального протокола RESP (REdis Serialization Protocol), а сервер в ответ присылает результаты выполнения команд. Реализовав данный не сложный протокол, у вас будет своя собственная реализация клиента. Но для начала я бы рекомендовал обратиться к списку уже существующих реализаций, которые существую практически для всех современных языков — полный список клиентов можно найти тут.

Redis в контексте Azure

Если вы уже разобрались что такое Redis и как с ним работать, то остаётся буквально пару моментов, на которые стоит обратить внимание при работе в Azure Redis Cache.
  1. При создании экземпляра Azure Redis Cache будут предложены различные ценовые предложения: Basic и Standart. Для разработки, тестирования и не критических узлов системы следует использовать более дешёвую версию – Basic, которая отличается от аналогичных Standart версий отсутствием второго зеркального узла (реплики), и соответственно не подлегает соглашению об уровне обслуживания SLA. Детальней про цены можно узнать тут.

  2. Azure Redis Cache не поддерживается Azure Emulator’ом. Для локальной работы необходимо запустить свой Redis сервер (локальный или удалённый).
  3. По умолчанию мониторинг кеша выключен и для его активации необходимо выполнить ряд шагов (детали тут).
  4. После создания экземпляра кеша загляните в раздел настроек, там вы обнаружите множество полезных вещей, среди которых: включение SSL, политики поведения при достижении максимального объёма памяти, настройки прав доступа и другое.


Пример использования

Дабы не изобретать велосипед и соревноваться с тех-райтерами компании Микрософт, в этом разделе я приведу ряд ссылок на русскоязычные разделы сайта MSDN, в которых замечательно описаны основные шаги, необходимые для ознакомления с Redis в .Net приложениях.
Итак, прежде чем использовать Azure Redis Cache, нам необходимо создать и настроить экземпляр через портал управления Azure.
Далее необходимо добавить нужную реализацию клиента Redis. Рекомендованной реализацией в .Net приложениях является реализация от StackExchange, которая доступна нам в виде Nuget пакета (детали тут).

Теперь для доступа к кешу мы создаём подключение и на его основании получаем ссылку на базу данных. Благодаря ней нам открывается удобный API для общения с Azure Redis Cache. Для подробностей этих шагов снова отсылаю вас к соответствующей странице на MSDN.

Необычное использование Azure Radis Cache

Кроме классического использования кеша (для хранения долго вычисляемых значений или значений полученных из медленного хранилища), Azure Redis Cache может быть использован для хранения ASP.NET сессии (документация) или для кеширования вывода ASP.NET (документация).

Заключение


Надеюсь данный материал дал вам возможность сформировать общее представление о механизмах кеширования в Azure. Для более детального ознакомления с темой рекомендую использовать следующие ресурсы:

Комментарии (8)


  1. Kefir
    12.05.2015 11:50

    Судя по ценам, если нужен кеш меньше 13ГБ дешевле взять виртуалку с линуксом и развернуть в ней redis самостоятельно (благодаря докеру это делается одной командой).
    Для репликации понадобятся две виртуалки и немного почитать документацию — и все равно это будет дешевле.


  1. david_off Автор
    12.05.2015 13:00

    Согласен, что судя по ценам, которые мы видим на сайте, то 6Гб кеш можно соорудить из двух D2 linux серверов и сэкономить около $80 в месяц; аналог 2,5Гб кеш из двух D1 серверов, даст экономию $40 в месяц (цифры для стандарт версии). Но, нужно учитывать несколько важных моментов. Искользуя Azure Redis Cache у вас есть ряд приятных плюшек, таких как: мониторинг, настройки прав доступа, развёртывание в 3 клика и тп. Если посчитать время, которое потребуется админу на поднятие серверов и попытку соорудить что-то подобное возможностям Azure, то может оказаться, что игра не стоила свечь. И каждый раз когда нужно что-то промастабировать, изменить и т.п. мы опять будем бежать к админу и иметь завязку на человеческий фактор, который может болеть, быть занят и т.п. Так что тут решает каждый сам, что его важнее, сэкономить 50 баксов и потерять удобство и SLA или всё же переплатить и пользоваться всеми бенефитами инфраструктуры Azure.


    1. fingoldo
      13.05.2015 03:05

      «бенефитами», my ass. Пиджн-инглиш детектед! Лет ас нот микс лэнгвиджиз, ит лукс со агли! А по сути, согласен — каждый выбирает экономию либо удобство!


      1. david_off Автор
        13.05.2015 11:45

        Да, не всегда мой русский является исконно русским. Сегодня многие английские слова так плотно входят в обиход, что далеко не сразу находятся русские аналоги. Но главное не скатываться до абсурда, как это было у меня в институте. Одного человека заставили на плакатах по защите диплома переводить слово cookies и на них жирно красовались слова «печеньки» и производные от них.


        1. fingoldo
          13.05.2015 19:01

          Ха-ха, точно, аналога кукисам в русском нет! ) вот в этом случае калька — единственный выход… А вообще Никитин как-то высказывался, что у них есть только мэйлы, а у нас письма и мэйлы. И друзья и френды вовсе не одно и то же ) Но в тех случаях, когда смысл равнозначен, я всё же голосую за использование устоявшихся обозначений, если они есть. А слово «преимущество» в русском уже есть )) А если хочется добавить англицизмов, хорошо смотрится использование кавычек. Переплатить и пользоваться всеми «бенефитами» инфраструктуры Azure. Ну, это личная точка зрения, конечно же )


  1. lostmsu
    13.05.2015 21:05

    Как понять в какой момент переходить от static ConcurrentDictionary<string, object> cache; внутри Web Role к хранению данных в Azure Cache?


    1. david_off Автор
      14.05.2015 00:01

      Для начала, хотелось бы разобраться что такое кеш. Ведь реализация на основе ConcurrentDictionary это не совсем кеш. Одним из важных свойств любого кеша является возможность быть ограниченным по максимальному объёму занимаемой памяти. Для Dictionary-like реализаций это далеко не просто сделать. Можно конечно условно задать максимальное количество элементов в словаре, но мы всё равно можем добавить небольшое кол-во тяжёлых объектов и в итоге такая реализация будет попахивать утечкой памяти. Поэтому ответ будет скорее всего зависеть от ваших целей.
      Если вы хотите гарантировать, что операция получения каждого дорогостоящего ресурса будет произведена не более одного раза (получили и положили в словарь), то вам вообще кеш не нужен и переходить на него не надо никогда.
      Если всё-таки, ваша цель иметь кеш, то в первую очередь он должен быть реализован как кеш. Благо начиная с .Net 4.0 у нас появились ObjectCache и его прямой потомок MemoryCache, которые очень облегчают жизнь разработчика и дают готовую In-memory реализацию правильного кеша.
      Далее, если мы говорим о переходе с MemoryCache на In-Role Cache (будь то co-located или dedicated), то преимуществ особо я не могу придумать. Максимум что приходит в голову, это более удобное планирование ресурсов (мы можем контролировать максимально возможный объём занимаемой памяти и размещение его в топологии нашей системы через конфигурационный файл нашего Cloud Service-a). Ещё, как по мне, декларативно выделенный кеш в виде отдельного компонента, выглядит более логичнее и проще для правильного конфигурирования. Так же, это может быть маленький шажочек на пути к горизонтальному масштабированию. Ведь если мы в Azure, то наверняка мы должны быть готовы к резкому увеличению нагрузки на систему и тогда, увеличивая количество экземпляров наших WebRole, мы должны иметь возможность сделать кеш общедоступным всем экземплярам. Иначе каждая роль будет иметь свой кеш, и ценность такого кеша будет падать (мы будем всегда читать более одного раза одно и тоже значение, даже если само значение только что вычитано, но наш балансировщик нагрузки направит запросы разным экземплярам WebRole), В случае с MemoryCache, хранимого в одной роли, добиться общедоступности будет сделать не просто.
      Переход на Redis может так же дать какой-то выигрыш производительности за счёт специфики реализации самого Redis, плюс открыть возможности реализации например Publisher-Subscriber механизма.
      Т. е. ещё раз повторюсь, всё зависит от того, что вы хотите в итоге получить и очень сложно дать дельный совет по вашему вопросу, не будучи знакомым с особенностями проекта.


      1. david_off Автор
        14.05.2015 00:10

        Вообще, написав такой долгий момент, думаю есть смысл сделать отдельный пост про «что такое кеш», что есть готовое в .Net и как этим пользоваться. Надеюсь не полениться и написать об этом в ближайшем будущем