Модуль 38

Redis у production-середовищі

Ось твій урок у стилі CS50 та Девіда Малана. Вмикай уяву — ми в аудиторії Сандерс-театру, і перед нами стоїть завдання зробити так, щоб наш код не просто "працював", а вижив у суворому світі продакшену!


🏛️ CS50: Redis у Production-середовищі

(Коли просто "швидко" вже недостатньо)


1. 🔥 Вступ: Коли все падає

Уявіть, що ви запустили стартап. Це інтернет-магазин кросівок. Сьогодні — Чорна п’ятниця. Тисячі користувачів одночасно намагаються купити лімітовану серію.

Ви, як розумний інженер, підключили Redis, щоб кешувати дані про товари. Все літає! Запити обробляються за мілісекунди, бо Redis тримає дані в оперативній пам’яті (RAM). Ви — герой дня.

Але раптом... блимає світло. Сервер перезавантажується.

Що відбувається з вашим Redis? 1. Вся оперативна пам'ять очищується. 2. Всі сесії користувачів зникають (людей "викидає" з акаунтів). 3. Кошики покупок порожні. 4. База даних (PostgreSQL/MySQL), на яку раптово обрушився весь трафік (бо кешу немає), лягає від навантаження.

Результат: Ви втратили гроші, репутацію і, можливо, кілька нервових клітин.

Питання: Чи має сенс супер-швидкість, якщо вона настільки крихка? Як зробити так, щоб Redis був не просто "швидким блокнотом", а надійним інструментом, якому можна довірити бізнес?

Саме про це ми сьогодні й поговоримо: Redis у Production.


2. 🧠 Теоретична база: Як не втратити дані?

Ви вже знаєте, що Redis — це Key-Value сховище в пам'яті. Але в продакшені нам потрібно вирішити дві головні проблеми: 1. Персистенція (Persistence) — як не втратити дані при перезапуску. 2. Витіснення (Eviction) — що робити, коли пам'ять закінчується.

А. Персистенція: Фотографія чи Щоденник?

У Redis є два способи зберегти дані на жорсткий диск (щоб пережити рестарт). Уявіть, що ви пишете роман.

  1. RDB (Redis Database Snapshotting) — "Фотографія"

    • Як це працює: Раз на певний час (наприклад, кожні 5 хвилин) Redis робить "зліпок" усієї пам'яті і зберігає його у файл.
    • Плюс: Швидко відновлюється, файл компактний.
    • Мінус: Якщо сервер впаде через 4 хвилини 59 секунд після останнього знімка, ви втратите дані за ці майже 5 хвилин.
  2. AOF (Append Only File) — "Щоденник"

    • Як це працює: Кожна команда зміни даних (SET, INCR, DEL) одразу дописується в кінець лог-файлу.
    • Плюс: Ви майже нічого не втрачаєте (максимум 1 секунду, залежно від налаштувань).
    • Мінус: Файл росте дуже швидко, і відновлення триває довше (бо Redis має "програти" всі команди заново).

Що треба запам'ятати: У продакшені часто використовують гібрид. RDB для бекапів, AOF для надійності.

Б. Витіснення: Коли шафа повна

Пам'ять не гумова. Що робити, коли ви виділили 4 ГБ, а даних на 4.1 ГБ? Redis має вирішити, кого "вигнати". Це називається Eviction Policy.

  • noeviction: "Вибач, місця немає". Redis просто повертає помилку на будь-який запис. (Небезпечно для продакшену!).
  • allkeys-lru: Видаляємо ті ключі, які найдавніше використовувались (Least Recently Used). Навіть якщо вони важливі, але старі.
  • volatile-lru: Видаляємо тільки ті старі ключі, у яких встановлено час життя (TTL). "Вічні" дані не чіпаємо.

3. 🧪 Приклади: Від "Hello World" до Реальності

Приклад 1: Базовий кеш (Поганий патерн)

SET user:101 "John Doe"

Чому це погано в продакшені? Цей ключ буде висіти в пам'яті вічно. Якщо таких користувачів мільйон, ваша пам'ять лусне.

Приклад 2: Правильний кеш із TTL (Time To Live)

Ми хочемо зберегти дані, але тільки на 1 годину.

SET user:101 "John Doe" EX 3600
  • EX 3600 — видалити через 3600 секунд.

Що ви очікуєте побачити через годину? nil (пустоту). Redis сам, як прибиральник, видалить сміття.

Приклад 3: Rate Limiter (Захист від спаму)

Уявіть, що хакер намагається підібрати пароль до адмінки. Ми хочемо дозволити тільки 5 спроб на хвилину.

Логіка: 1. Створюємо ключ login_attempts:IP_АДРЕСА. 2. Збільшуємо його на 1 при кожній спробі. 3. Якщо це перша спроба — ставимо таймер смерті на 60 секунд.

# Псевдокод (Python-style)
key = f"login_attempts:{ip_address}"

current_count = redis.incr(key) # Збільшує на 1, повертає нове значення

if current_count == 1:
    redis.expire(key, 60) # Якщо ключ новий, він живе 60 сек

if current_count > 5:
    raise Error("Забагато спроб! Охолоньте.")

Чому це круто? Це атомарна операція. Навіть якщо 100 хакерів вдарять одночасно, Redis (який є однопоточним) обробить їх по черзі, і лічильник буде точним.


4. 🛠 Практична частина

Час забруднити руки. Уявіть, що ви налаштовуєте redis.conf або пишете код.

Завдання 1: "Чистка шафи" Напишіть команду Redis, яка записує ціну товару (price:iphone15 = 999), але так, щоб ця інформація зникла рівно через 10 секунд. Перевірте через 11 секунд, чи вона там є.

Завдання 2: "Симуляція переповнення" (Думковий експеримент) У вас налаштовано політику volatile-lru. * Ключ А: без терміну дії (важливі налаштування). * Ключ Б: має TTL, до нього зверталися 1 хвилину тому. * Ключ В: має TTL, до нього зверталися 5 хвилин тому. Пам'ять закінчилась. Який ключ Redis вб'є першим, щоб звільнити місце?

Завдання 3: "Небезпечна команда" У вас в базі 10 мільйонів ключів. Ваш колега-джуніор пише в консолі продакшену: KEYS * (показати всі ключі). Питання: Що станеться з вашим сервісом в цей момент? (Підказка: Redis однопоточний).

Завдання 4: Міні-кейс Ви робите систему SMS-кодів підтвердження. Код діє 5 хвилин. Але користувач може запросити новий код не частіше, ніж раз на 30 секунд. Опишіть (словами або псевдокодом), які два ключі Redis вам знадобляться і які TTL ви їм дасте?


5. 💡 Мислення як у розробника

Ось де різниця між новачком і сеньйором.

❌ Помилка новачка: "Redis як постійна база"

Новачок думає: "Redis швидкий, буду зберігати тут ВСЕ назавжди". Реальність: Пам'ять дорога. Дані можуть зникнути. Redis — це кеш або "гаряче" сховище, а не архів.

❌ Фатальна помилка: Команда KEYS *

Ніколи, чуєте, НІКОЛИ не використовуйте KEYS * у продакшені. Чому? Redis обробляє команди в одному потоці. Поки він перебирає 10 мільйонів ключів, щоб показати їх вам, він блокує всі запити від користувачів. Ваш сайт "зависає" на кілька секунд або хвилин. ✅ Як робить профі: Використовує команду SCAN. Вона видає ключі порціями, не блокуючи сервер.

🧠 Порада сеньйора: "Думай про збій"

Завжди запитуйте себе: "Якщо Redis зараз зникне і повернеться чистим, мій додаток впаде чи просто почне працювати повільніше?" * Якщо впаде — у вас проблеми з архітектурою. * Якщо стане повільнішим (піде в БД) — ви все зробили правильно.


6. 🧩 Підсумок

Сьогодні ми зрозуміли, що Redis у продакшені — це не просто SET і GET. Це баланс між швидкістю та надійністю.

Тепер ви вмієте: 1. Розуміти різницю між RDB та AOF (фото vs щоденник). 2. Налаштовувати "смерть" даних через TTL, щоб пам'ять не засмічувалась. 3. Будувати прості Rate Limiters. 4. Боятися команди KEYS * як вогню.

Що далі? Ми навчилися зберігати дані. Але що, як нам треба, щоб різні сервіси спілкувалися між собою? В наступному уроці ми розглянемо Message Brokers і дізнаємося, як Redis може працювати листоношею, використовуючи Pub/Sub.

А поки що — не забудьте поставити TTL на свої сесії! 😉