Как избежать штормов запросов к базе данных с использованием шаблона кэширования - PullRequest
4 голосов
/ 10 марта 2011

Мы используем базу данных PostgreSQL и AppFabric Server, на котором запущен сайт электронной коммерции ASP.NET MVC с умеренной загруженностью.

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

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

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

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

Я что-то здесь упускаю? И какие другие подходы люди использовали, чтобы избежать такого поведения?

Ответы [ 2 ]

1 голос
/ 21 августа 2013

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

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

Таким образом, основной рабочий процесс:

1) Попробуйте извлечь изосновной / общий кэш-пул

* If successful, return
* If unsuccessul, continue

2) Проверить в кеше в процессе значение

* If successful, return (optionally seeding primary cache)
* If unsuccessul, continue

3) Получить блокировку по ключу кеша (и перепроверить в кеше в процессе, весли он был добавлен другим потоком)

4) Извлечь объект из первичной персистентности (дБ)

5) Заполнить кэш в процессе и вернуть

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

0 голосов
/ 06 апреля 2011

Мы успешно использовали AppFabric с упомянутой выше стратегией посева.На самом деле мы используем оба решения:

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

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

...