На шляху до безсерверних баз даних – як і навіщо

Всім привіт! Мене звуть Голов Микола. Раніше я працював в Авіто і шість років керував Data Platform, тобто займався всіма базами: аналітичними (Vertica, ClickHouse), потоковими та OLTP (Redis, Tarantool, VoltDB, MongoDB, PostgreSQL). За цей час я розібрався з великою кількістю баз даних — найрізноманітніших і найнезвичайніших, і з нестандартними кейсами їхнього використання.

Зараз я працюю в ManyChat. По суті, це стартап — новий, амбітний і швидко зростаючий. І коли я тільки вийшов у компанію, виникло класичне питання: «А що зараз варто брати молодому стартапу з ринку СУБД та баз даних?».

У цій статті, заснованій на моїй доповіді на онлайн-фестивалі РІТ++2020, відповім це питання. Відеоверсія доповіді доступна на YouTube.

На шляху до безсерверних баз даних – як і навіщо

Загальновідомі бази даних 2020 року

На дворі 2020, я озирнувся і побачив три типи БД.

Перший тип - класичні OLTP бази: PostgreSQL, SQL Server, Oracle, MySQL. Вони написані давним-давно, але, як і раніше, актуальні, тому що добре знайомі спільноті розробників.

Другий тип - бази з «нульових». Вони намагалися уникнути класичних шаблонів шляхом відмови від SQL, традиційних структур і ACID, за рахунок додавання вбудованого шардування та інших привабливих фіч. Наприклад, це Cassandra, MongoDB, Redis чи Tarantool. Всі ці рішення хотіли запропонувати ринку щось принципово нове і зайняли свою нішу, тому що у певних завданнях виявилися вкрай зручними. Ці бази позначу парасольковим терміном NOSQL.

«Нульові» закінчилися, до NOSQL баз звикли, і світ, на мій погляд, зробив наступний крок — до managed баз. У цих баз ядро ​​те саме, що й у класичних баз OLTP або нових NoSQL. Але вони не потребують DBA і DevOps і вони крутяться на керованому залозі в хмарах. Для розробника це просто база, яка десь працює, а як вона встановлена ​​на сервері, хто налаштував сервер і хто його оновлює, нікого не хвилює.

Приклади таких баз:

  • AWS RDS - managed обгортка над PostgreSQL/MySQL.
  • DynamoDB - AWS аналог document based бази, схоже на Redis і MongoDB.
  • Amazon Redshift - managed аналітична база.

В основі це старі бази, але підняті в середовищі, без необхідності роботи з залізом.

Примітка. Приклади взяті для середовища AWS, але їх аналоги існують також у Microsoft Azure, Google Cloud або Яндекс.Хмарі.

На шляху до безсерверних баз даних – як і навіщо

Що ж із цього нового? 2020 року нічого з цього.

Serverless концепції

Справді, нове на ринку в 2020 році — це serverless або безсерверні рішення.

Спробую пояснити, що це означає на прикладі звичайного сервісу або бекенд-додатку.
Щоб розгорнути звичайний бекенд-додаток, купуємо або орендуємо сервер, копіюємо на нього код, опубліковуємо назовні endpoint і регулярно сплачуємо за оренду, електрику та послуги дата-центру. Це стандартна схема.

Чи можна якось інакше? З безсерверними сервісами можна.

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

Спробую проілюструвати цей підхід на картинках.
На шляху до безсерверних баз даних – як і навіщо

Класичний деплой. У нас є сервіс із певним навантаженням. Піднімаємо два інстанси: фізичні сервери або інстанси в AWS. На ці інстанси надсилаються зовнішні запити, які там обробляються.

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

На шляху до безсерверних баз даних – як і навіщо

Безсерверний деплой. У безсерверному оточенні подібний сервіс не має інстансів і серверів. Є певний пул розігрітих ресурсів - невеликих підготовлених Docker-контейнерів з розгорнутим кодом функції. Система отримує зовнішні запити і на кожен із них безсерверний фреймворк піднімає маленький контейнер із кодом: обробляє саме цей запит та вбиває контейнер.

Один запит – один піднятий контейнер, 1000 запитів – 1000 контейнерів. А розгортання на залізних серверах це вже робота хмарного провайдера. Вона повністю прихована безсерверним фреймворком. У цій концепції ми платимо за кожний виклик. Наприклад, прийшов один виклик за день — ми заплатили за один виклик, прийшов мільйон за хвилину — заплатили за мільйон. Або за секунду, таке теж буває.

Концепція публікації безсерверної функції підходить для stateless сервісу. А якщо вам потрібен (state) statefull сервіс, то до сервісу додаємо базу даних. У цьому випадку, коли доходить до роботи зі станом, зі станом, кожна статевеповна функція просто пише і читає з бази даних. Причому бази даних будь-якого з трьох типів, описаних на початку статті.

Яке загальне обмеження у всіх цих баз? Це витрати на постійно використовується хмарний або залізний сервер (або кілька серверів). Неважливо, використовуємо класичну базу чи managed, є Devops і адмін чи ні, все одно 24 на 7 платимо за залізо, електрику та оренду дата-центру. Якщо у нас класична база, ми платимо за master та slave. Якщо високонавантажена шардована база - платимо за 10, 20 або 30 серверів і платимо постійно.

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

Serverless база даних - теорія

Питання 2020 року: чи можна базу даних також зробити serverless? Усі чули про serverless бекенд… а давайте й базу даних спробуємо зробити serverless?

Це звучить дивно, тому що база даних - це ж statefull сервіс, не дуже підходящий для serverless інфраструктури. При цьому і state у бази даних дуже великий: гігабайти, терабайти, а в аналітичних базах навіть петабайти. Його так просто у легковажних Docker-контейнерах не підняти.

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

Відповідно, ідея: якщо частина логіки допускає Stateless виконання, чому б не розпиляти базу на Stateful і Stateless частини.

Serverless для OLAP рішень

Давайте подивимося, як може виглядати розпилювання бази даних на Stateful і Stateless частини на практичних прикладах.

На шляху до безсерверних баз даних – як і навіщо

Наприклад, у нас є аналітична база даних: зовнішні дані (червоний циліндр зліва), ETL-процес, який завантажує дані до бази, та аналітик, який відправляє до бази SQL-запити. Це класична схема роботи сховища даних.

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

Розглянемо альтернативний підхід, реалізований на базі AWS Athena Serverless. Тут немає постійно виділеного заліза, у якому зберігаються завантажені дані. Замість цього:

  • Користувач надсилає SQL-запит до Athena. Оптимізатор Athena аналізує SQL-запит і шукає у сховищі метаданих (Metadata) конкретні дані, необхідних виконання запиту.
  • Оптимізатор, на основі зібраних даних, вивантажує потрібні дані із зовнішніх джерел у тимчасове сховище (тимчасову базу даних).
  • У тимчасовому сховищі виконується SQL-запит від користувача, результат повертається користувачеві.
  • Тимчасове сховище очищується, ресурси вивільняються.

У цій архітектурі ми платимо тільки за виконання запиту. Немає запитів – немає витрат.

На шляху до безсерверних баз даних – як і навіщо

Це робочий підхід і він реалізується не тільки в Athena Serverless, але і в Redshift Spectrum (AWS).

На прикладі Athena видно, що Serverless база даних працює на реальних запитах з десятками та сотнями Терабайт даних. Для сотень Терабайт знадобляться сотні серверів, але нам не потрібно платити за них — ми платимо за запити. Швидкість кожного запиту (дуже) низька порівняно зі спеціалізованими аналітичними базами типу Vertica, але ми не оплачуємо періоди простою.

Така база даних застосовується для поодиноких аналітичних ad-hoc запитів. Наприклад, коли ми спонтанно вирішимо перевірити гіпотезу на якомусь величезному обсязі даних. Для цих кейсів Athena підходить ідеально. Для регулярних запитів така система виходить дорого. У цьому випадку кешуйте дані у якомусь спеціалізованому рішенні.

Serverless для OLTP рішень

У попередньому прикладі розглядалися OLAP-завдання (аналітичні). Тепер розглянемо OLTP-завдання.

Представимо масштабований PostgreSQL або MySQL. Давайте піднімемо звичайний managed instance PostgreSQL або MySQL на мінімальних ресурсах. Коли на інстанс буде приходити більше навантаження, ми будемо підключати додаткові репліки, на які розподілимо частину навантаження, що читає. Якщо запитів та навантаження немає – відключаємо репліки. Перший інстанс – це майстер, а решта – репліки.

Ця ідея реалізована у базі під назвою Aurora Serverless AWS. Принцип простий: запити від зовнішніх програм приймає proxy fleet. Бачачи зростання навантаження, він виділяє обчислювальні ресурси із попередньо прогрітих мінімальних інстансів – підключення виконується максимально швидко. Відключення інстансів відбувається так само.

У рамках Aurora є поняття Aurora Capacity Unit, ACU. Це (умовно) – інстанс (сервер). Кожен конкретний ACU може бути master або slave. Кожен Capacity Unit має свою оперативну пам'ять, процесор і мінімальний диск. Відповідно, один master, решта read only репліки.

Кількість цих працюючих Aurora Capacity Units — це параметр, що настроюється. Мінімальна кількість може бути один або нуль (у такому разі база не працює, якщо немає запитів).

На шляху до безсерверних баз даних – як і навіщо

Коли база отримує запити, proxy fleet піднімає Aurora CapacityUnits, збільшуючи продуктивні ресурси системи. Можливість збільшувати та зменшувати ресурси дозволяє системі «жонглювати» ресурсами: автоматично виводити окремі ACU (підмінюючи їх новими) та накочувати на виведені ресурси всі актуальні оновлення.

База Aurora Serverless може масштабувати навантаження, що читає. Але у документації про це не сказано прямо. Може виникнути відчуття, що можуть піднімати multi-master. Чари ж ніякого немає.

Ця база добре підходить, щоб не витрачати величезних грошей на системи з непередбачуваним доступом. Наприклад, при створенні MVP або маркетингових сайтів-візиток, ми зазвичай не очікуємо на стабільне навантаження. Відповідно, за відсутності доступу ми не платимо за інстанси. Коли несподівано виникає навантаження, наприклад, після конференції або рекламної кампанії, натовпи людей заходять на сайт і навантаження різко зростає, Aurora Serverless автоматично приймає це навантаження і швидко підключає ресурси, що бракують (ACU). Далі конференція проходить, всі забувають про прототип, сервери (ACU) гаснуть, і витрати падають до нуля – зручно.

Це рішення не підходить для стабільного високого highload, тому що воно не вміє масштабувати навантаження, що пише. Всі ці підключення та відключення ресурсів відбуваються в момент так званого scale point - моменту часу, коли базу не тримає транзакція, не тримають тимчасові таблиці. Наприклад, протягом тижня scale point може і не статися, і база працює на одних ресурсах і просто не може розширитися, ні стиснутися.

Чарів немає - це звичайний PostgreSQL. Але процес додавання машин та відключення частково автоматизований.

Serverless by design

Aurora Serverless це стара база, переписана під хмари, щоб використовувати окремі переваги Serverless. А тепер розповім про базу, яка спочатку написана під хмари, під підхід serverless — Serverless-by-design. Її відразу розробляли без припущення, що вона працює на фізичних серверах.

Ця база називається Snowflake. У ній три ключові блоки.

На шляху до безсерверних баз даних – як і навіщо

Перший – це блок метаданих. Це швидкий in-memory сервіс, який вирішує питання з безпекою, метаданими, транзакціями, оптимізацією запиту (на ілюстрації зліва).

Другий блок – це безліч віртуальних обчислювальних кластерів для розрахунків (на ілюстрації – набір синіх гуртків).

Третій блок – система зберігання даних на базі S3. S3 - це безрозмірне об'єктне сховище в AWS, щось на зразок безрозмірного Dropbox для бізнесу.

Давайте подивимося, як Snowflake працює, припущення про холодний старт. Тобто база є, дані до неї завантажені, працюючих запитів немає. Відповідно, якщо до бази немає запитів, то ми маємо швидкий in-memory Metadata сервіс (перший блок). І ми маємо сховище S3, де лежать дані таблиць, розбиті на так звані мікропартиції. Для простоти: якщо таблиці лежать угоди, то микропартиции — дні угод. Щодня – це окрема мікропартиція, окремий файлик. І коли база працює в такому режимі, ви платите лише за місце, яке займає дані. Причому тариф за місце є дуже низьким (особливо з урахуванням значного стиснення). Сервіс метаданих теж працює постійно, але для оптимізації запитів багато ресурсів не потрібне, і сервіс можна вважати умовно-безкоштовним.

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

Далі сервіс ініціює запуск обчислювального кластера. Обчислювальний кластер — це кластер із серверів, які виконують обчислення. Тобто це кластер, який може містити 1 сервер, 2 півночі, 4, 8, 16, 32 – скільки захочете. Ви кидаєте запит і під нього миттєво починається запуск кластера. Це реально займає секунди.

На шляху до безсерверних баз даних – як і навіщо

Далі, після того, як кластер стартував, у кластер з S3 починають копіюватися мікропартиції, потрібні для обробки саме вашого запиту. Тобто, уявімо, що для виконання SQL-запиту потрібно дві партиції з однієї таблиці та одна з другої. У такому разі в кластер буде скопійовано лише три потрібні партиції, а не всі таблиці повністю. Саме тому і саме через те, що все знаходиться в рамках одного дата-центру та з'єднане дуже швидкими каналами, весь процес перекачування відбувається дуже швидко: за секунди, дуже рідко — за хвилини, якщо не йдеться про якісь жахливі запити . Відповідно мікропартиції копіюються на обчислювальний кластер, і, по завершенні, на цьому обчислювальному кластері виконується SQL запит. Результатом цього запиту може бути один рядок, кілька рядків або таблиця - вони відправляються назовні користувачеві, щоб він вивантажив, відобразив у себе в BI інструменті, або ще якось використав.

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

Описаний вище сценарій, від приходу користувача до підняття кластера, завантаження даних, виконання запитів, отримання результатів оплачується за тарифом за хвилини використання піднятого віртуального обчислювального кластера, віртуального warehouse. Тариф варіюється в залежності від зони AWS та розміру кластера, але в середньому це кілька доларів на годину. Кластер із чотирьох машин у два рази дорожчий, ніж із двох машин, із восьми машин ще вдвічі дорожчий. Доступні варіанти із 16, 32 машин, залежно від складності запитів. Але ви платите тільки за ті хвилини, коли кластер реально працює, тому що, коли запитів немає, ви як би прибираєте руки, і після 5-10 хвилин очікування (параметр, що настроюється) він сам погасне, звільнить ресурси і стане безкоштовним.

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

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

Припустимо, ми маємо багато аналітиків і Tableau звітів, які постійно бомбардують нашу базу великою кількістю нескладних аналітичних SQL-запитів.

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

Для описаних вище двох типів навантаження Snowflake дозволяє піднімати кілька незалежних кластерів різної потужності. Причому ці обчислювальні кластери працюють незалежно, але із загальними узгодженими даними.

Для великої кількості легких запитів можна підняти 2-3 невеликі кластери, розміром, умовно, 2 машини кожен. Ця поведінка реалізована, у тому числі, за допомогою автоматичних налаштувань. Тобто ви кажете: «Snowflake, підніми маленький кластер. Якщо навантаження на нього виросте більше за певний параметр, підніми аналогічний другий, третій. Коли навантаження почне спадати, гаси зайві». Щоб незалежно від того, скільки аналітиків надходить і починає дивитися звіти, всім вистачало ресурсів.

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

Для важких запитів (від Data Scientists), ви можете підняти один дуже великий кластер на умовні 32 машини. Цей кластер теж буде оплачуватись лише за ті хвилини та години, коли там працює ваш гігантський запит.

Описана вище можливість дозволяє розділяти за кластерами не тільки 2, а й більше видів навантаження (ETL, моніторинг, матеріалізація звітів, ...).

Підіб'ємо підсумок по Snowflake. База поєднує гарну ідею та працездатну реалізацію. У ManyChat ми використовуємо Snowflake для аналітики всіх наявних даних. Кластерів у нас не три, як у прикладі, а від 5 до 9 різних розмірів. У нас є умовні 16-машинні, 2-машинні, є і супер-маленькі 1-машинні для деяких завдань. Вони успішно розподіляють навантаження та дозволяють нам здорово економити.

База успішно масштабує навантаження, що читає і пише. Це величезна відмінність і величезний прорив у порівнянні з тією ж «Авророю», яка тягла тільки навантаження, що читає. Snowflake дозволяє масштабувати цими обчислювальними кластерами і навантаження. Тобто, як я згадав, у нас у ManyChat використовується кілька кластерів, маленькі та супермаленькі кластери в основному використовуються для ETL, для завантаження даних. А аналітики живуть вже на середніх кластерах, які абсолютно не торкнулися ETL-навантаження, тому працюють дуже швидко.

Відповідно база добре підходить для OLAP-задач. При цьому, на жаль, для OLTP-навантажень вона ще не застосовується. По-перше, ця база колонкова, з усіма наслідками. По-друге, сам підхід, коли на кожен запит за потребою ви піднімаєте обчислювальний кластер та проливаєте його даними, на жаль, для OLTP-навантажень ще недостатньо швидкий. Секунди очікування для OLAP-завдань - це нормально, а для OLTP-завдань - неприйнятно, краще б 100 мс, а ще краще - 10 мс.

Підсумок

Serverless база даних можлива за рахунок поділу бази даних на Stateless і Stateful частини. Ви, мабуть, звернули увагу, що у всіх наведених прикладах, Stateful частина - це, умовно кажучи, зберігання мікропартицій в S3, а Stateless - це оптимізатор, робота з мета-даними, обробка питань безпеки, які можуть бути порушені як незалежні легковажні Stateless послуги.

Виконання SQL-запитів теж можна сприйняти як послуги з легким state, які можуть спливти в безсерверному режимі, як обчислювальні кластери Snowflake, завантажити лише необхідні дані, виконати запит і «згаснути».

Serverless бази продакшен рівня вже доступні для використання, вони працюють. Ці serverless бази вже готові долати OLAP-завдання. На жаль, для OLTP-задач вони застосовуються з нюансами, так як є обмеження. З одного боку це мінус. Але з іншого боку, це можливість. Можливо, хтось із читачів знайде спосіб, як OLTP-базу зробити повністю serverless, без обмежень Aurora.

Сподіваюся, що вам було цікаво. За Serverless майбутнє 🙂

Джерело: habr.com

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