Модуль 15

Redis як message broker

Ось твій урок у стилі CS50! 🎓🔥


🎓 CS50: Redis як Message Broker

Лектор: Твій AI-двійник Девіда Малана Тема: Redis, Pub/Sub, Черги повідомлень Рівень: Від початківця до впевненого користувача


1. 🔥 Вступ: Чому ми не кричимо на кухні?

Уявіть, що ви прийшли до переповненого ресторану. Ви робите замовлення офіціанту: "Мені, будь ласка, піцу пепероні".

Що відбувається далі? Чи біжить офіціант на кухню, стає над душею шеф-кухаря і чекає 20 хвилин, поки тісто спечеться, ігноруючи всіх інших клієнтів?

Звісно, ні! Це було б катастрофою. Ресторан збанкрутував би за день.

Натомість офіціант записує замовлення на клаптик паперу (або вбиває в термінал) і "вішає" його на спеціальну дошку. Він повертається до зали приймати нові замовлення. Кухар, коли звільняється, бачить папірець, готує їжу і дзвонить у дзвоник 🔔.

Оце і є Message Broker (брокер повідомлень).

У світі програмування ми часто маємо ту ж проблему. * Користувач натискає кнопку "Згенерувати звіт" (важка задача). * Якщо ваш веб-сервер буде "стояти над душею" і чекати, поки звіт згенерується, сайт "зависне" для всіх інших.

Нам потрібен посередник. Місце, куди ми кинемо задачу ("Зроби звіт!"), і підемо далі. І сьогодні цим місцем буде Redis.

Риторичне запитання: Чи готові ви дізнатися, як змусити ваші програми спілкуватися між собою так само ефективно, як злагоджена команда на кухні Michelin?


2. 🧠 Теоретична база: Радіо чи Пошта?

Redis — це не просто база даних, де ми зберігаємо ключі та значення (SET key value). Це швейцарський ніж, і одна з його найкрутіших функцій — вміння пересилати повідомлення.

Є два основні підходи, як Redis це робить. І тут важливо зрозуміти різницю на рівні інтуїції.

📡 Підхід №1: Pub/Sub (Видавець / Підписник)

Аналогія: Радіо.

  • Publisher (Видавець): Це діджей. Він каже щось у мікрофон.
  • Subscriber (Підписник): Це ви, слухаєте радіо в машині.
  • Channel (Канал): Частота радіостанції.

Як це працює: Видавець кричить повідомлення в канал "news". Всі, хто прямо зараз підписаний на канал "news", почують це.

🚨 Що треба запам'ятати (Критично!): Якщо ви вимкнули радіо (ваш сервіс впав), а діджей щось сказав — ви це пропустили назавжди. Redis у режимі Pub/Sub не зберігає історію. Це принцип "Fire and Forget" (вистрелив і забув).

📬 Підхід №2: Queue (Черга через List)

Аналогія: Поштова скринька.

  • Producer: Кидає листа в скриньку.
  • Consumer: Приходить пізніше, відкриває скриньку і забирає листа.

Як це працює: Ми використовуємо списки Redis (List). Один сервіс додає задачу в кінець списку, інший забирає з початку.

В чому різниця: Якщо Consumer "спить", повідомлення чекає в Redis, поки його не заберуть. Нічого не губиться.


3. 🧪 Приклади (Дивимось код)

Давайте відкриємо термінал (або уявімо його). Ми будемо використовувати стандартні команди redis-cli, бо вони універсальні.

Приклад А: Чат у реальному часі (Pub/Sub)

Уявіть, що ми робимо чат. Відкрийте два вікна терміналу.

Вікно 1 (Користувач А - Слухач):

SUBSCRIBE general_chat

Запитання до вас: Що станеться? Термінал "зависне". Він перейшов у режим очікування. Він слухає.

Вікно 2 (Користувач Б - Базіка):

PUBLISH general_chat "Привіт, світе!"

Результат у Вікні 1: Ви миттєво побачите повідомлення!

Чому так? Redis виступає як комутатор. Він взяв повідомлення від Б і миттєво перекинув його А.


Приклад Б: Обробка важких задач (Queue)

Тепер реальніший сценарій. Сайт для обробки відео.

  1. Юзер завантажив відео.
  2. Сайт (Web App) каже: "Ок, прийнято" (відповідає за 0.1 сек).
  3. Але хтось має це відео перекодувати (це займає 5 хвилин).

Ми використовуємо список Redis як чергу.

Дія 1: Веб-сервер додає задачу (Producer) Використовуємо LPUSH (Left Push — вставити зліва).

LPUSH video_queue "video_id:12345"
LPUSH video_queue "video_id:12346"

Тепер у нас у Redis є список задач.

Дія 2: Воркер забирає задачу (Consumer) Використовуємо BRPOP (Blocking Right Pop — "Заблокуйся" і чекай, поки справа щось не з'явиться, потім забери).

BRPOP video_queue 0

(Нуль означає "чекати вічно, поки щось не прийде")

Що ви очікуєте побачити? Redis поверне "video_id:12345" і видалить його зі списку. Воркер бере це ID і починає працювати. Якщо запустити ще одного воркера — він забере "video_id:12346".


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

Час "забруднити руки". Якщо у вас є встановлений Redis (або Docker), спробуйте це зараз. Якщо ні — пропишіть логіку на папері.

Завдання 1: "Шпигун" Відкрийте 3 термінали. * У 1-му підпишіться на канал secret_mission. * У 2-му теж підпишіться на secret_mission. * У 3-му надішліть повідомлення "Launch!". * Питання: Скільки разів Redis "розмножив" це повідомлення?

Завдання 2: "Спізнення" * Закрийте всі підписки (термінали 1 і 2). * У 3-му надішліть повідомлення в канал secret_mission. * Знову запустіть підписку в терміналі 1. * Питання: Чи побачите ви повідомлення? Чому? (Згадайте аналогію з Радіо).

Завдання 3: "Надійний поштар" * Використовуйте LPUSH tasks "Email для Олега". * Використовуйте LPUSH tasks "Email для Марії". * Перевірте довжину черги командою LLEN tasks. * Заберіть одне повідомлення через RPOP tasks (без блокування). * Питання: Що залишилось у списку?

Завдання 4 (Для сміливих): Міні-кейс Ви будуєте систему замовлення таксі. * Водіям треба надсилати їхні GPS-координати в реальному часі на карту клієнта. * Клієнту треба надіслати SMS, коли таксі приїхало.

Завдання: Де тут використати Pub/Sub, а де — Чергу (List)? Поясніть свою логіку.


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

Як відрізнити новачка від Senior-розробника при роботі з Redis?

  1. Помилка новачка: Думати, що Pub/Sub — це надійно.

    • Новачок: "Я надіслав повідомлення про оплату через Pub/Sub, але сервіс білінгу перезавантажувався і ми загубили гроші."
    • Профі: Для грошей/замовлень — тільки Черги (Lists) або Redis Streams (просунута тема), або взагалі RabbitMQ. Pub/Sub — це для сповіщень, чатів, оновлення кешів, де втрата одного пакета не критична.
  2. Помилка новачка: Не обробляти збої воркерів.

    • Ситуація: Воркер взяв задачу (RPOP), почав робити і... впав (світло вимкнули). Задача зникла з Redis, але не виконалась. Вона загубилась у "цифровому лімбі".
    • Профі: Використовує патерн "Reliable Queue" (RPOPLPUSH — перекласти задачу в список "в процесі") або просто знає, що Redis — це про швидкість, а не про 100% гарантію транзакцій (якщо не налаштувати правильно).
  3. Порада: Redis — це оперативна пам'ять. Вона швидка, як блискавка, але не гумова. Не пхайте в чергу повідомлень картинки у Base64. Тільки посилання або ID!


6. 🧩 Підсумок

Отже, що ми сьогодні зробили? Ми навчилися розчіплювати (decouple) наші системи.

  1. Ми зрозуміли, що Pub/Sub — це як кричати в мегафон (швидко, для багатьох, але повідомлення летять за вітром).
  2. Ми зрозуміли, що Queue (List) — це як поштова скринька (повідомлення чекає, поки його оброблять).
  3. Тепер ви можете будувати чати, системи сповіщень та фонову обробку задач.

Тепер ви вмієте: ✅ Змусити Python-скрипт "слухати" інший скрипт. ✅ Організувати чергу задач, щоб сервер не "зависав".

Тизер наступного уроку: "Ми тримаємо всі ці повідомлення в пам'яті. Але що станеться, якщо хтось висмикне шнур живлення сервера з розетки? Чи зникнуть всі наші дані назавжди? Наступного разу ми поговоримо про Redis Persistence (RDB та AOF) — як не втратити все, коли гасне світло."

Це був CS50. Побачимось! 👋