Будівельні блоки розподілених програм. Нульове наближення

Будівельні блоки розподілених програм. Нульове наближення

Світ не стоїть на місці. Прогрес створює нові технологічні дзвінки. Відповідно до вимог, що змінилися, повинна еволюціонувати і архітектура інформаційних систем. Сьогодні ми говоритимемо про подієво-орієнтовану архітектуру, конкурентність, паралельність, асинхронність і про те, як в Erlang можна з усім цим жити мирно.

Запровадження

Залежно від розмірів проектованої системи та вимог до неї ми, розробники, вибираємо спосіб обміну інформацією в системі. У більшості випадків для організації взаємодії сервісів робочим варіантом може бути схема з брокером, наприклад на основі RabbitMQ або kafka. Але іноді потік подій, SLA та рівень контролю над системою такі, що готовий messaging нам не підходить. Звичайно, можна трохи ускладнити систему, взявши відповідальність за транспортний рівень та формування кластера, наприклад, використовуючи ZeroMQ або nanomsg. Але якщо системі вистачає пропускної спроможності та можливостей стандартного Erlang кластера, то питання внесення додаткової сутності потребує докладного вивчення та економічного обґрунтування.

Тема реактивних розподілених додатків досить велика. Щоб укластися у формат статті, предметом сьогоднішнього обговорення будуть лише гомогенні середовища, побудовані на основі Erlang/Elixir. Екосистема Erlang/OTP дозволяє реалізувати реактивну архітектуру з найменшими витратами праці. Але в будь-якому випадку нам знадобиться шар обміну повідомленнями.

Теоретичний базис

Проектування починається з визначення цілей та обмежень. Основна мета не знаходиться в галузі розробки для розробки. Нам необхідно отримати безпечний та масштабований інструмент, на основі якого можна створювати, а найголовніше – розвивати сучасні програми різного рівня: починаючи від односерверних, які обслуговують невелику аудиторію, які надалі можуть розвинутися в кластери до 50-60 вузлів, закінчуючи федераціями кластерів. Таким чином, основна мета – максимізація прибутку шляхом скорочення вартості розробки та володіння підсумковою системою.

Виділимо 4 основні вимоги до підсумкової системи:

  • Собуткова орієнтованість.
    Система завжди готова пропускати через себе потік подій та робити необхідні дії;
  • Масштабованість.
    Окремі блоки можуть масштабуватись як вертикально, так і горизонтально. Вся система повинна мати можливість нескінченного горизонтального зростання;
  • Отказостійкість.
    Всі рівні та всі сервіси повинні мати можливість автоматичного відновлення при збоях;
  • Гарантований час відгуку.
    Час цінний і користувачі не повинні чекати занадто довго.

Пам'ятаєте стару казку про “The little engine that could”, він же – “Паровозик, який зміг”? Щоб проектована система успішно вийшла зі стадії прототипу і була прогресивною, її фундамент має відповідати мінімальним вимогам ЗМІГ.

До messaging як до інфраструктурного інструменту та базису для всіх сервісів додається ще один пункт: зручність використання для програмістів.

Орієнтованість на події

Щоб програма могла вирости з одного сервера до кластера, його архітектура повинна забезпечувати слабку пов'язаність. Цій вимогі відповідає асинхронна модель. У ній відправник та одержувач піклуються про інформаційне навантаження повідомлення та не турбуються за передачу та маршрутизацію всередині системи.

масштабованість

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

В рамках однієї машини Erlang створює висококонкурентне середовище. Баланс між конкурентністю і паралельністю можна задати вибором кількості потоків операційної системи доступних Erlang VM і числом планувальників утилізують ці потоки.
Erlang процеси не мають загального стану та працюють у неблокуючому режимі. Це забезпечує порівняно низьку латентність і більш високу пропускну здатність, ніж у традиційних додатків, побудованих на блокуючій синхронізації. Планувальник Erlang піклується про справедливий розподіл CPU та IO, а відсутність блокувань дозволяє додатку відповідати навіть у режимі пікових навантажень чи збоїв.

На рівні кластера проблема з утилізацією також існує. Важливо, щоб усі машини в кластері були рівномірно навантажені, а мережа не перевантажена. Уявімо ситуацію: користувальницький трафік приземляється на вхідні балансувальники (haproxy, nginx, etc), вони максимально рівномірно розподіляють запити на обробку між набором доступних бекендів. В рамках інфраструктури програми сервіс, що реалізує необхідний інтерфейс, – це лише остання миля, і йому потрібно буде запросити низку інших сервісів, щоб відповісти на початковий запит. Внутрішні запити також вимагають маршрутизації та балансування.
Щоб ефективно управляти потоками даних, messaging повинен надавати розробникам інтерфейс управління маршрутизацією і розподілом навантаження. Завдяки цьому, розробники зможуть, використовуючи мікросервісні патерни (aggregator, proxy, chain, branch, etc), вирішувати як стандартні завдання, так і ті, що рідко виникають.

З погляду бізнесу, масштабованість – один із інструментів управління ризиками. Головне задовольнити запити клієнтів, оптимально використовуючи обладнання:

  • При збільшенні потужності устаткування внаслідок прогресу. Воно не простоюватиме через недосконалість ПЗ. Erlang чудово масштабується вертикально і завжди зможе утилізувати всі ядра CPU та доступну пам'ять;
  • В умовах хмарних середовищ ми можемо керувати кількістю обладнання в залежності від поточного або прогнозованого навантаження та гарантувати SLA.

Відмовостійкість

Розглянемо дві аксіоми: "Відмови неприпустимі" і "Відмови будуть завжди". Для бізнесу відмова ПЗ – втрата грошей, а що гірше – репутації. Балансуючи між можливими втратами та вартістю розробки відмовостійкого ПЗ, часто можна знайти компроміс.

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

чуйність

Незалежно від збоїв, програма повинна відповідати на запити та задовольняти SLA. Реальність така, що люди не хочуть чекати, відповідно бізнес має підлаштуватися. Від дедалі більшої кількості програм чекають високої чуйності.
Чуйні програми працюють у режимі, наближеному до реального часу. Erlang VM функціонує як м'якого реального часу. Для деяких областей, таких як біржова торгівля, медицина, управління промисловим обладнанням, важливим є режим жорсткого реального часу.
Чуйні системи покращують UX та корисні бізнесу.

Попередній підсумок

Плануючи цю статтю, я хотів поділитися досвідом створення брокера обміну повідомленнями та побудовою на його основі складних систем. Але теоретична та мотиваційна частина вийшла досить великою.
У другій частині статті я розповім про нюанси реалізації точок обміну, шаблони обміну повідомленнями та їх застосування.
У третій частині розглянемо загальні питання організації сервісів, маршрутизації та балансування. Поговоримо про практичну сторону масштабованості та відмовостійкості систем.

Кінець першої частини.

Фото @lucabravo.

Джерело: habr.com

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