РАСПРЕДЕЛЕННЫЕ СИСТЕМЫ

Эта статья представляет собой подробное руководство по распределенному кэшу. Он охватывает все часто задаваемые вопросы о нем, например, что такое распределенный кеш? Какая в этом необходимость? Чем он архитектурно отличается от традиционного кэширования? Каковы варианты использования распределенных кэшей? Какие популярные распределенные кэши используются в отрасли?

Итак, без лишних слов.
Давайте продолжим.

Прежде чем перейти к распределенному кэшированию. Было бы неплохо получить представление о кэшировании. В конце концов, почему мы используем кэширование в наших веб-приложениях?

1. Что такое кэширование? И почему мы используем его в наших веб-приложениях?

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

Кэширование служит нижеуказанным целям в веб-приложениях.

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

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

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

Кэширование можно использовать на каждом уровне архитектуры веб-приложений, будь то база данных, CDN, DNS и т. д.

1.1 Как кэширование помогает снизить вычислительные затраты приложения?

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

Бывают случаи, когда в приложении слишком много записей, например, в массовых многопользовательских онлайн-играх.

Данные, которые не имеют такого большого приоритета, могут быть просто записаны в кеш, а периодические пакетные операции могут выполняться для сохранения данных в базе данных. Это помогает значительно сократить затраты на запись в базу данных.

Ну, это то, что я сделал, когда развернул игру, которую написал, и в Google Cloud. Я использовал службу Google Cloud Datastore NoSQL. Этот подход очень помог с затратами.

Теперь, когда мы поняли, что такое кэш и кэширование. Перейдем к распределенному кэшированию.

Рекомендуемая литература: Лучшие отобранные ресурсы для создания прочной основы архитектуры программного обеспечения и проектирования систем

2. Что такое распределенное кэширование? Какая потребность в этом?

Распределенный кеш — это кеш, данные которого распределены по нескольким узлам в кластере, а также по нескольким кластерам в нескольких дата-центрах, расположенных по всему миру.

Развертывание на нескольких узлах помогает с горизонтальной масштабируемостью, экземпляры могут добавляться на лету в соответствии с требованиями.

Распределенное кэширование сегодня в основном используется в отрасли из-за возможности масштабирования по требованию и высокой доступности.

Масштабируемость, высокая доступность, отказоустойчивость имеют решающее значение для крупномасштабных онлайн-сервисов, работающих сегодня. Предприятия не могут позволить себе отключить свои услуги. Подумайте о здравоохранении, фондовых рынках, армии. У них нет возможности спуститься вниз. Они распределены по нескольким узлам с довольно солидной степенью избыточности.

Распределенный кэш, и не только кэш, распределенные системы являются предпочтительным выбором для облачных вычислений исключительно из-за возможности масштабирования и доступности.

Google Cloud использует Memcache для кэширования данных на своей общедоступной облачной платформе. Redis используется интернет-гигантами для кэширования, хранилища данных NoSQL и ряда других вариантов использования.

3. Чем распределенное кэширование отличается от традиционного/локального кэширования?

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

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

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

4. Каковы варианты использования распределенного кэша?

Распределенные кэши имеют несколько вариантов использования, указанных ниже:

Кэширование базы данных

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

Хранение пользовательских сессий

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

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

Межмодульное взаимодействие и общее хранилище

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

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

Обработка и аналитика потока данных в памяти

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

Это полезно во многих ситуациях, таких как обнаружение аномалий, мониторинг мошенничества, статистика онлайн-игр в режиме реального времени, рекомендации в реальном времени, обработка платежей и т. д.

5. Как работает распределенный кэш? — Дизайн и архитектура

Проектирование распределенного кэша требует отдельной подробной статьи. А пока я дам вам краткий обзор того, как распределенный кеш работает за кулисами?

Распределенный кэш — это распределенная хеш-таблица, которая отвечает за сопоставление значений объекта с ключами, распределенными по нескольким узлам.

Распределенная хеш-таблица позволяет масштабировать распределенный кеш на лету, она постоянно управляет добавлением, удалением и сбоем узлов, пока служба кеша находится в сети. Распределенные хэш-таблицы изначально использовались в системах peer-to-peer.

Говоря о дизайне, кэширует вытесняемые данные на основе политики LRU наименее недавно использованного. В идеале он использует Linked-List для управления указателями данных. Указатель часто используемых данных постоянно перемещается в начало списка/очереди. Очередь реализована с использованием связанного списка.

Данные, которые не так часто используются, перемещаются в конец списка и в конечном итоге удаляются.

Linked-List — это подходящая структура данных, в которой слишком много вставок и удалений, обновлений в списке. Он обеспечивает лучшую производительность по сравнению с ArrayList.

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

Также распределенный кеш часто работает с распределенными системными координаторами, такими как Zookeeper. Это облегчает связь и помогает поддерживать согласованное состояние между несколькими работающими узлами кэша.

6. Какие существуют типы стратегий распределенного кэширования?

Существуют различные виды стратегий кэширования, которые служат конкретным случаям использования. Это кэш-память, кэш-память для чтения, кэш-память для сквозной записи и обратная запись.

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

Кэш в сторону

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

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

Такая стратегия лучше всего работает с рабочими нагрузками с большим количеством операций чтения. Тип данных, которые редко обновляются, например, данные профиля пользователя на портале. Его имя, номер счета и т.д.

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

Во избежание этого данные в кеше имеют TTL Time to Live. По истечении этого установленного периода данные из кеша становятся недействительными.

Введение

Распределенная система кэширования Pinterest, построенная на базе технологий с открытым исходным кодом memcached и mcrouter, является важнейшим компонентом стека производственной инфраструктуры. Платформа Pinterest кеш как услуга отвечает за снижение задержки приложений по всем направлениям, сокращение общих затрат на облако и обеспечение соблюдения строгих целевых показателей доступности на всей площадке.

Сегодня парк memcached Pinterest включает более 5000 инстансов EC2 в различных типах инстансов, оптимизированных по параметрам вычислений, памяти и хранилища. В совокупности парк обслуживает до ~ 180 миллионов запросов в секунду и пропускную способность сети ~ 220 ГБ / с в активном наборе данных объемом около 460 ТБ в памяти и на диске, разделенном на ~ 70 отдельных кластеров.

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

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

Общее описание доступной рабочей области для оптимизации производительности для memcached, работающего на виртуальных машинах в общедоступных облачных средах

Мониторинг, наблюдаемость и оценка

Все усилия по оптимизации производительности начинаются с точного количественного измерения и структурированного воспроизводимого механизма создания рабочих нагрузок для изолированной оценки.

Предпосылки критического мониторинга для всех оценок эффективности, проводимых на протяжении многих лет, включают:

  • Показатели на стороне сервера для пропускной способности запросов, пропускной способности сети, использования ресурсов и параметров на уровне оборудования (статистика сетевых адаптеров, такая как пропускная способность пакетов для каждой очереди и исчерпание разрешений EC2, время отклика диска и запросы ввода-вывода в процессе выполнения и т. д.)
  • Показатели на стороне клиента для процента задержки запроса кэша, времени ожидания и частоты ошибок, а также доступности для каждого сервера (SLI), а также индикаторы производительности приложений верхнего уровня, такие как время отклика службы RPC P99.

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

  • Создание искусственной нагрузки: memtier_benchmark — это инструмент с открытым исходным кодом, способный генерировать синтетическую нагрузку на кластер memcached с настраиваемыми параметрами для количества одновременных клиентов и потоков, отношения чтения/записи, размеров данных и механизма передачи. (открытый текст или TLS).
  • Производственный теневой трафик: mcrouter – это прокси-сервер маршрутизации с протоколом кэширования памяти с открытым исходным кодом, развернутый в качестве вспомогательного компонента на стороне клиента в парке Pinterest. Он предоставляет строительные блоки для разработки прозрачных политик маршрутизации теневого трафика с настраиваемыми процентами трафика и кластерами источника/цели, что позволяет гибко экспериментировать с темным трафиком в различных классах рабочей нагрузки.

Вместе эти инструменты позволяют проводить оценку производительности с высоким уровнем сигнала с нулевым или минимальным влиянием на производственный трафик критического пути.

Как кэширование помогает (ИЛИ)преимущества кэширования

1. Производительность приложений
2. Нагрузка на серверную часть
3. Пропускная способность
4. Предсказуемая производительность
5. Стоимость базы данных

  • Производительность приложения:

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

  • Бэкэнд-загрузка:

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

  • Пропускная способность:

Системы с оперативной памятью предлагают меньшую задержку и более высокую скорость обработки запросов (операций ввода/вывода в секунду) по сравнению с реальной базой данных, обслуживая все больше и больше запросов в секунду.

  • Предсказуемая производительность:

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

  • Стоимость базы данных:

Стоимость базы данных будет снижена, поскольку один экземпляр кэша, заменяющий экземпляры базы данных, может выполнять множество операций ввода-вывода в секунду.

Что такое распределенный кэш?

Распределенный кеш — это метод кэширования, при котором кеш распределяется по нескольким машинам по нескольким узлам, разбросанным по кластерам, а иногда и по центрам обработки данных, расположенным по всему миру.

Распределенный кеш в основном используется для

  • Высокая доступность. Как следует из названия, распределение кеша по нескольким компьютерам помогает нам повысить доступность кеша. Если один из экземпляров по какой-то причине выходит из строя, мы все равно можем получить поддержку от других машин, которые разделили нагрузку. Мы также можем создать резервную копию для каждого экземпляра, чтобы всегда поддерживать определенное количество экземпляров с зарезервированными пассивными экземплярами.
  • Масштабируемость. Его будет легко масштабировать, поскольку данные будут храниться в нескольких местах, благодаря чему кеш остается легким и меньшим по размеру, что, в свою очередь, помогает выполнять операцию поиска. в хорошем темпе.

Шаблоны/политики кэширования:

Вот некоторые из наиболее часто используемых шаблонов кэширования.

1. Кэширование
2. Сквозное чтение
3. Сквозная запись
4. Обратная/отложенная запись
5. Обратная запись
6. Упреждающее обновление

  • Кэш в сторону —

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

На Рис. 1 — когда мы запрашиваем определенные данные, приложение сначала ищет их в кеше (операция-1). Когда приложение не может найти совпадающие данные в кеше, оно отступает (операция-2) и извлекает то же самое из базы данных (как в операции 3 и 4), и то же самое будет обновлено в кеше для будущих извлечений и возврата. данные обратно пользователю.

На Рис. 2 — когда мы запрашиваем определенные данные, приложение сначала ищет их в кеше (операция-1) и возвращает то же самое, если находит соответствие данные в кэш (операция-2).

  • Прочитать —

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

На рис. 1 — когда кеш запрашивают данные, связанные с определенным ключом (операция-1), и если он не существует (операция-2), то кеш извлекает данные из хранилища данных и помещает их в кеш для будущих извлечений (операция-3) и, наконец, возвращает значение обратно вызывающей стороне.

На рис. 2 — когда кеш запрашивают данные, связанные с определенным ключом (операция-1), и если они существуют (операция-2), то то же самое будет возвращаться обратно вызывающему абоненту.

  • Записать через —

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

  • Написать ответ

В этом методе мы делаем несколько записей данных непосредственно в кэш (операция-1 и операция-2), но не одновременно в хранилище данных (операция-3). Вместо этого мы ставим в очередь данные, которые, как мы предполагаем, должны быть вставлены/обновлены, в кэш и реплицируем поставленные в очередь данные в хранилище данных на более поздних этапах.

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

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

  • Написать вокруг —

В этом шаблоне данные будут записываться непосредственно в хранилище данных, не записывая их в кеш (operatoin-1). При операции чтения из хранилища данных то же самое будет помещено в кеш (как в операции 2 и 3).

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

  • Предварительное обновление

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

Методы/алгоритмы удаления кэширования (очистки)

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

  • Наименее недавно использовавшиеся (LRU) –обновляет кеш с недавно использовавшимися элементами поверх кеша в зависимости от доступности кеша. Когда предел кеша заполнен, мы удаляем из кеша элементы, к которым наименее недавно обращались.
  • Наименее часто используемые (LFU) — мы в основном увеличиваем значение каждый раз, когда данные получают доступ из кеша, в этом случае элемент с наименьшим количеством будет исключен (удален). первый.
  • First In First Out (FIFO). Как следует из названия, мы удаляем первый элемент, доступ к которому был осуществлен первым, без учета того, как часто или сколько раз к нему обращались в прошлом.
  • Last In First Out (LIFO) – это означает, что удаляется элемент, который использовался последним, независимо от того, сколько раз или как часто к нему обращались в прошлом.
  • Самые недавно использованные (MRU) –это действительно помогает, когда старые элементы с большей вероятностью будут использоваться.фактически мы сначала удаляем элементы, к которым недавно обращались.

Случаи использования:некоторые распространенные варианты использования

1.Кэширование базы данных
2.Веб-кэширование
3.Облако
4.DNS — система доменных имен
5.CDN — сеть доставки контента
6.Управление сеансами< br /> 7.API — Интерфейсы прикладного программирования

Производительность и эффективность

Облачное оборудование

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

  • Пропускная способность (вычисления)
  • Объем данных (память и/или емкость диска)
  • Пропускная способность данных (сеть и вычисления)
  • Требования к задержке (вычисления)

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

Профиль рабочей нагрузки: умеренная пропускная способность, умеренный объем данных.

Семейство экземпляров EC2: r5

Обоснование: экземпляры семейства r5 предлагают соотношение виртуальных ЦП и DRAM, которое хорошо подходит для большинства вариантов использования ванильного кэша в Pinterest. Этот тип экземпляра считается «базовым уровнем», по которому оцениваются другие экземпляры.

Профиль рабочей нагрузки: высокая пропускная способность, небольшой объем данных

Семейство экземпляров EC2: c5

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

Профиль рабочей нагрузки: большой объем данных, низкие требования к задержке.

Семейство экземпляров EC2: r5d

Обоснование: экземпляры семейства r5d функционально эквивалентны экземплярам семейства r5, но с совмещенным с экземпляром твердотельным накопителем NVMe, используемым extstore в качестве вторичного хранилища. r5d экономически эффективен для кластеров с большим объемом данных, так что есть ощутимые улучшения в частоте попаданий при записи данных на диск. Из-за более медленного диска (по сравнению с экземплярами семейства i3) ожидается более высокая задержка хвоста.

Профиль рабочей нагрузки: большой объем данных, низкие требования к задержке.

Семейство экземпляров EC2: i3 и i3en

Обоснование: инстансы семейства i3 и i3en поставляются с быстрым и вместительным диском, размещенным в одном инстансе, что ощутимо повышает производительность extstore для рабочих нагрузок с очень высоким соотношением рабочих данных на диске к DRAM. Кроме того, они предлагают объем памяти, сравнимый с инстансами серии r5, что снижает перегрузку extstore за счет поддержания разумного соотношения использования DRAM и диска.

Распределение типов инстансов EC2 для парка кэшированных данных Pinterest

В частности, использование extstore для расширения емкости хранения за пределы DRAM на локальный уровень флэш-дисков NVMe повышает эффективность хранения каждого экземпляра на несколько порядков и пропорционально снижает связанные с этим затраты на кластер. Типы инстансов EC2, оптимизированные для хранения, предоставляют локально подключенные твердотельные накопители с высокой произвольной пропускной способностью IOPS и R/W, что позволяет использовать варианты использования extstore с большими объемами данных и высокой пропускной способностью запросов без ущерба для хвостовой задержки.

Внедрение различных типов инстансов EC2, оптимизированных для хранения, в парк (в частности, варианты более низкого уровня семейства инстансов i3en, содержащие несколько независимых дисков на инстанс) еще больше снижает затраты, предлагая улучшения в производительности ввода-вывода и затратах. эффективность. Pinterest настраивает эти экземпляры с программным RAID-массивом Linux на уровне RAID0, чтобы объединить несколько аппаратных блочных устройств в один логический диск для использования пользовательского пространства. Распределяя операции чтения и записи по двум дискам, RAID0 удваивает максимальную теоретическую пропускную способность ввода-вывода с двукратным сокращением эффективного времени отклика диска за счет удвоенного среднего времени безотказной работы. Такая повышенная производительность оборудования для extstore за счет увеличения теоретической частоты отказов является очень выгодным компромиссом. Выполнение рабочих нагрузок в общедоступном облаке требует проектирования инфраструктуры, которая должна быть эфемерной, способной к самовосстановлению в случае сбоя экземпляра. Плоскость управления топологией для mcrouter автоматически и корректно реагирует на неожиданные изменения производительности сервера; потеря экземпляра не является проблемой.

Вычислить

Примерно половина всех рабочих нагрузок кэширования в Pinterest связана с вычислительными ресурсами (т. е. связана исключительно с пропускной способностью запросов). Успешная оптимизация эффективности вычислений позволяет уменьшить размер кластеров без ущерба для пропускной способности.

Точнее, эффективность вычислений для memcached определяется как дополнительная скорость запросов, которые могут быть обслужены одним экземпляром на каждый процентный пункт увеличения использования ЦП экземпляра без увеличения задержки запросов. Проще говоря, оптимизация, повышающая эффективность вычислений, — это та, которая позволяет memcached обслуживать более высокую скорость запросов при меньшем использовании ЦП без изменения характеристик задержки запросов.

В Pinterest большинство рабочих нагрузок (включая парк распределенного кэша) выполняются на выделенных виртуальных машинах EC2. Многие исторические улучшения эффективности связаны с оптимизацией на самом аппаратном уровне, такой как миграция на другие семейства инстансов или обновление до более новых поколений существующих типов инстансов. Однако рабочие нагрузки на выделенных (виртуализированных) машинах предлагают уникальные возможности оптимизации на границе аппаратного и программного обеспечения.

Memcached несколько уникален среди систем данных с отслеживанием состояния в Pinterest, поскольку это исключительная основная рабочая нагрузка со статическим набором долгоживущих рабочих потоков на каждом экземпляре EC2, на котором она развернута. Это отличается от рабочих нагрузок базы данных, которые могут иметь, например, несколько совместно расположенных процессов для несвязанных уровней хранения и обслуживания. С этой целью одной простой, но очень эффективной оптимизацией является настройка планирования процессов, чтобы запросить у ядра приоритет процессорного времени для memcached за счет преднамеренного удержания процессорного времени от других процессов на хосте, таких как демоны мониторинга. Это включает в себя запуск memcached в соответствии с политикой планирования в реальном времени SCHED_FIFO с высоким приоритетом — указание ядру эффективно разрешить memcached монополизировать ЦП, вытесняя (и, таким образом, преднамеренно голодая) все процессы, не работающие в реальном времени, всякий раз, когда поток memcached становится недоступным. работающий.

$ sudo chrt — — fifo ‹приоритет› memcached …

Пример вызова memcached в соответствии с политикой планирования в реальном времени SCHED_FIFO

Это однострочное изменение после развертывания во всех вычислительных кластерах снизило задержку P99 на стороне клиента на величину от 10 до 40 %, а также устранило ложные всплески задержки P99 и P999 по всем направлениям. Кроме того, это дало возможность поднять потолок использования ЦП в стационарном режиме на 20% без регрессии задержки. В конечном итоге это сократило общие затраты memcached почти на 10%.

Сравнение задержки кэша P99 на стороне клиента для одной службы по неделям, в то время как планирование в реальном времени было развернуто для соответствующего выделенного кластера memcached

Соотношение времени, затрачиваемого memcached на ожидание выполнения ядром, по сравнению со временем настенных часов до и после включения планирования в реальном времени (данные собираются из schedstat в файловой системе /proc)

Стабилизация ложных всплесков задержки после включения планирования в реальном времени на канареечном хосте (серии красного цвета)

Сеть

Есть несколько ключевых аспектов при рассмотрении производительности сети:

  • Ограничения пропускной способности данных, пропускной способности пакетов и TCP-подключений. EC2 накладывает жесткие ограничения на PPS для каждого экземпляра, совокупную пропускную способность и TCP-подключения (но только при развертывании в группе безопасности с входными правилами TCP). . О чрезмерном использовании за пределами этих ограничений сообщает драйвер Elastic Network Adapter (ENA), доступ к которому можно получить через ethtool. Как ни странно, EC2 также выражает общую пропускную способность NIC в терминах импульсных нагрузок, а не устойчивых нагрузок, поэтому требуется определенная степень проб и ошибок для определения практического потолка пропускной способности для рабочих нагрузок, таких как memcached, с предсказуемыми характеристиками сети.
  • Задержка и надежность соединения. Есть ли способ сделать первоначальные TCP-соединения с memcached более быстрыми и надежными, особенно в сценариях резкого увеличения нагрузки, когда тысячи клиентов одновременно устанавливают соединения?
  • Накладные расходы, связанные с функциями транспортного уровня, такими как TLS. Есть ли способ уменьшить вычислительные затраты на шифрование/дешифрование TLS? Кроме того, есть ли способ снизить стоимость первоначальной настройки (т. е. рукопожатие TLS)?

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

В архитектуре кэширования Pinterest mcrouter является универсальным прокси-сервером маршрутизации и единственной точкой входа для приложения на уровень распределенного кэширования. Каждый экземпляр mcrouter (по сути, каждый отдельный хост в сервисном кластере) создает статический долгоживущий пул TCP-соединений для каждого отдельного memcached-сервера в кластере. Размеры пула подключений определяются количеством логических ядер, доступных в хост-системе, обычно от 8 до 72 для канонических типов экземпляров. Это приводит к более чем десяткам тысяч активных установленных TCP-соединений на хост-сервер и легко превышает миллион соединений на кластер серверов, что требует стратегии для поддержания минимальной задержки соединения и надежности соединения в масштабе.

TCP Fast Open (TFO) — это механизм для сокращения накладных расходов на задержку при установлении TCP-соединения за счет оптимизации одного RTT в дорогостоящем TCP 3WHS (трехстороннее рукопожатие), а также позволяет быстро передавать ранние данные во время рукопожатия. сам. Первоначально предназначенный для конечных пользователей в ненадежных домашних и мобильных сетях, подключающихся к удаленным пограничным серверам, TFO также продемонстрировал ощутимые улучшения в надежности соединения в закрытой облачной среде. Внедрение поддержки TFO в memcached сократило среднюю продолжительность TCP-подключений последовательных сеансов примерно на 10 %, что особенно заметно в соединениях, установленных через границу зоны доступности.

Обмен пакетами между клиентом и сервером во время установки файлов cookie TFO и последующего сеанса, инициированного TFO, с ранними данными

Кроме того, повышение значения параметра sysctl для net.core.somaxconn и соответствующего размера очереди прослушивания в пользовательском пространстве callsite listen(2) в memcached улучшило доступность пакетных соединений для кластеров с высокой пропускной способностью. Ранее развертывание нового бинарного файла memcached вызывало всплески ошибок сервера ECONNREFUSED, вызванные исчерпанием очередей приема TCP на стороне сервера, управляемых толпами одновременных входящих подключений от тысяч экземпляров клиентского mcrouter. Более высокий порог ожидания прослушивания сократил время простоя каждого сервера и устранил короткие, но частые нарушения SLO при развертывании общего арендного кластера.

Наконец, TLS играет важную роль в шифровании данных при передаче между memcached и mcrouter, и он включен для 100% кэш-трафика в Pinterest, чтобы соответствовать общесайтовым политикам аутентификации, авторизации и аудита. Даже при криптографии с аппаратным ускорением TLS добавляет нетривиальные начальные и служебные данные в устойчивом состоянии из-за рукопожатия TLS после подключения и шифрования/дешифрования на уровне приложений во время сетевого ввода-вывода соответственно. Возобновление сеанса TLS после реализации в memcached снизило время ожидания подключения на стороне клиента для всего парка, позволив повторно использовать ранее кэшированные сеансы TLS. Одним из способов борьбы с постоянными накладными расходами является kernel TLS (kTLS) — механизм для переноса уровня записи TLS из пользовательского пространства в ядро, реализованный либо в программном обеспечении, либо в поддерживаемом выделенном оборудовании сетевой карты для полностью прозрачного встроенного шифрования/дешифрования данных. . Возобновление сеанса TLS было передано Pinterest в memcached и доступно в версии 1.6.3 и выше; kTLS — это текущая и относительно экспериментальная область оптимизации.

Будущая работа

Оптимизация инфраструктуры является важной задачей для Pinterest, которая в конечном итоге обеспечивает более приятный опыт для пиннеров, а также снижает наши собственные затраты на облачные вычисления. Мы с нетерпением ждем продолжения изучения способов повышения производительности и эффективности кэширования на всех уровнях стека, от клиентов приложений и прокси-серверов маршрутизации до самих серверов. В ближайшем будущем мы намерены продолжить оценку TLS программного ядра, изучить совместимость memcached с новыми типами инстансов EC2 для улучшения характеристик соотношения цены и производительности, а также оптимизацию программного обеспечения на стороне приложения/прокси-сервера, например сжатие во время выполнения, для улучшения эффективность хранения. Мы надеемся дополнительно создать сквозную автоматизированную среду для регрессионного тестирования производительности, чтобы отслеживать влияние этих оптимизаций с течением времени.

Прочитать

Эта стратегия очень похожа на стратегию Cache Aside с небольшими отличиями, например, в стратегии Cache Aside система должна извлекать информацию из базы данных, если она не найдена в кеше, но в стратегии сквозного чтения кэш всегда остается согласованным. с базой данных. Библиотека кеша берет на себя ответственность за поддержание согласованности с серверной частью;

Информация в этой стратегии тоже лениво загружается в кеш, только когда пользователь ее запрашивает.

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

Хотя разработчики могут предварительно загрузить в кеш информацию, которая, как ожидается, будет наиболее востребована пользователями.

Сквозная запись

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

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

Эта стратегия используется с другими стратегиями кэширования для достижения оптимальной производительности.

Обратная запись

Я уже говорил об этом подходе во введении к этой статье. Это помогает значительно оптимизировать расходы.

В стратегии кэширования с обратной записью данные записываются непосредственно в кэш, а не в базу данных. А кеш после некоторой задержки по бизнес-логике записывает данные в базу.

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

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

7. Какие популярные распределенные кэши используются в отрасли?

Популярными распределенными кэшами, используемыми в отрасли, являются Eh-cache, Memcache, Redis, Riak, Hazelcast.

Memcache используется Google Cloud в своей платформе как сервисе. Это высокопроизводительное распределенное хранилище ключей и значений, которое в основном используется для снижения нагрузки на базу данных.

Это похоже на большую хеш-таблицу, распределенную по нескольким машинам. Включение доступа к данным в O(1) т. е. постоянное время.

Помимо наличия пары ключ-значение, Redis — это распределенная система с открытым исходным кодом в памяти, которая также поддерживает другие структуры данных, такие как распределенные списки, очереди, строки, наборы, отсортированные наборы. Помимо кэширования, Redis также часто рассматривается как хранилище данных NoSQL.

10 ошибок кэширования программ, устраняющих ошибки

Вот 10 основных ошибок (вкратце):

  1. Использование сериализатора по умолчанию. Сериализаторы по умолчанию могут использовать много ресурсов ЦП, особенно для сложных типов. Подумайте о наилучшем методе сериализации и десериализации для вашего языка и среды.
  2. Хранение больших объектов в одном элементе кэша. Из-за затрат на сериализацию и десериализацию, при одновременной нагрузке частый доступ к графам больших объектов может убить ЦП вашего сервера. Вместо этого разбейте больший граф на более мелкие подграфы и кэшируйте их отдельно. Получите только самую маленькую единицу, которая вам нужна.
  3. Использование кеша для обмена объектами между потоками. Соревнования при записи возникают, если части программы одновременно обращаются к одним и тем же кэшированным элементам. Нужен какой-то внешний запирающий механизм.
  4. Предполагается, что элементы будут помещены в кеш сразу после их сохранения. Никогда не предполагайте, что элемент будет находиться в кеше, даже после того, как он был только что записан, потому что кеш может сбрасывать элементы, когда памяти становится мало. Код всегда должен проверять возвращаемое значение null из кеша.
  5. Хранение всей коллекции с вложенными объектами. Сохранение всей коллекции, когда вам нужно получить конкретный элемент, приводит к снижению производительности из-за накладных расходов на сериализацию. Кэшируйте отдельные элементы отдельно, чтобы их можно было получить отдельно.
  6. Сохранение дочерних объектов вместе, а также по отдельности. Иногда объект одновременно содержится в двух или более родительских объектах. Чтобы один и тот же объект не хранился в двух разных местах в кеше, храните его отдельно под своим ключом. Затем родительские объекты будут считывать объекты, когда потребуется доступ.
  7. Настройки конфигурации кэширования. Храните данные конфигурации в статической переменной, которая является локальной для вашего процесса. Доступ к кэшированным данным обходится дорого, поэтому по возможности следует избегать этих затрат.
  8. Кэширование живых объектов с открытым дескриптором потока, файла, реестра или сети. Не кэшируйте объекты, которые ссылаются на такие ресурсы, как файлы, потоки, память и т. д. Когда кэшированный элемент удаляется из кэша, эти ресурсы не удаляются, а системные ресурсы утекают.
  9. Сохранение одного и того же элемента с использованием нескольких ключей. Доступ к элементу может быть удобным по ключу и номеру индекса. Это может работать, когда кеш находится в памяти, потому что кеш может содержать ссылку на один и тот же объект, что означает, что изменения в объекте будут видны через оба пути доступа. При использовании удаленного кеша любые обновления не будут видны, поэтому объекты не будут синхронизированы.
  10. Не обновлять или удалять элементы в кеше после их обновления или удаления в постоянном хранилище. Элементы в удаленном кеше хранятся как копии, поэтому обновление объекта не приведет к обновлению кеша. Кэш должен быть специально обновлен, чтобы изменения были видны всем остальным. С кэшем в памяти изменения объекта будут видны всем. То же самое для удаления. Удаление объекта не удалит его из кеша. Программа должна убедиться, что кешированные элементы удалены правильно.

Все это будет рассмотрено ниже для примера обслуживания

Распределенное кэширование
Обязательные функции в распределенном кэше
Сроки действия
Исключения
Кэширование реляционных данных
Синхронизация кэша с другими средами
Синхронизация базы данных
Сквозное чтение
Сквозная запись, отложенная запись
Запрос кэша
Распространение событий
Производительность и масштабируемость кэша
Высокая доступность
Производительность
Набирающая популярность

Если вы разрабатываете приложение ASP.NET, веб-службы или приложение для высокопроизводительных вычислений (HPC), вы, вероятно, столкнетесь с серьезными проблемами масштабируемости при попытке масштабирования и увеличения нагрузки на свое приложение. В приложении ASP.NET узкие места возникают в двух хранилищах данных. Первый — это данные приложения, находящиеся в базе данных, а другой — данные состояния сеанса ASP.NET, которые обычно хранятся в одном из трех режимов (InProc, StateServer или SqlServer), предоставляемых Microsoft. Все три имеют серьезные проблемы с масштабируемостью.

Веб-службы обычно не используют состояние сеанса, но у них есть узкие места в плане масштабируемости, когда речь идет о данных приложения. Как и приложения ASP.NET, веб-службы можно размещать в IIS и развертывать в веб-ферме для обеспечения масштабируемости.

Приложения для высокопроизводительных вычислений, предназначенные для выполнения массовых параллельных вычислений, также имеют проблемы с масштабируемостью, поскольку хранилище данных не масштабируется таким же образом. HPC (также называемые распределенными вычислениями) традиционно использовали Java, но по мере роста доли рынка .NET становится все более популярным и для приложений HPC. Приложения HPC развертываются на сотнях, а иногда и тысячах компьютеров для параллельной обработки, и им часто приходится работать с большими объемами данных и обмениваться промежуточными результатами с другими компьютерами. Приложения HPC используют базу данных или общую файловую систему в качестве хранилища данных, и оба они не очень хорошо масштабируются.

Распределенное кэширование

Кэширование — хорошо известная концепция как в аппаратном, так и в программном мире. Традиционно кэширование было автономным механизмом, но в большинстве сред он больше не работает, поскольку теперь приложения выполняются на нескольких серверах и в нескольких процессах на каждом сервере.

Распределенное кэширование в памяти — это форма кэширования, которая позволяет кэшу охватывать несколько серверов, что позволяет увеличивать его размер и емкость транзакций. Распределенное кэширование стало возможным сейчас по ряду причин. Во-первых, память стала очень дешевой, и вы можете набивать компьютеры многими гигабайтами по бросовым ценам. Во-вторых, сетевые карты стали очень быстрыми: 1 Гбит теперь является стандартом повсеместно, а 10 Гбит набирает обороты. Наконец, в отличие от сервера базы данных, для которого обычно требуется высокопроизводительная машина, распределенное кэширование хорошо работает на более дешевых машинах (таких, которые используются для веб-серверов), что позволяет легко добавлять новые машины.

Распределенное кэширование является масштабируемым благодаря используемой архитектуре. Он распределяет свою работу по нескольким серверам, но по-прежнему дает вам логическое представление об одном кеше. Для данных приложения распределенный кэш хранит копию подмножества данных в базе данных. Это должно быть временное хранилище, которое может означать часы, дни или недели. Во многих ситуациях данные, используемые в приложении, не нужно хранить постоянно. В ASP.NET, например, данные сеанса являются временными и необходимы в течение от нескольких минут до нескольких часов.

Точно так же в HPC большие части обработки требуют хранения промежуточных данных в хранилище данных, и это также носит временный характер. Однако окончательный результат HPC может храниться в базе данных. На рис. 1 показана типичная конфигурация распределенного кэша на предприятии.

Рис. 1. Распределенный кэш, совместно используемый различными приложениями на предприятии (щелкните изображение, чтобы увеличить его)

Обязательные функции распределенного кэша

Традиционно разработчики рассматривали возможность кэширования только статических данных, то есть данных, которые никогда не меняются на протяжении всего жизненного цикла приложения. Но эти данные обычно представляют собой очень небольшое подмножество — может быть, 10% — данных, которые обрабатывает приложение. Хотя вы можете хранить статические данные в кеше, реальная ценность возникает, если вы можете кэшировать динамические или транзакционные данные — данные, которые меняются каждые несколько минут. Вы по-прежнему кэшируете его, потому что в течение этого промежутка времени вы можете получить его десятки раз и сохранить столько же обращений к базе данных. Если вы умножите это на тысячи пользователей, пытающихся выполнять операции одновременно, вы можете себе представить, насколько меньше у вас операций чтения в базе данных.

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

Срок действия

Сроки действия находятся вверху списка. Они позволяют указать, как долго данные должны оставаться в кэше, прежде чем кэш автоматически удалит их. Вы можете указать два типа истечения срока действия: истечение абсолютного времени и истечение скользящего времени (или простоя).

Если данные в вашем кэше также существуют в основном источнике данных, вы знаете, что эти данные могут быть изменены в базе данных пользователями или приложениями, у которых может не быть доступа к кэшу. Когда это происходит, данные в кеше становятся устаревшими. Если вы можете оценить, как долго эти данные можно безопасно хранить в кеше, вы можете указать абсолютное время истечения срока действия — что-то вроде «Срок действия этого элемента истекает через 10 минут» или «Срок действия этого элемента истекает сегодня в полночь».

Один интересный вариант абсолютного истечения срока действия заключается в том, может ли ваш кэш перезагружать обновленную копию кэшированного элемента непосредственно из вашего источника данных. Это возможно только в том случае, если ваш кеш предоставляет функцию сквозного чтения (см. последующие разделы) и позволяет вам зарегистрировать обработчик сквозного чтения, который перезагружает кэшированные элементы, когда происходит полное истечение срока действия. За исключением нескольких коммерческих кэшей, большинство кэшей не поддерживают эту функцию.

Вы можете использовать время простоя (скользящее время) для истечения срока действия элемента, если он не используется в течение заданного периода времени. Вы можете указать что-то вроде «Срок действия этого элемента истекает, если никто не читает или не обновляет его в течение 10 минут». Этот подход удобен, когда вашему приложению нужны данные временно, но как только приложение закончит их использовать, вы хотите, чтобы кеш автоматически устарел. Состояние сеанса ASP.NET — хороший кандидат на истечение времени простоя.

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

Выселения

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

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

Выселения производятся на основе различных алгоритмов. Самый популярный — наименее недавно использованный (LRU), когда удаляются те кешированные элементы, к которым не прикасались в течение длительного времени. Наименее часто используется другой алгоритм (LFU). Здесь удаляются те предметы, к которым прикасались наименьшее количество раз. Есть еще несколько вариантов, но эти два самые популярные.

Кэширование реляционных данных

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

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

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

В ASP.NET Cache есть действительно классная функция, называемая CacheDependency, которая позволяет отслеживать отношения между различными кэшированными элементами. Некоторые коммерческие кэши также имеют эту функцию. На рис. 2 показан пример работы кэша ASP.NET.

Рис. 2. Отслеживание взаимосвязей между кэшированными элементами

Копировать

using System.Web.Caching; ... public void CreateKeyDependency() { Cache["key1"] = "Value 1"; // Make key2 dependent on key1. String[] dependencyKey = new String[1]; dependencyKey[0] = "key1"; CacheDependency dep1 = new CacheDependency(null, dependencyKey); Cache.Insert("key2", "Value 2", dep2); }

Это многоуровневая зависимость, означающая, что A может зависеть от B, а B может зависеть от C. Таким образом, если ваше приложение удаляет C, A и B также должны быть удалены из кеша.

Синхронизация кэша с другими средами

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

Например, предположим, что ваш кеш написан с использованием Microsoft .NET Framework, но у вас есть приложения Java или C++, изменяющие данные в основном источнике данных. Вы хотите, чтобы эти приложения уведомляли ваш кеш, когда определенные данные изменяются в основных источниках данных, чтобы ваш кеш мог аннулировать соответствующий кэшированный элемент.

В идеале ваш кеш должен поддерживать эту возможность. Если это не так, это бремя ложится на ваше приложение. ASP.NET Cache предоставляет эту функцию через CacheDependency, как и некоторые коммерческие решения для кэширования. Это позволяет вам указать, что определенный кэшированный элемент зависит от файла и что всякий раз, когда этот файл обновляется или удаляется, кеш обнаруживает это и делает кэшированный элемент недействительным. Аннулирование элемента заставляет ваше приложение извлекать последнюю копию этого объекта в следующий раз, когда оно понадобится вашему приложению, и не найдет его в кеше.

Если бы у вас было 100 000 элементов в кеше, 10 000 из них могли бы иметь файловые зависимости, и для этого у вас могло бы быть 10 000 файлов в специальной папке. Каждый файл имеет специальное имя, связанное с этим кэшированным элементом. Когда какое-либо другое приложение — написанное на .NET или нет — изменяет данные в основном источнике данных, это приложение может обмениваться данными с кэшем посредством обновления временной метки файла.

Синхронизация базы данных

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

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

Синхронизация с базой данных может означать аннулирование связанного элемента в кеше, чтобы в следующий раз, когда он понадобится вашему приложению, оно извлекло его из базы данных. Один интересный вариант этого процесса — когда кеш автоматически перезагружает обновленную копию объекта при изменении данных в базе данных. Однако это возможно только в том случае, если ваш кэш позволяет вам предоставить обработчик сквозного чтения (см. следующий раздел), а затем использует его для перезагрузки кэшированного элемента из базы данных. Однако только некоторые из коммерческих кешей поддерживают эту функцию, а бесплатные нет.

Кэш ASP.NET имеет функцию SqlCacheDependency (см. рис. 3), которая позволяет синхронизировать кэш с базой данных SQL Server 2005/2008 или Oracle 10g R2 или более поздней версии — практически с любой базой данных, в которую встроена среда .NET CLR. Некоторые коммерческие кэши также предоставляют эту возможность.

Рис. 3. Использование SqlDependency для синхронизации с реляционной базой данных

Копировать

using System.Web.Caching; using System.Data.SqlClient; ... public void CreateSqlDependency(Customers cust, SqlConnection conn) { // Make cust dependent on a corresponding row in the // Customers table in Northwind database string sql = "SELECT CustomerID FROM Customers WHERE "; sql += "CustomerID = @ID"; SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.Add("@ID", System.Data.SqlDbType.VarChar); cmd.Parameters["@ID"].Value = cust.CustomerID; SqlCacheDependency dep = new SqlCacheDependency(cmd); string key = "Customers:CustomerID:" + cust.CustomerID; Cache.Insert(key, cust, dep); }

Кэш ASP.NET SqlCacheDependency позволяет указать строку SQL, соответствующую одной или нескольким строкам в таблице базы данных. Если эта строка когда-либо обновляется, СУБД запускает событие .NET, которое перехватывает ваш кеш. Затем он узнает, какой кэшированный элемент связан с этой строкой в ​​базе данных, и делает этот кэшированный элемент недействительным.

Одной из возможностей, которую ASP.NET Cache не предоставляет, но которую предоставляют некоторые коммерческие решения, является синхронизация базы данных на основе опроса. Эта возможность полезна в двух ситуациях. Во-первых, если в вашу СУБД не встроена среда .NET CLR, вы не сможете воспользоваться преимуществами SqlCacheDependency. В этом случае было бы неплохо, если бы ваш кеш мог опрашивать вашу базу данных с настраиваемыми интервалами и обнаруживать изменения в определенных строках в таблице. Если эти строки были изменены, ваш кеш делает недействительными соответствующие кешированные элементы.

Вторая ситуация — когда данные в вашей базе данных часто меняются, а события .NET становятся слишком болтливыми. Это происходит из-за того, что для каждого изменения SqlCacheDependency запускается отдельное событие .NET, и если у вас есть тысячи строк, которые часто обновляются, это может легко привести к переполнению кэша. В таких случаях гораздо эффективнее полагаться на опрос, когда с помощью одного запроса к базе данных вы можете получить сотни или тысячи измененных строк, а затем аннулировать соответствующие кэшированные элементы. Конечно, опрос создает небольшую задержку синхронизации (возможно, 15–30 секунд), но во многих случаях это допустимо.

Повторное чтение

В двух словах, сквозное чтение — это функция, которая позволяет вашему кешу напрямую считывать данные из вашего источника данных, каким бы он ни был. Вы пишете обработчик сквозного чтения и регистрируете его в своем кеше, а затем ваш кеш вызывает этот обработчик в соответствующее время. На рис. 4 показан пример.

Рис. 4. Пример обработчика сквозного чтения для SQL Server

Копировать

using System.Web.Caching; using System.Data.SqlClient; using Company.MyDistributedCache; ... public class SqlReadThruProvider : IReadhThruProvider { private SqlConnection _connection; // Called upon startup to initialize connection public void Start(IDictionary parameters) { _connection = new SqlConnection(parameters["connstring"]); _connection.Open(); } // Called at the end to close connection public void Stop() { _connection.Close(); } // Responsible for loading object from external data source public object Load(string key, ref CacheDependency dep) { string sql = "SELECT * FROM Customers WHERE "; sql += "CustomerID = @ID"; SqlCommand cmd = new SqlCommand(sql, _connection); cmd.Parameters.Add("@ID", System.Data.SqlDbType.VarChar); // Let's extract actual customerID from "key" int keyFormatLen = "Customers:CustomerID:".Length; string custId = key.Substring(keyFormatLen, key.Length - keyFormatLen); cmd.Parameters["@ID"].Value = custId; // fetch the row in the table SqlDataReader reader = cmd.ExecuteReader(); // copy data from "reader" to "cust" object Customers cust = new Customers(); FillCustomers(reader, cust); // specify a SqlCacheDependency for this object dep = new SqlCacheDependency(cmd); return cust; } }

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

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

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

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

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

Написать через, написать позади

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

Обычно ваше приложение выдает обновление кэша (например, «Добавить», «Вставить» или «Удалить»). Кэш сначала обновляет сам себя, а затем вызывает обновление базы данных через обработчик сквозной записи. Ваше приложение ожидает обновления кэша и базы данных.

Что делать, если вы хотите дождаться обновления кеша, но не хотите ждать обновления базы данных, потому что это снижает производительность вашего приложения? Вот тут-то и появляется отложенная запись, которая использует тот же обработчик сквозной записи, но синхронно обновляет кеш и асинхронно базу данных. Это означает, что ваше приложение ожидает обновления кеша, но вы не ждете обновления базы данных.

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

Кэшировать запрос

Обычно ваше приложение находит объекты в кеше на основе ключа, точно так же, как хэш-таблица, как вы видели в примерах исходного кода выше. У вас есть ключ, а значение — это ваш объект. Но иногда вам нужно искать объекты на основе атрибутов, отличных от ключа. Следовательно, ваш кеш должен предоставлять вам возможность искать или запрашивать кеш.

Есть несколько способов сделать это. Один из них — поиск по атрибутам объекта. Другой включает ситуации, в которых вы назначили произвольные теги кэшированным объектам и хотите выполнять поиск на основе тегов. Поиск на основе атрибутов в настоящее время доступен только в некоторых коммерческих решениях через языки объектных запросов, но поиск на основе тегов доступен в коммерческих кэшах и в Microsoft Velocity.

Допустим, вы сохранили объект клиента. Вы можете сказать: «Дайте мне всех клиентов, где город Сан-Франциско», когда вам нужны только объекты клиентов, даже если в вашем кэше есть сотрудники, клиенты, заказы, позиции заказов и многое другое. Когда вы отправляете SQL-подобный запрос, подобный показанному на рис. 5, он находит объекты, соответствующие вашим критериям.

Рис. 5. Использование запроса LINQ для поиска элементов в кэше

Копировать

using Company.MyDistributedCache; ... public List<Customers> FindCustomersByCity(Cache cache, string city) { // Search cache with a LINQ query List<Customers> custs = from cust in cache.Customers where cust.City == city select cust; return custs; }

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

Распространение событий

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

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

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

Производительность и масштабируемость кэша

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

Масштабируемость — фундаментальная проблема, которую решает распределенный кэш. Масштабируемый кеш — это тот, который может поддерживать производительность даже при увеличении нагрузки на него транзакциями. Таким образом, если у вас есть приложение ASP.NET в веб-ферме и вы увеличиваете свою веб-ферму с пяти веб-серверов до 15 или даже 50 веб-серверов, вы сможете пропорционально увеличить количество серверов кэширования и сохранить то же время отклика. . Это то, что вы не можете сделать с базой данных.

Распределенный кэш позволяет избежать проблем с масштабируемостью, с которыми обычно сталкивается база данных, потому что он намного проще по своей природе, чем СУБД, а также потому, что он использует другие механизмы хранения (также известные как топологии кэширования), чем СУБД. К ним относятся топологии реплицированного, секционированного и клиентского кэша.

В большинстве ситуаций с распределенным кэшем у вас есть два или более кэш-сервера, на которых размещается кэш. Я буду использовать термин «кластер кеша» для обозначения двух или более серверов кеша, объединенных вместе для формирования одного логического кеша. Реплицированный кэш копирует весь кэш на каждый сервер кэша в кластере кэша. Это означает, что реплицированный кэш обеспечивает высокую доступность. Если какой-либо сервер кеша выходит из строя, вы не теряете данные в кеше, потому что другая копия немедленно становится доступной для приложения. Кроме того, это чрезвычайно эффективная топология, обеспечивающая отличную масштабируемость, если вашему приложению необходимо выполнять множество операций с интенсивным чтением. По мере добавления дополнительных серверов кеша вы увеличиваете емкость транзакций чтения в своем кластере кеша. Но реплицированный кеш — не идеальная топология для операций с интенсивными операциями записи. Если вы обновляете кеш так же часто, как и читаете его, не используйте реплицированную топологию.

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

Многие распределенные кэши предоставляют вариант секционированного кэша для обеспечения высокой доступности, где каждый раздел также реплицируется, так что один кэш-сервер содержит раздел и копию или резервную копию раздела другого сервера. Таким образом, вы не потеряете данные, если какой-либо сервер выйдет из строя. Некоторые решения для кэширования позволяют создавать более одной копии каждого раздела для повышения надежности.

Еще одна очень мощная топология кэширования — клиентский кеш (также называемый ближним кешем), который очень полезен, если ваш кеш находится на удаленном выделенном уровне кэширования. Идея клиентского кеша заключается в том, что каждый клиент хранит рабочий набор кеша рядом (даже внутри процесса приложения) на клиентской машине. Однако точно так же, как распределенный кеш должен быть синхронизирован с базой данных с помощью различных средств (как обсуждалось ранее), клиентский кеш должен быть синхронизирован с распределенным кешем. Некоторые коммерческие решения для кэширования предоставляют этот механизм синхронизации, но большинство из них предоставляют только автономный клиентский кэш без какой-либо синхронизации.

Точно так же, как распределенный кеш уменьшает трафик к базе данных, клиентский кеш уменьшает трафик к распределенному кешу. Он не только быстрее, чем распределенный кеш, потому что он ближе к приложению (и также может быть InProc), но и улучшает масштабируемость распределенного кеша за счет сокращения обращений к распределенному кешу. Конечно, клиентский кеш — хороший подход, только когда вы выполняете гораздо больше операций чтения, чем записи. Если количество операций чтения и записи одинаковое, не используйте клиентский кеш. Запись станет медленнее, потому что теперь вам нужно обновить как клиентский кеш, так и распределенный кеш.

Высокая доступность

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

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

  • Можете ли вы отключить один из серверов кеша, не останавливая весь кеш?
  • Можно ли добавить новый сервер кеша, не останавливая кеш?
  • Можно ли добавлять новых клиентов, не останавливая кэш?

В большинстве кэшей вы используете указанный максимальный размер кэша, чтобы кэш не превышал объем данных. Размер кеша зависит от того, сколько памяти у вас есть в этой системе. Можете ли вы изменить эту способность? Допустим, вы изначально установили размер кэша равным 1 ГБ, но теперь хотите сделать его равным 2 ГБ. Можно ли это сделать, не останавливая кеш?

Это те вопросы, которые вы хотите рассмотреть. Сколько из этих изменений конфигурации действительно требует перезапуска кэша? Чем меньше, тем лучше. Помимо функций кэширования, первым критерием наличия кэша, который может работать в производственной среде, является время безотказной работы, которое кэш может предоставить вам.

Производительность

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

Первое, что нужно помнить, это то, что распределенный кеш обычно является OutProc или удаленным, поэтому время доступа никогда не будет таким быстрым, как у автономного кеша InProc (например, ASP.NET Cache). В автономном кэше InProc вы, вероятно, можете считывать от 150 000 до 200 000 элементов в секунду (размер объекта 1 КБ). При использовании OutProc или удаленного кэша это число значительно снижается. Что касается производительности, вы должны ожидать от 20 000 до 30 000 операций чтения в секунду (размер объекта 1 КБ) в качестве пропускной способности отдельного сервера кэширования (от всех клиентов, обращающихся к нему). Вы можете добиться некоторой производительности InProc, используя клиентский кэш (в режиме InProc), но это только для операций чтения, а не для операций записи. Вы жертвуете некоторой производительностью, чтобы получить масштабируемость, но более низкая производительность все же намного быстрее, чем доступ к базе данных.

Завоевание популярности

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

Горизонтальное масштабирование для пользовательского объема с распределенным кэшированием

Когда одного только вертикального масштабирования оказывается недостаточно для масштабирования платформы данных InterSystems IRIS в соответствии с требованиями вашей рабочей нагрузки, вы можете рассмотреть возможность распределенного кэширования — архитектурно простого, прозрачного для приложений и недорогого подхода к горизонтальному масштабированию.

Обзор распределенного кэширования

Архитектура распределенного кэширования InterSystems IRIS горизонтально масштабируется в зависимости от количества пользователей, распределяя как логику приложений, так и кэширование по уровню серверов приложений, расположенных перед сервером данных, что позволяет разделить пользователей на этом уровне. Каждый сервер приложений обрабатывает запросы пользователей и поддерживает свой собственный кэш базы данных, который автоматически синхронизируется с сервером данных, в то время как сервер данных обрабатывает все хранение данных и управление ими. Прерванные соединения между серверами приложений и сервером данных автоматически восстанавливаются или сбрасываются в зависимости от продолжительности простоя.

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

Кластер распределенного кэша

Эта архитектура обеспечивается за счет использования протокола Enterprise Cache Protocol (ECP), основного компонента платформы данных InterSystems IRIS, для связи между серверами приложений и сервером данных.

Распределенная архитектура кэширования и уровень сервера приложений полностью прозрачны для пользователя и для кода приложения. Вы можете легко преобразовать существующий автономный экземпляр InterSystems IRIS, обслуживающий данные, в сервер данных кластера, добавив серверы приложений.

В следующих разделах приведены дополнительные сведения о распределенном кэшировании:

Распределенная архитектура кэширования

Чтобы лучше понять архитектуру распределенного кэширования, ознакомьтесь со следующей информацией о том, как InterSystems IRIS хранит данные и осуществляет доступ к ним:

  • InterSystems IRIS хранит данные в файле в локальной операционной системе, который называется база данных. Экземпляр InterSystems IRIS может иметь (и обычно имеет) несколько баз данных.
  • Приложения InterSystems IRIS получают доступ к данным посредством пространства имен, которое обеспечивает логическое представление данных, хранящихся в одной или нескольких базах данных. Экземпляр InterSystems IRIS может иметь (и обычно имеет) несколько пространств имен.
  • Каждый экземпляр InterSystems IRIS поддерживает кэш базы данных — локальный буфер общей памяти, используемый для кэширования данных, извлеченных из баз данных, так что повторяющиеся экземпляры одного и того же запроса могут извлекать результаты из памяти, а не из хранилища, обеспечивая очень значительный выигрыш в производительности.

Архитектура кластера распределенного кэша концептуально проста, и использует эти элементы следующим образом:

  • Экземпляр InterSystems IRIS становится сервером приложений путем добавления другого экземпляра в качестве удаленного сервера, а затем добавления любой или всех его баз данных в качестве удаленных баз данных. Это делает второй экземпляр сервером данных для первого экземпляра.
  • Локальные пространства имен на сервере приложений сопоставляются с удаленными базами данных на сервере данных так же, как они сопоставляются с локальными базами данных. Разница между локальной и удаленной базами данных совершенно прозрачна для приложения, запрашивающего пространство имен на сервере приложений.
  • Сервер приложений поддерживает собственный кэш базы данных так же, как если бы он использовал только локальные базы данных. ECP эффективно распределяет данные, блокировки и исполняемый код между несколькими экземплярами InterSystems IRIS, а также синхронизирует кэши сервера приложений с сервером данных.

На практике кластер с распределенным кэшем из нескольких серверов приложений и сервера данных работает следующим образом:

  • Сервер данных продолжает хранить, обновлять и обслуживать данные. Сервер данных также синхронизирует и поддерживает согласованность кэшей серверов приложений, чтобы гарантировать, что пользователи не получают и не хранят устаревшие данные, а также управляет блокировками в кластере.
  • Каждый запрос к данным выполняется в пространстве имен на одном из различных серверов приложений, каждый из которых использует свой собственный кэш базы данных для кэширования получаемых результатов; в результате общий набор кэшированных данных распределяется по этим отдельным кэшам. При наличии нескольких серверов данных сервер приложений автоматически подключается к тому, на котором хранятся запрошенные данные. Каждый сервер приложений также отслеживает свои соединения с сервером данных и, если соединение прерывается, пытается восстановить его.
  • Запросы пользователей могут распределяться по серверам приложений циклически с помощью балансировщика нагрузки, но наиболее эффективный подход использует все преимущества распределенного кэширования, направляя пользователей с похожими запросами на один и тот же сервер приложений, повышая эффективность кэширования. Например, медицинское приложение может сгруппировать клинических пользователей, выполняющих один набор запросов на одном сервере приложений, и сотрудников службы приема и размещения, выполняющих другой набор запросов, на другом. Если кластер обрабатывает несколько приложений, пользователи каждого приложения могут быть направлены на отдельный сервер приложений. На следующих рисунках одиночный экземпляр InterSystems IRIS сравнивается с кластером, в котором пользовательские подключения распределяются таким образом. (Запросы пользователей на балансировку нагрузки могут быть даже вредными в некоторых обстоятельствах; для получения дополнительной информации см. Оценка влияния запросов пользователей на балансировку нагрузки.)
  • Количество серверов приложений в кластере можно увеличить (или уменьшить), не требуя другой реконфигурации кластера или операционных изменений, поэтому вы можете легко масштабироваться по мере увеличения количества пользователей.

Локальные базы данных сопоставлены с локальными пространствами имен в одном экземпляре InterSystems IRIS

Удаленные базы данных на сервере данных сопоставлены с пространствами имен на серверах приложений в кластере распределенного кэша

В распределенном кэш-кластере сервер данных отвечает за следующее:

  • Хранение данных в своих локальных базах данных.
  • Синхронизация кэшей базы данных сервера приложений с базами данных, чтобы серверы приложений не видели устаревшие данные.
  • Управление распределением блокировок по сети.
  • Мониторинг состояния всех соединений с серверами приложений и принятие мер в случае прерывания соединения на определенное время (см. Восстановление ECP).

В кластере распределенного кэша каждый сервер приложений отвечает за следующее:

  • Установление соединений с определенным сервером данных всякий раз, когда приложение запрашивает данные, хранящиеся на этом сервере.
  • Поддержание в своем кеше данных, полученных по сети.
  • Мониторинг состояния всех подключений к серверу данных и принятие мер, если подключение прерывается на определенное время (см. Восстановление ECP).

Примечание.

Кластер распределенного кэша может включать более одного сервера данных (хотя это редкость). Экземпляр InterSystems IRIS может одновременно действовать и как сервер данных, и как сервер приложений, но не может действовать как сервер данных для данных, которые он получает как сервер приложений.

Функции ЕСП

ECP поддерживает архитектуру распределенного кэша, предоставляя следующие функции:

  • Автоматическая отказоустойчивая работа. После настройки ECP автоматически устанавливает и поддерживает соединения между серверами приложений и серверами данных и пытается восстановиться после любых отключений (запланированных или незапланированных) между сервером приложений и экземплярами сервера данных (см. Восстановление ЭКП). ECP также может сохранять состояние работающего приложения при отказе сервера данных (см. Распределенное кэширование и высокая доступность).
  • Эти функции не только обеспечивают доступность данных для приложений, но и упрощают управление кластером распределенного кэша; например, можно временно перевести сервер данных в автономный режим или выполнить отработку отказа в рамках планового обслуживания без выполнения каких-либо операций с экземплярами сервера приложений.
  • Гетерогенная сеть. Системы InterSystems IRIS в кластере распределенного кэша могут работать на разных аппаратных платформах и операционных системах. ECP автоматически управляет всеми необходимыми преобразованиями формата данных.
  • Надежный транспортный уровень, основанный на TCP/IP. ECP использует стандартный протокол TCP/IP для передачи данных, что упрощает его настройку и обслуживание.
  • Эффективное использование пропускной способности сети. ECP использует все преимущества высокопроизводительных сетевых инфраструктур.

Восстановление ЭКП

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

Дополнительные сведения о подключениях ECP см. в разделе Мониторинг распределенных приложений; дополнительные сведения о восстановлении ECP см. в разделах Протокол восстановления ECP и Процесс восстановления ECP, гарантии и ограничения.

Распределенное кэширование и высокая доступность

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

Серверы данных можно зеркалировать для обеспечения высокой доступности так же, как автономный экземпляр InterSystems IRIS, а серверы приложений можно настроить на автоматическое перенаправление подключений к резервной копии в случае аварийного переключения. (Зеркалировать сервер приложений нет необходимости и даже невозможно, так как он не хранит никаких данных.) Подробную информацию об использовании зеркалирования в кластере с распределенным кэшем см. в разделе Настройка соединений ECP с зеркалом и Настройка зеркалирования. ” в Руководстве по высокой доступности.

Другие стратегии отработки отказа, описанные в главе Стратегии отработки отказа для обеспечения высокой доступности в Руководстве по обеспечению высокой доступности, также можно использовать в кластере с распределенным кэшем. Независимо от стратегии аварийного переключения, используемой для сервера данных, серверы приложений повторно подключаются и восстанавливают свое состояние после аварийного переключения, позволяя продолжить обработку приложения с того места, где оно было остановлено до сбоя.

Развертывание кластера распределенного кэша

Кластер распределенного кэша InterSystems IRIS состоит из экземпляра сервера данных, предоставляющего данные одному или нескольким экземплярам серверов приложений, которые, в свою очередь, предоставляют их приложению. Платформа данных InterSystems IRIS предлагает несколько методов автоматического развертывания кластеров распределенного кэша. Инструкции в этом разделе предназначены для ручного развертывания кластера с помощью портала управления. Информация о защите кластера после развертывания представлена ​​в разделе Безопасность кластера распределенного кэша.

ВАЖНО:

Как правило, экземпляры InterSystems IRIS в кластере с распределенным кэшем могут иметь разные версии, если ни один из серверов приложений не имеет более поздней версии, чем сервер данных. Важные требования и ограничения, касающиеся совместимости версий, см. в разделе Совместимость ECP в разделе Поддерживаемые платформы InterSystems.

Хотя хосты сервера данных и сервера приложений могут иметь разные операционные системы и/или порядок следования байтов, все экземпляры InterSystems IRIS в кластере распределенного кэша должны использовать одну и ту же локаль. Сведения о настройке локалей см. в разделе Использование страницы настроек NLS на портале управления в Руководстве по системному администрированию.

Примечание.

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

Наиболее типичная конфигурация кластера распределенного кэша включает один экземпляр InterSystems IRIS на хост и одну роль кластера на каждый экземпляр, то есть либо сервер данных, либо сервер приложений. При использовании одного из методов автоматического развертывания, описанных в следующем разделе, эта конфигурация является единственным вариантом. Предоставленная процедура использования портала управления также предполагает эту конфигурацию.

HealthShare Health Connect не поддерживает распределенное кэширование.

Автоматизированные методы развертывания для кластеров

В дополнение к ручной процедуре, описанной в этом разделе, платформа InterSystems IRIS Data предоставляет несколько методов автоматического развертывания кластеров распределенного кэша, которые полностью готовы к работе после развертывания.

Развертывание кластера распределенного кэша с помощью InterSystems Cloud Manager (ICM)

С помощью InterSystems Cloud Manager (ICM) вы можете автоматически развертывать любую конфигурацию платформы данных InterSystems IRIS, включая кластеры распределенного кэша с зеркальным или незеркальным сервером данных и любым количеством серверов приложений, а также веб-серверы, балансировщик нагрузки и арбитр, если нужный. Сочетая текстовые декларативные файлы конфигурации, простой интерфейс командной строки и развертывание InterSystems IRIS в контейнерах, ICM предоставляет вам простой и интуитивно понятный способ подготовки облачной или виртуальной инфраструктуры и развертывания желаемой архитектуры InterSystems IRIS в этой инфраструктуре наряду с другими услуги. ICM также можно установить из установочного комплекта InterSystems IRIS.

Полную документацию по ICM, включая сведения о развертывании кластера с распределенным кэшем в общедоступном или частном облаке или в существующей инфраструктуре, включая оборудование, см. в Руководстве по InterSystems Cloud Manager. Краткое введение в ICM, включающее практическое изучение развертывания сегментированного кластера, см. в разделе Первый взгляд: InterSystems Cloud Manager.

Развертывание кластера распределенного кэша с помощью InterSystems Kubernetes Operator (IKO)

Kubernetes — это механизм оркестрации с открытым исходным кодом для автоматизации развертывания, масштабирования и управления контейнерными рабочими нагрузками и службами. Вы определяете контейнерные службы, которые хотите развернуть, и политики, которыми они должны управлять; Kubernetes прозрачно предоставляет необходимые ресурсы наиболее эффективным способом, исправляет или восстанавливает развертывание, когда оно отклоняется от спецификации, и масштабируется автоматически или по требованию. Оператор InterSystems Kubernetes (IKO) расширяет API Kubernetes с помощью пользовательского ресурса IrisCluster, который можно развернуть в виде сегментированного кластера InterSystems IRIS, кластера с распределенным кэшем или автономного экземпляра, при необходимости зеркального отображения, в любом Kubernetes. Платформа.

IKO не требуется для развертывания InterSystems IRIS в Kubernetes, но он значительно упрощает процесс и добавляет в Kubernetes возможности управления кластером, специфичные для InterSystems IRIS, позволяя выполнять такие задачи, как добавление узлов в кластер, которые в противном случае вам пришлось бы выполнять вручную, взаимодействуя непосредственно с экземплярами.

Подробнее об использовании IKO см. в разделе Использование InterSystems Kubernetes Operator.

Развертывание кластера распределенного кэша с помощью объединения конфигураций

Функция слияния конфигураций, доступная в системах Linux и UNIX®, позволяет изменять конфигурации контейнеров InterSystems IRIS, развернутых из одного образа, или локальных экземпляров, установленных из одного и того же комплекта, просто применяя требуемый декларативный файл слияния конфигураций к каждому экземпляру в развертывание.

Этот файл слияния, который также можно применять при перезапуске существующего экземпляра, обновляет файл параметров конфигурации (CPF) экземпляра, который содержит большинство его параметров конфигурации; эти параметры считываются из CPF при каждом запуске, включая первый после развертывания экземпляра. Когда вы применяете слияние конфигурации во время развертывания, вы фактически заменяете CPF по умолчанию, поставляемый с экземпляром, вашей собственной обновленной версией.

Используя слияние конфигурации, вы можете развернуть кластер распределенного кэша, вызвав отдельные файлы слияния для сервера данных и серверов приложений, развертывая их последовательно.

ICM, описанный в предыдущем разделе, включает функцию слияния конфигураций.

Сведения об использовании объединения конфигураций в целом и о развертывании кластера распределенного кэша в частности см. в разделе Автоматизация настройки InterSystems IRIS с помощью объединения конфигураций.