Как удалить просроченные элементы из кэша?

StackOverflow https://stackoverflow.com/questions/141452

  •  02-07-2019
  •  | 
  •  

Вопрос

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

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

Какая хорошая методология для удаления таких элементов из кэша с истекшим сроком действия?

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

Это было полезно?

Решение

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

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

Другие советы

Лучший код - это отсутствие кода.Вместо этого используйте кеш ASP.NET.Вы можете ссылаться на него как System.Web.HttpRuntime.Кэшируйте в любом приложении, а не только в веб-приложениях.

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

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

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

Однако ответ Харальда Шейриха лучше, если вы не возражаете, что объекты висят вечно, когда кэш не обновляется.

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

private DateTime nextFlush;
public object getItem(object key)
{
  DateTime now = DateTime.Now
  if (now > nextFlush)
  {
    Flush();
    nextFlush = now.AddMinutes(1)
  }
  return fetchItem(key);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top