Створення масштабованого API на спотових інстансах AWS

Всім привіт! Мене звуть Кирило, я CTO в Adapty. Більшість нашої архітектури знаходиться на AWS, і сьогодні я розповім про те, як ми скоротили витрати на сервери в 3 рази за рахунок використання спотових інстансів на продакшн оточенні, а також про те, як налаштувати їхнє автомасштабування. Спершу буде огляд того, як це працює, а потім докладна інструкція для запуску.

Що таке спотові інстанси?

Спотові інстанси — це сервери інших користувачів AWS, які зараз простоюють, і вони продають їх з великою знижкою (Amazon пише до 90%, на наш досвід ~3x, варіюється в залежності від регіону, AZ і типу інстансу). Основна їхня відмінність від звичайних у тому, що вони можуть вимкнутись у будь-який момент. Тому ми довгий час вважали, що їх нормально використовувати для дів оточень, або для завдань з розрахунку чогось зі збереженням проміжних результатів на S3 або в базу, але не для прода. Існують сторонні рішення, які дозволяють використовувати споти на проді, але там для нашого кейсу багато милиць, тому ми не впроваджували їх. Підхід, описаний у статті, працює повністю у рамках стандартного функціоналу AWS, без додаткових скриптів, кронів тощо.

Далі наведу кілька скріншотів, які показують історію цін на спотові інстанси.

m5.large у регіоні eu-west-1 (Ireland). Ціна переважно стабільна протягом 3 місяців, зараз економія 2.9x.

Створення масштабованого API на спотових інстансах AWS

m5.large у регіоні us-east-1 (N. Virginia). Ціна постійно змінюється протягом 3 місяців, зараз економія від 2.3 до 2.8 в залежності від зони доступності.

Створення масштабованого API на спотових інстансах AWS

t3.small у регіоні us-east-1 (N. Virginia). Ціна стабільна протягом 3 місяців, зараз економія 3.4x.

Створення масштабованого API на спотових інстансах AWS

Архітектура сервісу

Базова архітектура сервісу, про який ми говоритимемо в рамках цієї статті, зображена на діаграмі нижче.

Створення масштабованого API на спотових інстансах AWS

Application Load Balancer → EC2 Target Group → Elastic Container Service

Як балансувальник використовується Application Load Balancer (ALB), який надсилає запити до EC2 Target Group (TG). TG відповідає за те, щоб відкрити на інстансах порти ALB і зв'язати їх з портами контейнерів Elastic Container Service (ECS). ECS - це аналог Kubernetes в AWS, який займається менеджментом контейнерів Docker.

На одному інстансі може бути кілька працюючих контейнерів з однаковими портами, тому ми можемо задати їх фіксовано. ECS повідомляє TG, що він запускає новий таск (у термінології Kubernetes це називається під), вона робить перевірку вільних портів на інстансі і призначає один з них для таска, що запускається. Також TG регулярно перевіряє, чи працює інстанс та апі на ньому за допомогою health check, і якщо бачить якісь проблеми, то перестає передавати туди запити.

EC2 Auto Scaling Groups + ECS Capacity Providers

У наведеній вище діаграмі не показано обслуговування EC2 Auto Scaling Groups (ASG). З назви можна зрозуміти, що він відповідає за масштабування інстансів. При цьому донедавна AWS не мала вбудованої можливості керувати кількістю запущених машин з ECS. ECS дозволяв масштабувати кількість тяган, наприклад, використання CPU, RAM або кількості запитів. Але якщо таски займали всі вільні інстанси, нові машини автоматично не піднімалися.

Це змінилося з появою ECS Capacity Providers (ECS CP). Тепер кожен сервіс в ECS можна зв'язати з ASG, і якщо таски не вміщаються на працюючих інстансах, піднімуться нові (але в рамках встановлених лімітів ASG). Це працює і у зворотний бік, якщо ECS CP бачить інстанси, що простоюють без тяган, то він дасть команду ASG, щоб вона їх вимкнула. ECS CP має можливість вказати цільовий відсоток завантаження інстансів, так, щоб деяка кількість машин була завжди вільно для швидкого масштабування тяган, розповім про це трохи пізніше.

EC2 Launch Templates

Останній сервіс, про який я розповім, перш ніж перейти до детального опису створення цієї інфраструктури, є EC2 Launch Templates. Він дозволяє створити шаблон, за яким запускатимуться всі машини, щоб не повторювати це щоразу з нуля. Тут можна вибрати тип машини, що запускається, групу безпеки, образ диска і багато інших параметрів. Також можна вказати дані користувача, які будуть залиті на всі інстанси, що запускаються. У даних користувача можна запускати скрипти, наприклад, можна відредагувати вміст файлу конфігурації ECS агента.

Один із найважливіших у рамках цієї статті параметром конфігурації — ECS_ENABLE_SPOT_INSTANCE_DRAINING= true. Якщо цей параметр увімкнений, то як тільки ECS отримує сигнал про те, що спотовий інстанс забирають, він переводить всі таски, які працюють на ньому статус Draining. Ніякі нові таски на цей інстанс не призначатимуться, якщо є таски, які прямо зараз хочуть викотитися на нього, вони скасовуються. Запити з балансувальника теж не приходять. Повідомлення про видалення інстансу надходить за 2 хвилини до фактичної події. Тому якщо ваш сервіс не виконує завдань довше 2 хвилин і не зберігає нічого на диску, то ви можете використовувати спотові інстанси без втрати даних.

Щодо диска — AWS нещодавно зробив Можливе використання Elastic File System (EFS) разом з ECS, з цією схемою навіть диск не є перешкодою, але ми це не пробували, тому що в принципі нам диск не потрібен для зберігання стану. За замовчуванням після отримання SIGINT (відправляється в момент переведення тяга в статус Draining) всі завдання, що працюють, будуть зупинені через 30 секунд, навіть якщо вони не встигли виконатися, змінити цей час можна за допомогою параметра ECS_CONTAINER_STOP_TIMEOUT. Головне не виставляти його більше ніж 2 хвилини для спотових машин.

Створення сервісу

Переходимо безпосередньо до створення описаного сервісу. У процесі я опишу додатково кілька корисних моментів, про які не йшлося вище. Загалом це покрокова інструкція, але якісь зовсім базові чи навпаки дуже специфічні кейси я не розглядатиму. Усі дії виконуються у візуальній консолі AWS, але їх можна відтворити програмно за допомогою CloudFormation або Terraform. У Adapty ми використовуємо Terraform.

EC2 Launch Template

У цьому сервісі створюється конфігурація машин, які використовуватимуться. Управління шаблонами відбувається у розділі EC2 -> Instances -> Launch templates.

Amazon machine image (AMI) — вказуємо образ диска, з яким запускатимуться всі інстанси. Для ECS найчастіше варто використовувати оптимізований образ від Amazon. Він регулярно оновлюється та містить все необхідне для роботи ECS. Щоб дізнатися про актуальний ID образу, заходимо на сторінку Amazon ECS-optimized AMIs, вибираємо регіон і копіюємо AMI ID для нього. Наприклад, для регіону us-east-1 актуальний на момент написання статті ID. ami-00c7c1cf5bdc913ed. Цей ID потрібно вставити у пункт Specify a custom value.

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

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

Мережеві настройки - Вказуємо параметри мережі. Networking platform у більшості випадків має бути Virtual Private Cloud (VPC). Групи безпеки - Групи безпеки для ваших інстансів. Оскільки ми будемо використовувати балансувальник перед інстансами, то рекомендую вказувати групу, яка дозволяє вхідні з'єднання тільки з балансувальника. Тобто у вас буде 2 групи безпеки, одна для балансувальника, яка дозволяє вхідні (inbound) з'єднання звідусіль по портах 80 (http) і 443 (https), а друга для машин, яка дозволяє вхідні з'єднання по будь-яких портах від групи балансувальника. Вихідні (outbound) з'єднання обох групах необхідно відкрити TCP протоколу попри всі порти попри всі адреси. Можна обмежити порти та адреси для вихідних з'єднань, але тоді потрібно постійно моніторити, що ви не намагаєтеся звернутися кудись закритим портом.

Storage (volumes) - Вказуємо параметри дисків для машин. Об'єм диска не може бути меншим від того, що заданий в AMI, для ECS Optimized - 30 GiB.

Розширені деталі - Вказуємо додаткові параметри.

Purchasing option — чи хочемо купувати спотові інстанси. Ми хочемо, але тут цю галочку не будемо відзначати, налаштуємо це в Auto Scaling Group, там більше опцій.

Профіль екземпляра IAM - Вказуємо роль, з якої запускатимуть інстанси. Для того, щоб інстанси працювали в ECS, їм потрібні права, які зазвичай лежать у ролі ecsInstanceRole. У деяких випадках вона може бути створена, якщо ні, то тут інструкція про те, як це зробити. Після створення вказуємо її у шаблоні.
Далі йде багато параметрів, переважно скрізь можна залишати дефолтні значення, але в кожного з них зрозумілий опис. Я завжди вмикаю параметри EBS-optimized instance та T2/T3 Unlimited, якщо використовуються burstable інстанси.

Час користувача - Вказуємо дані користувача. Ми будемо редагувати файл /etc/ecs/ecs.config, В якому лежить конфігурація агента ECS.
Приклад того, як виглядає user data:

#!/bin/bash
echo ECS_CLUSTER=DemoApiClusterProd >> /etc/ecs/ecs.config
echo ECS_ENABLE_SPOT_INSTANCE_DRAINING=true >> /etc/ecs/ecs.config
echo ECS_CONTAINER_STOP_TIMEOUT=1m >> /etc/ecs/ecs.config
echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config
echo "ECS_ENGINE_AUTH_DATA={"registry.gitlab.com":{"username":"username","password":"password"}}" >> /etc/ecs/ecs.config

ECS_CLUSTER=DemoApiClusterProd - Параметр вказує, що інстанс належить кластеру із заданим ім'ям, тобто цей кластер зможе розміщувати на цьому сервері свої таски. Ми поки що не створили кластер, але при створенні будемо використовувати це ім'я.

ECS_ENABLE_SPOT_INSTANCE_DRAINING=true - Параметр вказує, що при отриманні сигналу про вимкнення спотового інстансу, всі таски на ньому повинні переводитися в статус Draining.

ECS_CONTAINER_STOP_TIMEOUT=1m — параметр вказує, що після отримання сигналу SIGINT у всіх завдань є 1 хвилина, перш ніж їх уб'ють.

ECS_ENGINE_AUTH_TYPE=docker — параметр вказує, що як механізм авторизації використовується docker-схема

ECS_ENGINE_AUTH_DATA=... — параметри підключення до приватного container registry, де зберігаються ваші образи Docker. Якщо він публічний, то нічого не треба вказувати.

У рамках цієї статті я використовуватиму публічний образ із Docker Hub, тому вказуватиму параметри ECS_ENGINE_AUTH_TYPE и ECS_ENGINE_AUTH_DATA не потрібно.

Корисно знати: рекомендується регулярно оновлювати AMI, тому що в нових версіях оновлюються версії Docker, Linux, ECS агента та ін. Щоб не забувати про це, можна налаштувати повідомлення про вихід нових версій. Ви можете отримувати повідомлення на email та оновлювати руками, а можете написати Lambda-функцію, яка автоматично створюватиме нову версію Launch Template з оновленим AMI.

EC2 Auto Scaling Group

Auto Scaling Group відповідає за запуск та масштабування інстансів. Управління групами відбувається у розділі EC2 -> Auto Scaling -> Auto Scaling Groups.

Launch template - Вибираємо створений на попередньому кроці шаблон. Версію залишаємо дефолтну.

Purchase options and instance types - Вказуємо типи інстансів для кластера. Adhere to launch Template використовує тип інстансу з Launch Template. Combine purchase options and instance types дозволяє гнучко налаштовувати типи інстансів. Ми будемо використовувати його.

Optional On-Demand base — кількість звичайних, не спотових інстансів, які завжди працюватимуть.

On-Demand percentage above base - Відсоткове співвідношення звичайних і спотових інстансів, 50-50 розподілятиме порівну, 20-80 на кожен звичайний інстанс буде підніматися 4 спотові. У рамках цього прикладу я вкажу 50-50, але насправді ми найчастіше робимо 20-80, у деяких випадках 0-100.

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

Створення масштабованого API на спотових інстансах AWS

мережу — налаштування мережі, вибираєте VPC та підмережі для машин, у більшості випадків варто вибрати всі доступні підмережі.

Балансування навантаження - Налаштування балансувальника, але ми це зробимо окремо, тут нічого не чіпаємо. Перевірки стану здоров'я також буде налаштовано пізніше.

Розмір групи - Вказуємо ліміти на кількість машин у кластері та бажану кількість машин на старті. Кількість машин у кластері ніколи не стане меншою за мінімально вказану і більшу за максимальну, навіть якщо за метриками має відбутися масштабування.

Scaling policies — параметри масштабування, але ми масштабуватимемо, відштовхуючись від запущених ECS тяг, тому налаштуємо масштабування пізніше.

Instance scale-in protection — захист інстансів від видалення під час масштабування вниз. Включаємо, щоб ASG не видалила машину, на якій є таски, що працюють. Відключатиме захист для інстансів, на яких немає тяган, буде ECS Capacity Provider.

Додати теги можна вказати теги для інстансів (для цього повинна стояти галочка Tag new instances). Рекомендую вказати тег Name, тоді всі інстанси, які запускаються в рамках групи, однаково називатимуться, їх зручно дивитися в консолі.

Створення масштабованого API на спотових інстансах AWS

Після створення групи відкрийте її і зайдіть в розділ Advanced configurations, чому на етапі створення консолі видно не всі опції.

Termination policies - Правила, які враховуються при видаленні інстансів. Вони використовуються по порядку. Ми зазвичай використовуємо такі, як на малюнку нижче. Спочатку видаляються інстанси з найстарішим Launch Template (наприклад, якщо ми оновили AMI, ми створили нову версію, але всі інстанси встигли на неї перейти). Потім вибираються інстанси, які найближче до наступної розрахункової години по білінгу. І далі вибираються найстаріші за датою запуску.

Створення масштабованого API на спотових інстансах AWS

Корисно знати: для оновлення всіх машин у кластері, зручно використовувати Instance Refresh. Якщо поєднати це з функцією Lambda з попереднього кроку, то у вас буде повністю автоматизована система апдейта інстансів. Перед оновленням всіх машин необхідно вимкнути instance scale-in protection для всіх інстансів у групі. Не налаштування групи, а саме захист з самих машин, це робиться на вкладці Instance management.

Application Load Balancer та EC2 Target Group

Балансувальник створюється у розділі EC2 → Load Balancing → Load Balancers. Ми будемо використовувати Application Load Balancer, порівняння різних типів балансувальників можна прочитати на сторінці сервісу.

Слухачі — має сенс зробити 80 і 443 порти і зробити редирект з 80 на 443 з допомогою правил балансировщика.

Зони доступності - Найчастіше вибираємо всім зони доступності.

Налаштуйте параметри безпеки - тут вказується SSL-сертифікат для балансувальника, найзручніший варіант - зробити сертифікат в ACM. Про відмінності Політика безпеки можна почитати в документації, можна залишати вибраний за замовчуванням ELBSecurityPolicy-2016-08. Після створення балансувальника, ви побачите його Ім'я DNS, на який потрібно настроїти CNAME для вашого домену. Наприклад, так це виглядає у Cloudflare.

Створення масштабованого API на спотових інстансах AWS

Група безпеки - створюємо або вибираємо групу безпеки для балансувальника, детальніше про це писав трохи вище в розділі EC2 Launch Template → Network settings.

Цільова група — створюємо групу, яка відповідає за роутинг запитів з балансувальника на машини та перевіряє їхню доступність, щоб замінити у разі проблем. Тип цілі повинен бути Instance, протокол и порт будь-які, якщо ви використовуєте HTTPS для спілкування між балансувальником та інстансами, то на них треба завантажити сертифікат. У рамках цього прикладу ми цього робити не будемо, просто залишимо 80 портів.

Перевірки стану здоров'я - Параметри перевірки працездатності сервісу. У цьому сервісі це має бути окремий запит, який реалізує важливі частини бізнес-логіки, в рамках цього прикладу я залишу налаштування за замовчуванням. Далі можна вибрати інтервал запитів, таймаут, коди успішних відповідей та ін. У прикладі вкажемо Success codes 200-399, тому що Docker образ, який буде використовуватися, повертає 304 код.

Створення масштабованого API на спотових інстансах AWS

Register Targets — тут вибираються машини для групи, але в нашому випадку цим займатиметься ECS, тому просто пропускаємо цей крок.

Корисно знати: на рівні балансувальника можна включити логи, які зберігатимуться в S3 у певному форматі. Звідти їх можна експортувати в сторонні послуги для аналітики, а можна робити SQL-запити прямо за даними в S3 з допомогою Athena. Це зручно і працює без додаткового коду. Також рекомендую налаштувати видалення логів з бакета S3 після закінчення заданого періоду часу.

ECS Task Definition

На попередніх кроках ми створили все, що пов'язане з інфраструктурою сервісу, тепер переходимо до опису контейнерів, які ми будемо запускати. Це робиться в розділі ECS → Task Definitions.

Launch type compatibility - Вибираємо EC2.

Task execution IAM role - Вибираємо ecsTaskExecutionRole. За допомогою неї пишуться логи, дається доступ до секретних змінних та ін.

У розділі Container Definitions натискаємо Add Container.

зображення - Посилання на образ з кодом проекту, в рамках даного прикладу я використовуватиму публічний образ з Docker Hub bitnami/node-example:0.0.1.

Обмеження пам'яті - Ліміти по пам'яті для контейнера. Жорсткий ліміт - Жорсткий ліміт, якщо контейнер вийде за вказане значення, то виконається команда docker kill, контейнер відразу ж помре. М'який ліміт - м'який ліміт, контейнер може вийти за вказане значення, але при цьому при розміщенні тяган на машини враховуватиметься цей параметр. Наприклад, якщо на машині 4 GiB оперативної пам'яті, а soft limit контейнера - 2048 MiB, то на цій машині може бути максимум 2 запущені таски з цим контейнером. Насправді 4 GiB оперативної пам'яті - це трохи менше, ніж 4096 MiB, це можна подивитися на вкладці ECS Instances в кластері. Soft limit не може бути більше hard limit. Важливо розуміти, що якщо в одному тягу є кілька контейнерів, то їх ліміти підсумовуються.

Port mappings - У Порт хоста вказуємо 0, це означає, що порт призначатиметься динамічно, його відстежуватиме Target Group. Container Port - порт, на якому працює ваша програма, часто задається в команді для виконання, або призначається в коді вашого додатку, Dockerfile і т.д. Для нашого прикладу використовуємо 3000, тому що він вказаний у Докер-файл використовуваного образу.

Перевірка здоров'я — параметри перевірки працездатності контейнера, не плутати з тим, що налаштовано у Target Group.

Навколишнє середовище - Налаштування оточення. CPU units - Схоже на Memory limits, тільки про процесор. Кожне ядро ​​процесора — 1024 юнітів, так що якщо на сервері двоядерний процесор і контейнер має значення 512, то на одному сервері може бути запущено 4 тяга з цим контейнером. CPU units завжди відповідають кількості ядер, їх може бути трохи менше як у випадку з пам'яттю.

Command - команда для запуску сервісу всередині контейнера, всі параметри вказуються через кому. Це може бути gunicorn, npm тощо. Якщо не вказано, буде використано значення директиви CMD із Dockerfile. Вказуємо npm,start.

Змінні середовища - Змінні оточення контейнера. Це можуть бути як текстові дані, так і секретні змінні з Менеджер секретів або Зберігання параметрів.

Storage and Logging - тут налаштуємо логування в CloudWatch Logs (сервіс для логів від AWS). Для цього достатньо увімкнути галочку Auto-configure CloudWatch Logs. Після створення Task Definition автоматично створиться група логів у CloudWatch. За замовчуванням логи зберігаються в ній нескінченно, рекомендую змінити Retention period з Never Expire на необхідний термін. Це робиться в CloudWatch Log groups, треба натиснути на поточний період і вибрати новий.

Створення масштабованого API на спотових інстансах AWS

ECS Cluster та ECS Capacity Provider

Перейдіть до розділу ECS → Clusters, щоб створити кластер. Як шаблон вибираємо EC2 Linux + Networking.

Назва кластера дуже важливо, робимо тут таке ж ім'я, як зазначено в Launch Template в параметрі ECS_CLUSTER, у нашому випадку - DemoApiClusterProd. Відзначаємо галочку Create an empty cluster. Опціонально можна увімкнути Container Insights, щоб дивитися метрики по сервісах у CloudWatch. Якщо ви все зробили правильно, то в розділі ECS Instances ви побачите машини, створені в Auto Scaling group.

Створення масштабованого API на спотових інстансах AWS

Переходимо на вкладку Capacity Providers та створюємо новий. Нагадаю, що він потрібен для того, щоб керувати створенням та вимкненням машин залежно від кількості працюючих ECS тяг. Важливо, що провайдер може бути прив'язаний лише до однієї групи.

Група автоматичного масштабування - Вибираємо створену раніше групу.

Кероване масштабування - Включаємо, щоб провайдер міг масштабувати сервіс.

Target capacity % - Який відсоток завантаження машин тасками нам потрібен. Якщо вказати 100%, всі машини завжди буде зайняті працюючими тасками. Якщо вказати 50%, то половина машин завжди будуть вільними. У такому разі, якщо трапиться різкий стрибок у навантаженні, нові таксі відразу потраплять на вільні машини, без необхідності чекати на розгортання інстансів.

Managed termination protection - Включаємо, цей параметр дозволяє провайдеру прибирати захист інстансів від видалення. Це відбувається, коли на машині немає активних тяган і дозволяє Target capacity %.

ECS Service та налаштування масштабування

Останній крок:) Щоб створити сервіс, треба зайти у створений раніше кластер на вкладку Services.

Тип запуску — Натисніть на Switch to capacity provider strategy і вибрати створені раніше провайдер.

Створення масштабованого API на спотових інстансах AWS

Task Definition - Вибираємо створений ранній Task Definition та його ревізію.

Назва послуги - щоб не плутатися, ми завжди вказуємо такий самий, як Task Definition.

Тип послуги - Завжди Replica.

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

Minimum healthy percent и Maximum percent - Визначають поведінку тяган при депло. Значення за замовчуванням 100 і 200 говорять про те, що в момент деплою кількість тягів збільшиться в рази, а потім повернеться до бажаного. Якщо у вас працює 1 таск, min = 0, а max = 100, то тоді при депло він буде вбиватися, і після цього підніматися новий, тобто буде простий. Якщо працює 1 таск, min = 50, max = 150, то деплой взагалі не станеться, тому що він 1 таск не можна розділити навпіл або збільшити у півтора рази.

Тип розгортання - Залишаємо Rolling update.

Placement Templates - Правила розміщення тяган на машинах. За замовчуванням стоїть AZ Balanced Spread — це означає, хто кожен новий таск поміщатиметься на новий інстанс доти, доки не піднімуться машини у всіх зонах доступності. Ми зазвичай робимо BinPack - CPU і Spread - AZ, при такій політиці таски поміщаються максимально щільно на одну машину по CPU. При необхідності створення нової машини вона створюється в новій зоні доступності.

Створення масштабованого API на спотових інстансах AWS

Load balancer type - Вибираємо Application Load Balancer.

Service IAM role - Вибираємо ecsServiceRole.

Ім'я балансувальника навантаження - Вибираємо створений раніше балансувальник.

Health check grace period - Пауза перед виконанням перевірок працездатності після викочування нового тяга, ми зазвичай ставимо 60 секунд.

Container to load balance — у пункті Target group name вибираємо створену групу, і все автоматично заповниться.

Створення масштабованого API на спотових інстансах AWS

Автоматичне масштабування послуги - Параметри масштабування сервісу. Вибираємо Configure Service Auto Scaling для вибору вашого сервісу, що утримується count. Задаємо мінімальну та максимальну кількість тягів при масштабуванні.

IAM role for Service Auto Scaling - Вибираємо AWSServiceRoleForApplicationAutoScaling_ECSService.

Automatic task scaling policies - Правила для масштабування. Є 2 типи:

  1. Відстеження цілі - відстеження цільової метрики (використання CPU/RAM або кількість запитів на кожен таск). Наприклад, ми хочемо середнє завантаження процесора була 85%, коли вона стане вищою, то нові таски будуть додаватися до тих пір, поки вона не прийде до цільового значення. Якщо завантаження нижче, то таски навпаки будуть забиратися, якщо не включено захист від масштабування вниз (Disable scale-in).
  2. Крок масштабування - Реакція на довільну подію. Тут можна налаштувати реакцію на будь-яку подію (CloudWatch Alarm), коли вона відбуватиметься, можна додати або прибрати вказану кількість тяган, або вказати точну кількість тяг.

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

Висновок

Якщо ви дотримувалися інструкції та використовували той самий Docker образ, ваш сервіс повинен повертати таку сторінку.

Створення масштабованого API на спотових інстансах AWS

  1. Ми створили шаблон, яким запускаються всі машини у сервісі. Ми також навчилися оновлювати машини при зміні шаблону.
  2. Ми налаштували обробку сигналу зупинки спотового інстансу, тому протягом хвилини після його отримання всі працюючі таски забираються з машини, таким чином нічого не втрачається і не переривається.
  3. Ми підняли балансувальник, щоб рівномірно розподіляти навантаження машинами.
  4. Ми створили сервіс, який працює на спотових інстансах, рахунок цього скорочуються витрати на машини приблизно в 3 рази.
  5. Ми налаштували автомасштабування в обидві сторони, щоб обробляти збільшення навантажень, але в той же час не платити за простий.
  6. Ми використовуємо Capacity Provider, щоб програма керувала інфраструктурою (машинами), а не навпаки.
  7. Ви молодці.

Якщо у вас є передбачувані сплески навантаження, наприклад, ви рекламуєтеся у великій email-розсилці, ви можете налаштувати масштабування по розкладом.

Ще можна робити масштабування на основі даних із різних частин вашої системи. Наприклад, у нас є функціонал розсилки індивідуальних промо-пропозицій користувачам мобільного додатка. Іноді кампанія розсилається на 1М+ людей. Після такого розсилання завжди спостерігається велике зростання запитів до API, оскільки багато користувачів одночасно заходять у додаток. Так що якщо ми бачимо, що в черзі на відправку промо-пушкою їх стало значно більше за стандартні показники, ми відразу можемо запустити кілька додаткових машин і тяган, щоб бути готовим до навантаження.

Буду радий, якщо в коментарях розповісте цікаві кейси використання спотових інстансів та ECS або щось масштабування.

Незабаром будуть статті про те, як ми обробляємо тисячі аналітичних евентів на секунду на переважно serverless стеку (з грошима) і як влаштований деплой сервісів за допомогою GitLab CI та Terraform Cloud.

Підписуйтесь на нас, буде цікаво!

Тільки зареєстровані користувачі можуть брати участь в опитуванні. Увійдіть, будь ласка.

Ви використовуєте spot instances на проді?

  • 22,2%Так6

  • 66,7%Ні18

  • 11,1%Дізнався про них зі статті, планую использовать3

Проголосували 27 користувачів. Утрималися 5 користувачів.

Джерело: habr.com

Додати коментар або відгук