Модуль 23

Redis Cluster: масштабування та shardинг

Ось готовий урок, створений спеціально для тебе у стилі David Malan. Приготуйся, буде динамічно!


🎓 CS50-Style: Redis Cluster — Масштабування та Шардинг

Привіт, друзі! 👋

Сьогодні ми виходимо за межі "одного сервера". Ми поговоримо про те, що відрізняє маленький домашній проект від глобальної системи рівня Facebook чи Twitter.

Ми поговоримо про Redis Cluster.


1. 🔥 Вступ: Коли один сервер каже "Досить!"

Уявіть, що ви відкрили кав’ярню. У вас є один бариста (це наш єдиний Redis сервер). Він супершвидкий, робить каву за секунди. Клієнти щасливі, ви щасливі.

Але раптом ваша кава стає вірусною в TikTok. Наступного ранку у черзі не 10 людей, а 10 000.

Ваш бариста — герой, але він фізично не може зробити 10 000 чашок одночасно. Його пам'ять (RAM) переповнена замовленнями, руки (CPU) палають. Що робити?

Змусити баристу працювати швидше? (Це Vertical Scaling — купити потужніший сервер). Але навіть Супермен має межу. Правильне рішення: найняти ще 10 барист. (Це Horizontal Scaling).

Але тут виникає проблема: Як клієнт знає, до якого баристи йти за своїм замовленням? Якщо я замовив лате у Баристи №1, а прийду забирати до Баристи №5, він скаже: "Я поняття не маю, хто ти".

Саме цю проблему вирішує Redis Cluster за допомогою шардингу (sharding). Без цього ваші дані перетворяться на хаос, а сервіс впаде під навантаженням.


2. 🧠 Теоретична база: Магія слотів

Давайте заглянемо під капот. Як Redis ділить дані між серверами?

Він не просто кидає ключі випадковим чином. Він використовує систему, схожу на гардероб у театрі.

🔑 Головне поняття: Hash Slot (Хеш-слот)

Уявіть, що у всьому всесвіті Redis Cluster існує рівно 16 384 полички (слоти). Це константа. Не більше, не менше.

Кожен сервер (нода) у вашому кластері відповідає за певну частину цих поличок. * Нода А бере слоти 0 – 5500. * Нода B бере слоти 5501 – 11000. * Нода C бере слоти 11001 – 16383.

⚙️ Алгоритм (Інтуїтивно)

Коли ви зберігаєте ключ, наприклад SET user:100 "Alex", Redis робить просту математику:

  1. Бере ім'я ключа (user:100).
  2. Перетворює його на число (через алгоритм CRC16).
  3. Бере остачу від ділення на 16384.
    • CRC16("user:100") % 16384 = 3450 (умовно).
  4. Redis дивиться на карту: "Ага, слот 3450 належить Ноді А".
  5. Запис летить на Ноду А.

❗️ Запам'ятайте: Клієнт (ваша програма) або сам Redis завжди знає, де лежить ключ, завдяки цій формулі. Вам не треба перевіряти всі сервери по черзі!


3. 🧪 Приклади: Від простого до болючого

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

Приклад 1: Простий запис

Ситуація: Ми підключаємось до кластера і пишемо дані.

# Ми підключилися до Ноди А (порт 7000)
127.0.0.1:7000> SET apple "red"
OK

Чому це спрацювало? Тому що хеш для слова "apple" випадково потрапив у діапазон слотів, якими володіє саме ця нода (7000). Пощастило.

Приклад 2: "Іди геть!" (Redirect)

Ситуація: Ми все ще на Ноді А, але пишемо ключ, який належить Ноді B.

Питання до вас: Що станеться, якщо я напишу SET banana "yellow" на Ноді А, але математика каже, що цей слот на Ноді B? (Подумайте секунду...)

Реальність:

127.0.0.1:7000> SET banana "yellow"
(error) MOVED 12450 127.0.0.1:7001

Redis на порту 7000 каже: "Це не моя поличка! Слот 12450 живе на порту 7001. Йди туди!". Розумний Redis-клієнт (бібліотека у вашому коді) побачить цю помилку, автоматично піде на порт 7001 і запише дані. Ви навіть не помітите цього в коді. Але в консолі (redis-cli) ви це побачите.

Приклад 3: Проблема Multi-Key (Це важливо!)

Ситуація: Ви хочете отримати два ключа однією командою (MGET), щоб зекономити час. MGET user:1 user:2

Якщо user:1 лежить на Ноді А, а user:2 на Ноді B — операція провалиться. Redis Cluster не вміє робити транзакції між різними нодами (cross-slot operations).

Рішення: Hash Tags {...}. Якщо ви назвете ключі {users}:1 і {users}:2, Redis для обчислення слота візьме тільки те, що у дужках — слово users. Оскільки слово однакове -> хеш однаковий -> слот однаковий -> одна й та сама нода. Бінго!


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

Час забруднити руки. Уявімо, що у вас запущено локально 3 ноди Redis Cluster (порти 7000, 7001, 7002).

🔹 Завдання 1: "Ручний GPS"

Запустіть redis-cli -c -p 7000 (прапорець -c вмикає режим кластера, клієнт буде сам "ходити" за перенаправленнями). 1. Виконайте SET framework "Django". 2. Подивіться на вивід. Чи перекинуло вас на інший порт? 3. Виконайте GET framework. Мета: Побачити, як клієнт "стрибає" між нодами.

🔹 Завдання 2: "Зламайте систему"

Спробуйте виконати операцію, яка зачіпає ключі з різними хешами без дужок: MSET key1 "value1" key2 "value2" Очікування: Отримайте помилку CROSSSLOT Keys in request don't hash to the same slot. Мета: Відчути біль розподілених систем.

🔹 Завдання 3: "Виправлення Хеш-тегами"

Перепишіть ключі з попереднього завдання, використовуючи {tag}. Наприклад: MSET {mydata}.key1 "value1" {mydata}.key2 "value2" Мета: Переконатися, що тепер це працює атомарно.

🔹 Завдання 4: Міні-кейс "Чатик"

Ви робите чат. У вас є повідомлення для кімнати room:42. Придумайте схему ключів для: 1. Списку повідомлень. 2. Списку активних юзерів у цій кімнаті. Умова: Ми хочемо отримувати і повідомлення, і юзерів за один запит до Redis, щоб чат вантажився миттєво. (Підказка: Використовуйте {room:42} як частину ключа).

🔹 Завдання 5: А що, якщо...

Що буде, якщо Нода B згорить? Чи втратимо ми дані? Відповідь для роздумів: Згадайте про Replicas (Master-Slave). У кластері у кожного Майстра зазвичай є Слейв, який чекає свого часу, щоб стати головним.


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

Як відрізнити новачка від профі в Redis Cluster?

Новачок: * Думає, що Redis Cluster — це просто "один великий Redis". * Використовує складні команди типу KEYS * або MGET на весь кластер і дивується, чому все гальмує або падає з помилками. * Не моніторить розподіл слотів (одна нода може бути перевантажена, якщо всі ключі потраплять в один хеш-тег).

Профі: * Планує ключі наперед. Він знає, які дані мають жити поруч (на одній ноді) для швидкого доступу. * Використовує пайплайни (Pipelining) розумно, групуючи запити до відповідних нод. * Боїться "Гарячих ключів" (Hot Keys). Якщо ви запхаєте всі дані під один тег {global}, то весь трафік піде на одну бідну ноду, і сенс кластера зникне.

Порада з практики:

Якщо вам не потрібні терабайти пам'яті, можливо, вам не потрібен Cluster. Часто достатньо одного потужного Redis + Replicas (Sentinel). Cluster додає складність. Використовуйте його, коли дійсно впираєтесь у ліміт RAM або CPU одного ядра.


6. 🧩 Підсумок

Отже, що ми маємо в сухому залишку?

  1. Масштабування: Redis Cluster дозволяє розбити дані на шматки (шарди).
  2. Слоти: Їх 16384. Це карта координат ваших даних.
  3. Клієнти: Мають бути розумними (cluster-aware), щоб знати, куди йти.
  4. Hash Tags {}: Ваш інструмент, щоб тримати пов'язані дані разом.

Тепер ви можете будувати системи, які витримають навалу мільйонів користувачів, і ваш "цифровий бариста" не зійде з розуму!

🚀 Наступного разу: Ми розігналися до космічних швидкостей, але що буде, якщо вимкнуть світло? Чи зникнуть всі дані? На наступному уроці ми розберемо Persistence (RDB vs AOF) — як зберегти дані на диск, не втрачаючи швидкості.

А поки — спробуйте запустити свій перший кластер! Удачі! 💻