English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

гість
1 / ?
назад до уроків

Два Шляхи Носити Більше Вантажу

Добро поживати

Коли послуг починає гнитися під навантаженням, оператор стає перед вибором. Збільшити існуючий комп'ютер (більше ЦП, більше ОЗП, швидкіші диски). або додати більше комп'ютерів, які кожен виконують ту саму роботу.

Перший шлях називається вертикальне збільшення (розширення вгору). Другий - горизонтальне збільшення (розширення в сторони).

Ця лекція вчить, чому майже кожна сучасна веб-архітектура обирає горизонтальне та яка властивість навантаження робить цей вибір можливим. Відповідь знаходиться в одній слові: стан.

Після закінчення ви розумієте:

- Криві витрат вертикального та горизонтального збільшення та де кожен з них має сенс

- Що означає 'станова' та 'безстандартова' на практиці та чому один з них дешево множиться

- Математика, яка розмірно флот репліки під очікуване та пікове навантаження

- Правило простору, яке запобігає зруйнування шару

- Куди потрібно розмістити стан (стан не зникає) та як витіснити його з шарів, які потрібно масштабувати

Чому Горизонтальне Перемагає Поза Порогом

Вертикальне збільшення: Один Більший Бокс

Плюси: просте. Без змін коду. Без координації. Той самий процес тепер має більше ЦП.

Мінуси: стеля. Найбільша комерційно доступна ВМ має кінцеве ОЗП та ядра ЦП. Над цим, гроші не купують додаткового простору. Витрати зростають надзвичайно швидкими темпами після оптимального розміру пропозиції вендора. Провал однієї машини призводить до повного зриву послуги.

Горизонтальне збільшення: Малі Бокові Бокси

Плюси: немає стелі (до вашої готовності платити та координувати машини). Ємність додається лінійно з відсотком репліки, передбачувано. Провал однієї репліки видаляє 1/N ємності, а не 100%.

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

Перетин: будь-який продуктивний сервіс, який повинен виживати при будь-якій одноразовій відмові системи, повинен працювати принаймні на двох машинах. Коли ви приймаєте два, ви вже обираєте горизонтальне масштабування. Звідти питання не «ми повинні?», а «як недорого ми можемо додати наступний репліку?»

Ключовий втілювач: навантаження, яке не містить стану на запит на машину. Тоді будь-яка репліка може відповідати на будь-яке запитання, та додавання репліки додає ємність без координації.

Вертикальне та горизонтальне масштабування: крива витрат та стеля

Команда працює над послугом на одній ВМ з 8 ядрами ЦП, яка обробляє 800 запитів/секунд на 60% ЦП. Вони очікують, що трафік зросте в 4 рази протягом наступного року. Вони обговорюють: орендувати 32-ядерну ВМ (вертикально), або запустити чотири ідентичні 8-ядерні ВМ за допомогою балансатора навантаження (горизонтально). Я рекомендую якийсь варіант, та назвіть дві причини, які виходять за межі чистої ємності.

Статевий vs Безстановий у практиці

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

Статевий компонент: тримає інформацію, втрату якої змінить поведінку. База даних, яка тримає облікові дані користувача. Кеш, який тримає токени сесії. Робочий, який закріплює тривалий час потік струменя до конкретного користувача.

Безстановий компонент: не тримає інформації, втрату якої буде мати значення. Веб-шар, який читає запит, запитує базу даних, та пише відповідь. Кожен запит стоїть сам по собі; шар не пам'ятає нічого між запрошеннями.

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

Практичний тест: якщо ви випадково вбили один процес у цьому шарі та запустили його знову, чи якийсь користувач зіткнувся з неправильною відповіддю або втратою сесії? Якщо так, він тримає стан. Якщо ні, він не тримає.

Приклади

- Python веб-процес, який читає запити, запитує Postgres, повертає JSON: безстановий. Стан живе в Postgres.

- Python веб-процес, який тримає корзини покупців користувачів у локальній пам'яті: становий. Вилучення процесу втрачає корзини.

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

- Кеш Redis перед фронтальной Postgres: состоящий в состоянии кеша, но допустимый, если пропускаются запросы к кешу. Провал реплики означает пропуск кеша, а не потеря данных.

Проектирование для горизонтального масштабирования = перенос состояния из слоя, который должен масштабироваться.

Аудит подозреваемого уровня

Команда работает с API рекомендаций на 6 задних виртуальных машин за реверс-прокси. Приложение: читает идентификатор пользователя из запроса, извлекает последнюю активность пользователя из Postgres, выполняет алгоритм оценки, возвращает список рекомендуемых товаров. Два нестандартных поведения:

- Приложение сохраняет 'последнюю активность пользователя' в кэше процессной памяти, заполненный на первом запросе для пользователя, используемый на последующих запросах.

- Приложение использует "связанные сессии": как только пользователь нажмет на VM #3, все их последующие запросы будут отправляться на VM #3 (прокси настроен на связанное маршрутизацию по файлу cookie).

Определите, какой из этих двух поведений делает уровень состоящим в состоянии и объясните, что бы сломалось, если команда попыталась увеличить масштабирование с 6 виртуальных машин до 12. Затем предложите переосмысление, которое позволяет уровню масштабироваться горизонтально без потери выгоды кэша пользователя.

Формула реплики

Самый простой формулы мощности

Как только уровень становится без состояния, его размер становится арифметикой. Вам нужно достаточно реплики, чтобы постоянная нагрузка прибыла и ушла с той же скоростью, с запасом для всплеска.

Формула:

реплики = ⌈ (peak_load × surge_factor) / per_replica_capacity ⌉ + headroom

Где:

- peak_load: максимальное продолжительное запросов/секунду, которые вы ожидаете в нормальной работе

- surge_factor: множитель, покрывающий кратковременные всплески выше максимального (обычно от 1,5x до 2x для предсказуемого трафика, 3x или больше для вирусного / непредсказуемого)

- per_replica_capacity: запросы/секунду, которые обрабатывает одна реплика с приятной задержкой и использованием (обычно измеряется при 70% CPU, не на предельной нагрузке)

- headroom: дополнительные реплики, чтобы несколько случаев провала реплики не разрушили уровень (обычно 1-2 реплики для небольших флотов, 10-20% для более крупных)

Примітка: приклад. Backend обслуговує 100 запит/с на одній репліці, витрачаючи 70% CPU. Максимальна навантаження - 600 запит/с. Очікується час від часу короткочасні збільшення до 2 разів. Вам потрібно, щоб служба витримала 2 випадкових відмов реплік.

репліки = ⌈ (600 × 2) / 100 ⌉ + 2 = 12 + 2 = 14 реплік

Правило 80%

Вміст репліки не є межею насыщення. Вимірюйте місткість на рівні 70-80% CPU, а не 100%.

Після 80% використання, криві відставання зростають різко: черга, яка займала 10 мс при 60% використання, займатиме 80 мс при 90% використовуваності. Задерження, а не швидкість передачі, перше зривається. (Паралельний урок 'геометрія безстандартної горизонтальної масштабування' виводить цю криву математично.)

Автомасштабування проти Статичного Наділення

Статичне: надходить ресурс для максимальної навантаження × резервний простір для збільшення та приймає витрати на роботу при низькій ефективності поза піком.

Автомасштабування: керуючий модуль додає та видаляє репліки на основі спостережуваної ефективності, мети задерження або глибини черги.

Попередження щодо автомасштабування: час холодного запуску має значення. Якщо нова репліка займає 2 хвилини на завантаженні, автомасштабування не може відповісти на короткочасне збільшення до 30 секунд. Досвідчений автомасштабування тримає теплу пул реплік нижче порогу збільшення.

Формула розміщення реплік з прикладом

Розмірніть флот для нової служби

Ваші колеги планують запустити API метаданих відео. Бенчмарки показують, що одна репліка обслуговує 250 запит/с при 70% CPU та 50 мс п99 задерження. Маркетинг спрогнозував максимальне навантаження 4,000 запит/с під час годин піку. Планове промо-мероприство може збільшити навантаження до 3 разів. Вам потрібно, щоб служба витримала 3 одночасних відмов реплік без перевищення 80% ефективності на виживших.

Застосуйте формулу репліки для розміщення запуску флоту. Показіть ваші кроки по кроці, а потім поясніть одну причину, чому ваша кількість може бути неправильною (холодний старт, прогрів кешу, затримка залежності, будь-які аргументи, які можна захистити).

Холодний старт, повільне відведення та інші реальні кути

Реальні флоти мають реальні кути

Формула припускає, що репліки з'являються миттєво, приймають трафік миттєво та відкидають трафік миттєво. Ніхто з цих припущень не виконується у виробництві.

Холодний старт: новій репліці потрібно завантажити ОС, запустити процес, завантажити конфігурацію, прогріти кеші та пройти перевірку здоров'я. Час від 5 секунд (перезапуск контейнера) до 5 хвилин (повний запуск ВМ + завантаження зображення). Автомасштабування не може реагувати на піки тривалістю менше цього затримання.

Помилкова витратка: репліка, яка видаляється з пулів, потребує часу для завершення активних запитів перед тим, як завершити роботу. У користувачів це може призвести до обрізання відповідей. Проксі підтримують витратку (зупинка прийому нових запитів, завершення активних) але це займає секунди-мініти.

Гаряча пул: продуктивні флоти тримають пул попередньо наділені, але безактивних реплік, готових приймати трафік за сигналом. Торгують малою постійною витратою на швидку реакцію на попит.

Відведення підключень проти негайного вбивства: поступове виведення з роботи має значення. SIGTERM, який викликає витратку, займає більше часу, ніж SIGKILL, але не порушує запитів користувача.

Час вікон перевірки здоров'я: репліка, яка тільки що розпочала роботу, може успішно пройти перше вікно перевірки здоров'я до того, як її базова підключення до бази даних будуть прогріти; проксі, отже, відправляє реальний трафік та перші десятка запитів є повільними. Тунінгайте вікна перевірки здоров'я для тестування реальної траси, а не лише живості процесу.

Проникнення стікінесу: навіть номінально безстандартні шари накопичують стікінес з часом (кеші CDN, кеші розв'язувача DNS, басейни підключень). Буďte підозрілий до "ідентичних реплік", які однаково поводяться по-різному.

Гаряча пул або реагуюча автомасштабування?

API вашої відеометаданих (той самий, який раніше, розмірений на 51 репліку для постійного піку + спалаху) зазнає 30-секундної спалаху до 5-кратного нормального навантаження при завантаженні нової вірусної відео. Автомасштабування зараз займає 90 секунд для додавання нової репліки зі холодного стану (завантаження зображення + прогрів). Під час 90-секундної діри час latency стрімко зростає та деякі запити закінчуються часом.

Представте пропозицію. Виберіть: (а) залишити реагуюче автомасштабування, але налаштувати його по-інакшому, (б) наділяти попередньо пул безактивних реплік, або (в) статично наділяти для постійного 5-кратного максимума. Обґрунтуйте свій вибір та назвіть одну вартість, яку інші варіанти накладуть.

Розробіть безстандартний шар з обмеженнями

Синтез

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

Застосуйте всі чотири.

Розробіть задній шар для feed.example.com, соціальної-постачальної API. Обмеження: ємність на репліку 200 req/s при 70% CPU; очікуване пікове навантаження 1500 req/s; коефіцієнт пікового навантаження 2.5x (рідкісні тредінгові історії); витримувати 2 одночасові випадки відмов репліки; час холодного запуску 60 секунд; вибухи можуть тривати 45 секунд; бюджет дозволяє деяку зайву ємність, але не постійне 2.5x розподілення.

Розмірить стабільний флот (покажіть математичне вираження), оберіть стратегію обробки піків (тепла басейна / реагуюче автомасштабування / обидва) та ідентифікуйте одну частину стану на користувача, яку ймовірно зберігає додаток та де вона повинна переміститися, щоб зберігати шар без стану.

Куди йде ця Курс

Куди йде ця Курс

Тепер ви маєте працюючий розумовий модел станинного шару: чому він масштабується, як розмірити його, що зривається на його межах та де стан повинен переміститися, коли ви відкидаєте його з шару, який повинен рости.

Наступне урок у цьому курсі (cs_distsys_ingress_egress_separation) вирішує більш субтильну проблему: навіть ідеально розмірений станинний шар може зриватися у несподіваних випадках, коли входяще та виходяще трафік ділять ту ж мережну дорогу. Класичним прикладом є проксі, яке намагається з'єднатися з самим собою; вирішення полягає у розділі одного шару на два з різними відповідальностями.

Паралельний урок: geometry_of_stateless_horizontal_scaling виводить криву чергування, закон Літтла, застосований до флоту реплік, та геометричне значення колінеютилізації на 80%.

Добре зроблено. Надалі.