Стратегия кэширования ASP.NET - PullRequest
5 голосов
/ 07 сентября 2011

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

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

(Кэширование вывода - мой следующий шаг, поэтому не нужно комментировать это.)

Я громко думаю:

A) Загружать все кампании заранее в Словарь, когдасервер запускается и кладет его в кеш.

Я подсчитал, что это займет около 3,8 МБ памяти сервера (ОК) и займет около 8 секунд (ОК) при просмотре первой страницы с текущим количеством кампаний.Единственная проблема в том, что это не очень хорошо масштабируется.Завтра у меня может быть в 10 раз больше кампаний.Кроме того, нам необходимо обновлять и добавлять новые кампании ежедневно, и каждый раз удаление всего кэша кампаний кажется излишним.

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

B) Ленивая загрузка: кэшируйте каждую кампанию индивидуально с помощью ключа, такого как «Кампании. [Id]»

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

C) Lazyload в словарь такие же bennefins, как B), и кэш не загроможден множеством ключей, но не может использовать функции кэша, и если памятьтуго весь словарь сбрасывается.

Что ты думаешь?Я склоняюсь в сторону B).

Кроме того, у меня есть сценарий, в котором мне нужно получать кампании либо по идентификатору, либо по коду (строке).

В следующих случаях:

Campaigns campaign = //Get campaign from database:
Cache["Campaigns.Id."+campaign.Id.ToString()] = campaign; //Id is Guid
Cache["Campaigns.Code."+campaigns.Code] = campaign;

Это будет стоить мне вдвое больше памяти или просто для другого индекса индекса?

1 Ответ

4 голосов
/ 07 сентября 2011

Хммм, я бы посмотрел на кеширование сгруппированных элементов (похоже на вашу идею B), но установил бы тайм-аут на них. Это означает, что редко используемые элементы будут кэшироваться, но в конечном итоге сбрасываются. Время ожидания должно соответствовать частоте нормального использования. Например, если обычная кампания получает удар 10 раз в час, сделайте тайм-аут довольно низким, возможно, 5-10 минут.

ASP.NET Cache имеет встроенный тайм-аут:

http://quickstarts.asp.net/QuickStartv20/aspnet/doc/caching/data.aspx

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

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

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

http://msdn.microsoft.com/en-us/library/ms228248.aspx

Так что вам не нужно слишком беспокоиться об этом.

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