Модуль 33

Redis для зберігання сесій користувачів

Ось твій урок у стилі CS50. Вмикай уяву, ми починаємо!


🎓 УРОК: Redis для зберігання сесій користувачів

(Або: Чому вашій базі даних потрібен відпочинок, а користувачам — швидкість)


1. 🔥 Вступ: Проблема амнезії в Інтернеті

Уявіть, що ви прийшли на вечірку у величезний нічний клуб. На вході стоїть охоронець. Він перевіряє ваше ім’я у списку гостей, усміхається і пропускає всередину.

Але тут стається дивне. Ви підходите до барної стійки — і бармен вимагає ваш паспорт та перевірку списку. Ви йдете в гардероб — там знову просять паспорт. Ви хочете вийти на балкон — знову паспорт!

Це було б жахливо, правда? Але саме так працює протокол HTTP. Він — як людина з повною амнезією. Він stateless (без стану). Кожен ваш запит до сервера (клік по посиланню, оновлення сторінки) для нього — як перший раз у житті. Він не пам'ятає, що ви ввели логін 5 секунд тому.

❓ Риторичне запитання: Як же тоді Facebook, Google чи ваш інтернет-банкінг пам'ятають, що ви — це ви, поки ви ходите по сторінках?

Тут з'являється поняття Сесія. У реальному клубі вам дають браслет на руку. Ви показуєте браслет (Cookie) — і вас пускають скрізь.

Але де серверу зберігати інформацію про те, кому належить цей браслет?

  1. У звичайній базі даних (PostgreSQL/MySQL)? Можна. Але уявіть, що кожен раз, коли ви дихаєте в клубі, охоронець біжить в архів у підвалі, дістає папку, читає, кладе назад. Це довго (диск повільний).
  2. У файлі на сервері? А якщо серверів у вас 10? Файл лежить тільки на одному.
  3. У пам'яті (RAM)? Бінго! Це миттєво.

Ось тут на сцену виходить Redis. Це наш супершвидкісний "блокнот" в оперативній пам'яті, створений саме для таких задач.


2. 🧠 Теоретична база: Що там "під капотом"?

Давайте розберемося без зайвих академічних термінів.

Redis (Remote Dictionary Server) — це, по суті, гігантська таблиця (словник/хеш-мапа), яка живе в оперативній пам'яті (RAM).

Як це працює в схемі "Клієнт — Сервер — Redis":

  1. Логін: Користувач вводить логін/пароль. Сервер перевіряє їх у головній базі даних (наприклад, Postgres). Все ок?
  2. Створення сесії: Сервер генерує довгий випадковий рядок (наприклад, sess_xyz123). Це ваш "номер браслета".
  3. Запис у Redis: Сервер каже Redis: "Запам'ятай: ключ sess_xyz123 = {user_id: 42, role: admin}".
  4. Відповідь: Сервер віддає цей ключ (sess_xyz123) користувачеві у вигляді Cookie.

Тепер, при кожному кліку, браузер просто показує "браслет" (Cookie). Сервер миттєво питає Redis: "Хто це?". Redis за наносекунди відповідає: "Це адмін, id 42".

🔑 Що треба запам'ятати (Key Concepts):

  • Key-Value (Ключ-Значення): Redis — це просто купа пар "ключ" і "значення". Як змінна в коді.
  • RAM (Оперативна пам'ять): Дані зберігаються там, тому доступ до них у тисячі разів швидший, ніж до жорсткого диска.
  • TTL (Time To Live): Це "кілер-фіча" Redis. Ви можете сказати: "Зберігай цей запис рівно 30 хвилин". Після цього Redis сам, автоматично видалить сесію. Вам не треба писати скрипти очищення сміття!

3. 🧪 Приклади: Від консолі до коду

Давайте подивимось, як це виглядає на практиці.

Приклад 1: "Hello World" у світі Redis (Консоль)

Уявіть, що ми спілкуємося з Redis напряму через термінал.

Ви: SET session:123 "User: David" Redis: OK (Ми зберегли дані)

Ви: GET session:123 Redis: "User: David" (Ми прочитали дані)

Ви: EXPIRE session:123 60 Redis: (integer) 1 (Ми сказали: знищи цей запис через 60 секунд. Таймер пішов!)


Приклад 2: Типовий сценарій авторизації (Псевдокод)

Уявіть, що ви пишете бекенд (наприклад, на Python або JS).

# 1. Користувач залогінився
def login(username, password):
    user = db.find_user(username) # Перевірка в повільній БД (Postgres)

    if user.password == password:
        # Генеруємо унікальний токен (наш "браслет")
        session_token = generate_random_string() 

        # МАГІЯ REDIS:
        # Зберігаємо ID користувача під цим токеном
        # І ставимо таймер на 1 годину (3600 секунд)
        redis.set(name=session_token, value=user.id, ex=3600)

        # Віддаємо токен користувачеві в куки
        return set_cookie("session_id", session_token)

Що тут відбулося? Ми розвантажили основну базу даних. Тепер, поки користувач ходить по сайту, ми не чіпаємо Postgres. Ми "смикаємо" тільки надшвидкий Redis.


Приклад 3: Трохи складніше (Кошик покупок)

Запитання до вас: А що, якщо ми хочемо запам'ятати не тільки те, що користувач залогінений, а і його тимчасовий кошик покупок, навіть якщо він ще не зареєструвався?

Очікування студента: Створити таблицю в базі даних "temp_carts"? Реальність: Ні! Використаємо Redis.

# Користувач додав товар з ID 555
session_token = get_cookie("session_id")

# Отримуємо поточний кошик (який зберігається як рядок JSON)
cart_json = redis.get(session_token) 
current_cart = json.parse(cart_json)

# Додаємо товар
current_cart.append(555)

# Зберігаємо назад у Redis, оновлюємо "таймер життя" ще на годину
redis.set(session_token, json.stringify(current_cart), ex=3600)

Чому це круто? Якщо користувач закриє вкладку і піде назавжди — через годину Redis сам видалить цей кошик. Ваша база даних не буде засмічена мільйонами покинутих кошиків.


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

Час "забруднити руки". Спробуйте подумки (або на папері/в редакторі) вирішити ці задачі.

Завдання 1: База Напишіть команду Redis, яка створює ключ user_session:999 зі значенням active і яка автоматично зникне через 10 секунд. (Підказка: див. Приклад 1)

Завдання 2: Логіка Користувач заходить на сторінку. У нього в куках є токен xyz. Ви робите запит redis.get("xyz") і отримуєте null (пустоту). Що це означає і що має зробити ваш сервер? * А) Пустити користувача. * Б) Перенаправити на сторінку логіну. * В) Викликати поліцію.

Завдання 3: Реальний кейс (Security) Хакери іноді крадуть сесії. У вас є задача: зробити так, щоб одна сесія працювала тільки з однієї IP-адреси. Що саме ви маєте зберегти в Redis як значення ключа сесії? Було: user_id Має стати: ???

Завдання 4: А що, якщо... Сервер Redis раптово перезавантажився (світло вимкнули, а налаштування збереження на диск були вимкнені). Що станеться з усіма користувачами, які зараз на сайті?


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

Ви тепер знаєте, як це працює. Але як не наробити дурниць?

🚫 Типова помилка новачка: Зберігати в сесії забагато даних. Новачки люблять запхати в Redis весь профіль користувача: ім'я, прізвище, адресу, історію замовлень, фотографію кота. Чому це погано? Redis зберігає дані в RAM. RAM — це найдорожчий ресурс сервера. Якщо у вас мільйон користувачів і по 1 МБ даних на кожного — вам знадобиться 1 Терабайт оперативки. Це дорого!

✅ Як думає Senior Developer: "У сесії я зберігаю мінімум, необхідний для ідентифікації (наприклад, тільки user_id і role). Якщо мені треба адреса — я візьму ID з сесії, піду в повільну базу даних і дістану адресу звідти. Пам'ять Redis — для швидкості, а не для архіву".

💡 Порада: Завжди використовуйте префікси (Namespacing). Не називайте ключі просто 123 або alex. Називайте їх session:123 або cart:alex. Коли ваш проект розростеться, ви скажете собі "дякую".


6. 🧩 Підсумок

Отже, що ми сьогодні розібрали?

  1. HTTP — забудькуватий, йому потрібна допомога, щоб впізнавати користувачів.
  2. Бази даних (SQL) — надійні, але повільні для перевірки кожного кліку.
  3. Redis — це наша "оперативна пам'ять" для Інтернету: супершвидка, з автоматичним таймером видалення даних (TTL).
  4. Ви тепер вмієте проектувати механізм логіну, який не "вб'є" вашу базу даних при напливі користувачів.

Тепер ви вмієте: Пояснити, навіщо потрібен Redis для сесій, і чому це стандарт індустрії. Ви розумієте різницю між постійним зберіганням (DB) і тимчасовим (Cache/Session).

🔜 Що далі? У Redis є ще одна суперсила. Уявіть, що ви хочете зробити чат, де повідомлення прилітають миттєво без оновлення сторінки. Для цього Redis має механізм Pub/Sub (Publish/Subscribe). Але це... вже зовсім інша історія.

А поки що — спробуйте встановити Redis локально і написати свій перший SET!


Це був CS50. (ну, майже 😉)