Постоянное кэширование ASP.NET (стиль «отложенной загрузки»?)

2

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

Проблема: Процесс извлечения запрошенных данных занимает много времени. Если вы используете стандартное кэширование ASP.NET, некоторые пользователи получат "хит" для извлечения данных. Это неприемлемо.

Решение?: Не очень важно, чтобы данные были на 100% текущими. Я хотел бы обслуживать старые недействительные данные при обновлении кэшированных данных в другом потоке, чтобы новые данные были доступны для будущих запросов. Я считаю, что данные необходимо каким-то образом сохранить, чтобы иметь возможность обслуживать первого пользователя после перезапуска приложения без того, чтобы пользователь "ударил".

Я сделал решение, которое делает что-то вроде выше, но мне интересно, есть ли способ "наилучшей практики" или существует каркас кэширования, который уже поддерживает это поведение?

Теги:
caching

6 ответов

1
Лучший ответ

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

3

Есть инструменты, которые делают это, например, Microsoft ISA Server (может быть немного дороже /overkill ).

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

  • 2
    EL-кеширование довольно просто, если ваши требования не слишком сложны.
  • 0
    Звучит как хорошая идея, однако я хотел сделать это, не полагаясь на сервис / запланированное задание.
Показать ещё 2 комментария
1

Вы можете сделать это довольно легко с классами Cache и Timer, встроенными в .NET. Таймер запускается в отдельном потоке.

И я на самом деле написал очень маленькую библиотеку-оболочку под названием WebCacheHelper, которая раскрывает эту функциональность в перегруженном конструкторе. Библиотека также служит строго типизированной оболочкой вокруг объекта Cache.

Вот пример того, как вы могли это сделать...

public readonly static WebCacheHelper.Cache<int> RegisteredUsersCount = 
  new WebCacheHelper.Cache<int>(new TimeSpan(0, 5, 0), () => GetRegisteredUsersCount()); 

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

Затем получение значения так же просто, как ссылка RegisteredUsersCount.Value.

1

Вы можете слушать, когда Cached Item будет удален и обработать,

public void RemovedCallback(String k, Object v, CacheItemRemovedReason r)
{
    // Put Item Back IN Cache, ( so others can use it until u have finished grabbing the new data)

    // Spawn Thread to Go Get Up To Date Data

    // Over right Old data with new return... 
} 

в глобальном asax

protected void Application_Start(object sender, EventArgs e)
{
     // Spawn worker thread to pre-load critical data
}

Ох... Я понятия не имею, если это лучшая практика, я просто подумал, что это будет пятно ~ Удачи ~

  • 0
    Отличная идея .. Я не думал об этом. Но, используя это решение, первый пользователь, посещающий сайт, все равно получит «хит» обновления кеша. Кроме того, поскольку я использую встроенные делегаты для извлечения данных, я не знаю, как перезапустить делегат внутри RemovedCallback.
  • 0
    Извините, я забыл обратиться к этой части. в вашем Global.Asax при запуске приложения создайте поток, который делает «фальшивые» запросы на необходимые данные. таким образом, он уже либо работает, либо уже завершен по первому запросу.
Показать ещё 1 комментарий
0

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

Существует очень мало шансов показать пользователю пустой экран. Я исключаю это путем кэширования через кеш asp.net в течение 1 минуты.

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

0

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню