JavaRush /Курсы /Модуль 4: FastAPI /Удаление и управление данными кэша в Redis

Удаление и управление данными кэша в Redis

Модуль 4: FastAPI
9 уровень , 8 лекция
Открыта

Сегодня нам предстоит понять, как управлять жизненным циклом данных в кэше, освоить подходы к удалению устаревших данных и научиться эффективно использовать возможности Redis для оптимизации.

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

Пример задания TTL для ключа:


import redis

# Подключение к Redis
r = redis.Redis(host='localhost', port=6379, db=0)

# Установка значения с временем жизни в 10 секунд
r.set('username', 'Alice', ex=10)

# Получение значения до истечения TTL
print(r.get('username'))  # b'Alice'

# Через 10 секунд ключ автоматически удалится

Флаг ex задаёт время жизни в секундах, а px — в миллисекундах.

Большинство кэширующих систем устанавливают TTL для предотвращения накопления устаревших данных и сохранения актуальности кэша.


Политики вытеснения данных

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

  • noeviction: ничего не удаляется, при исчерпании памяти сервер возвращает ошибку.
  • allkeys-lru: удаляются наименее недавно используемые ключи (Least Recently Used).
  • volatile-lru: удаляются наименее недавно используемые ключи с установленным TTL.
  • allkeys-lfu: удаляются наименее часто используемые ключи (Least Frequently Used).

Эти политики настраиваются в конфигурационном файле Redis (обычно redis.conf) через параметр maxmemory-policy. Например:


maxmemory-policy allkeys-lru

Если вы хотите протестировать вытеснение данных, используйте следующую настройку для запуска Redis:


redis-server --maxmemory 100mb --maxmemory-policy allkeys-lru

Удаление данных из кэша

Удаление определённых ключей в Redis осуществляется с помощью команды DEL. Это можно сделать как для одного ключа, так и для нескольких:


# Удаление одного ключа
r.delete('username')

# Удаление нескольких ключей
r.delete('key1', 'key2', 'key3')

Но иногда нам нужно удалять данные, соответствующие определённому шаблону. Для этого используется комбинация SCAN и DEL:


# Найти и удалить ключи, начинающиеся с "user:"
keys = r.scan_iter('user:*')
for key in keys:
    r.delete(key)

Используйте SCAN вместо KEYS, так как последний может сильно нагружать сервер при большом количестве записей.

Для очистки всех данных из Redis применяется команда FLUSHDB (очищает текущую базу данных) или FLUSHALL (очищает все базы данных):


# Полностью очистить текущую базу
r.flushdb()

# Полностью очистить все базы Redis
r.flushall()

Будьте осторожны! Эти команды удаляют все данные без возможности восстановления.


Обработка устаревших данных

Инвалидирование — это процесс удаления устаревших или изменённых данных из кэша, чтобы предотвратить использование неверной информации. Например, представьте, что у нас кэшируется информация о товаре:


# Кэшируем информацию о товаре
product_id = 42
product_data = {'name': 'Laptop', 'price': 1500}
r.set(f'product:{product_id}', json.dumps(product_data), ex=300)

Если цена товара изменяется в базе данных, необходимо удалить кэш, чтобы он не возвращал устаревшие данные:


# Удаляем старый кэш товара
r.delete(f'product:{product_id}')

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

Подходы к инвалидированию кэша:

  1. Явное инвалидирование: кэш удаляется вручную при обновлении данных.
  2. Lazy Loading (ленивая загрузка): устаревшие данные удаляются только при следующем запросе.
  3. Time-based Expiration: данные автоматически удаляются по истечению TTL.

Пример использования явного инвалидирования в FastAPI:


from fastapi import FastAPI
import redis
import json

app = FastAPI()
r = redis.Redis(host='localhost', port=6379, db=0)

@app.put("/update_product/{product_id}")
async def update_product(product_id: int, name: str, price: float):
    # Обновление данных в базе (предположим)
    database_update(product_id, name, price)

    # Удаление устаревших данных в кэше
    r.delete(f'product:{product_id}')
    return {"message": "Product updated and cache invalidated"}

Использование TTL и LRU для управления

Чтобы минимизировать количество устаревших данных и оптимизировать использование памяти:

  • Устанавливайте TTL для данных, которые меняются редко, но требуют регулярного обновления.
  • Настраивайте политику вытеснения, например, volatile-lru для ключей с TTL.

Пример:


# Кэшируем с TTL
r.set('user_preferences', json.dumps({'theme': 'dark'}), ex=86400)

# Проверка оставшегося времени жизни
ttl = r.ttl('user_preferences')
print(f"Remaining TTL: {ttl} seconds")

Практика: управление данными в сложной системе

Предположим, мы храним информацию о пользователях в кэше с ключами user:{id}. Когда пользователь обновляет свои данные, кэш должен обновляться, чтобы избежать устаревшей информации.

Пример кода:


@app.put("/update_user/{user_id}")
async def update_user(user_id: int, name: str):
    # Обновляем данные в БД
    update_user_in_db(user_id, name)

    # Инвалидируем кэш
    r.delete(f'user:{user_id}')

    # Заново добавляем данные в кэш
    new_data = {"id": user_id, "name": name}
    r.set(f'user:{user_id}', json.dumps(new_data), ex=3600)
    return new_data

Механизмы очистки: автоматизация

Если ручная очистка кажется слишком сложной, можно использовать:

  • Периодические задачи: запускать очистку кэша по расписанию через Celery.
  • Событийный подход: связывать операции в БД с кэшированием через сигналы.

Пример очистки:


# Celery задача для автоматической очистки
@app.task
def clear_expired_cache():
    keys = r.scan_iter()
    for key in keys:
        if r.ttl(key) == -1:  # Если у ключа нет TTL
            r.delete(key)

Заключительное приложение знаний

Теперь вы знаете, как управлять данными в кэше, от удаления конкретного ключа до настройки сложных политик вытеснения. В реальной жизни грамотное управление кэшем не просто повышает производительность — оно спасает вас от головной боли с устаревшими данными. А ведь что может быть хуже, чем пользователь, который видит в системе старую информацию? Разве что баг в пятницу вечером!

1
Задача
Модуль 4: FastAPI, 9 уровень, 8 лекция
Недоступна
Удаление ключей по шаблону
Удаление ключей по шаблону
1
Задача
Модуль 4: FastAPI, 9 уровень, 8 лекция
Недоступна
Автоматическое обновление кэша при изменении данных
Автоматическое обновление кэша при изменении данных
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ