Что такое Cache Expiration Time (время жизни кэша)?

Ответ

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

Основные стратегии истечения срока действия:

  1. Абсолютное истечение (Absolute Expiration): Данные удаляются в конкретный момент времени.

    • Пример: Кэшировать список городов на 24 часа.
  2. Скользящее истечение (Sliding Expiration): Таймер сбрасывается при каждом обращении к данным. Если к данным не обращаются в течение заданного интервала, они удаляются.

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

Пример настройки в C# с IMemoryCache:

// Создание опций для записи в кэш
var cacheEntryOptions = new MemoryCacheEntryOptions
{
    // Абсолютное истечение: удалить через 5 минут
    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),

    // Скользящее истечение: сбросить таймер при каждом чтении, удалить, если не использовались 2 минуты
    SlidingExpiration = TimeSpan.FromMinutes(2),

    // Приоритет кэша (может влиять на вытеснение при нехватке памяти)
    Priority = CacheItemPriority.High
};

// Добавление данных в кэш
_memoryCache.Set("popularProducts", productList, cacheEntryOptions);

Пример с IDistributedCache (например, Redis):

await distributedCache.SetStringAsync("config", jsonData, new DistributedCacheEntryOptions
{
    AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
});

Ключевые соображения:

  • Если заданы оба типа истечения (Absolute и Sliding), запись удаляется при наступлении первого из событий.
  • SlidingExpiration идеально подходит для часто используемых, «горячих» данных.
  • AbsoluteExpiration лучше для данных, которые устаревают по расписанию (например, ежедневные отчеты).
  • Истечение срока — это обычно «ленивая» операция; удаление может произойти не мгновенно в момент истечения TTL.

Ответ 18+ 🔞

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

Представь, что кэш — это твоя холодильная камера с готовыми обедами. TTL (Time To Live) — это как раз срок, через который борщ там превратится в нечто неопознанное и его надо выкинуть или сварить новый. Если поставить срок слишком маленький — будешь вечно у плиты стоять, производительность хромать будет. Слишком большой — рискуешь отравиться устаревшей окрошкой. Баланс, блядь, нужен.

Как эту хрень обычно настраивают:

  1. Жёсткий срок годности (Absolute Expiration): Всё, приплыли. Ровно в 18:00, даже если суп ещё не тронут, — на помойку. И всё.

    • Где сгодится: Закэшировал курс валют, который обновляется раз в сутки в 12:00. Поставил TTL на 24 часа — и похуй. Завтра в 12:01 новые данные подтянутся.
  2. Продлеваемый срок (Sliding Expiration): Пока ешь — срок годности отодвигается. Перестал жрать — через N времени выкинем.

    • Где сгодится: Сессия пользователя. Сидит, кликает — и пусть сидит, хоть до завтра. Закрыл вкладку и ушёл на хуй — через 20 минут сессию в тартарары.

Вот как это выглядит в коде на C# с IMemoryCache (это который в памяти приложения):

// Готовим правила, по которым наш супчик будет жить в холодильнике
var cacheEntryOptions = new MemoryCacheEntryOptions
{
    // Жёсткий приговор: через 5 минут — в утиль, даже если не трогали
    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),

    // А это продление: каждый раз, когда достаёшь, таймер сбрасывается.
    // Но если забыл про него на 2 минуты — всё, выкидываем.
    SlidingExpiration = TimeSpan.FromMinutes(2),

    // Важность контейнера. Если холодильник забит под завязку,
    // первым делом выкинут Low приоритет, а High попытаются оставить.
    Priority = CacheItemPriority.High
};

// Собственно, кладём наш борщ (список товаров) в кэш с этими правилами
_memoryCache.Set("popularProducts", productList, cacheEntryOptions);

А если кэш распределённый, типа Redis (IDistributedCache):

await distributedCache.SetStringAsync("config", jsonData, new DistributedCacheEntryOptions
{
    // Тут попроще, часто только абсолютный срок ставят.
    // Через час — хуяк, и ключ умирает.
    AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
});

Важные нюансы, чтобы не обосраться:

  • Если навесил и абсолютный, и скользящий срок — запись умрёт от того, что наступит первым. Поставил абсолютный на 5 минут, а скользящий на 2? Если данные читают каждую минуту, они проживут ровно 5 минут (скользящий будет сбрасываться, но абсолютный их прибьёт в 5:00). Если перестали читать на 2 минуты — умрут раньше, по скользящему.
  • Sliding — для горячих, популярных данных, которые постоянно в деле.
  • Absolute — для данных, которые устаревают по расписанию, как утренние новости.
  • И главное, запомни: истечение срока — часто ленивое. Это не значит, что ровно в 00:00:01 система в панике побежит удалять запись. Она её удалит, когда придёт за ней или когда там сборщик мусора в кэше прогуляется. Так что не наделяй это мистической точностью, ёпта.