Методи масштабування реляційних баз даних: переваги, недоліки та кейси використання

Привіт! Мене звати Максим, я Lead Back-end Engineer у продуктовій ІТ-компанії OBRIO з екосистеми Genesis, беру участь у розвитку застосунку Nebula. У бекенд-розробці працюю понад пʼять років, мій основний стек — NodeJS і PHP.

Масштабування реляційних баз даних відіграє ключову роль у підтримці високої продуктивності та доступності високонавантажених систем. Є чимало підходів: реплікація Master/Slave та Master/Master, функціональне та горизонтальне партиціювання, шардинг, денормалізація. У цій статті розповім про переваги та недоліки кожного з них, нюанси використання та навести кейси, коли ці методи працюють найкраще.

Реплікація

Реплікація — це процес створення та підтримки копій баз даних на різних вузлах з метою забезпечення високої доступності, збереження даних та розподілу навантаження. Це базовий підхід до масштабування реляційних БД, сама реплікація має дві схеми роботи: Master/Slave і Master/Master.

Master/Slave

Найпоширеніший та один з найефективніших підходів до масштабування. У ньому є головний (Master) вузол, який копіює дані на одну або декілька реплік (Slave). Це також може відбуватися у вигляді дерева, де Slave копіює дані в інші репліки.

Зазвичай у підході Master/Slave всі зміни (такі як insert/update/delete тощо) відбуваються на головному вузлі. Звідти їх отримують та зберігають репліки. Виходить, що Master відповідає за запис та читання, а Slave — тільки за читання.

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

Наприклад, у вас є мобільний застосунок, яким щодня користуються мільйони людей. Через велику кількість запитів основна база даних матиме велике навантаження, що призведе до уповільнення часу відгуку сервера. У той час, коли більшість користувачів лише читають контент (наприклад, переглядають пости та коментарі), база даних опрацьовує як запити на читання, так і на запис. Використовуючи підхід Master/Slave, ви можете розділити операції читання на декілька серверів, що зменшить час завантаження контенту і покращить користувацький досвід.

Переваги:

  • чітке розділення ролей: один сервер БД виконує тільки функцію запису, а інші — тільки читання;
  • простота налаштування: порівняно з Master/Master реплікацією, Master/Slave є простішою в налаштуванні та управлінні;
  • відсутність конфліктів, оскільки лише один сервер БД (Master) опрацьовує записи;
  • оптимізація ресурсів: завдяки розподілу ролей, можна налаштувати сервер під конкретну задачу. Наприклад, для ролі Slave можна виділити більше RAM для кешування;
  • вузол Slave може служити для резервного копіювання і не впливатиме на інші сервери.

Недоліки:

  • ризик втрати даних, якщо Master вийде з ладу до того, як всі дані реплікуються на Slave;
  • додаткова складна логіка, щоби Slave зробити головним вузлом, якщо той вийде з ладу.

Master/Master

Підхід реплікації Master/Master корисний, коли вашій системі потрібно виконувати операції запису у великій кількості.

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

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

Переваги:

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

Недоліки:

  • конфлікти записів: якщо два сервери одночасно вносять зміни в один рядок, виникає конфлікт, який потребує ручного втручання або специфічних стратегій вирішення;
  • Master/Master конфігурація може бути складнішою для налаштування та обслуговування порівняно з Master/Slave;
  • якщо використовується автоінкрементація для створення унікальних ID, потрібно налаштовувати репліки, щоби вони не генерували однакові ідентифікатори;
  • безпека — оскільки декілька серверів БД можуть писати дані, можливі додаткові напрямки атак;
  • збільшений ризик втрати даних: проблема, що виникла на одному сервері, може швидко поширитися на інші через реплікацію.

Спільні недоліки реплікації для Master/Slave і Master/Master:

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

Функціональне партиціювання

Функціональне партиціювання (Functional Partitioning/Database Federation) — це стратегія розділення бази даних на менші, спираючись на їхні функції.

Наприклад, у вас є застосунок, у якому користувачі можуть спілкуватися у чатах та здійснювати покупки. Якщо все розмістити на одному сервері БД, будь-яке збільшення навантаження на один компонент може вплинути на продуктивність всієї системи. Цю монолітну базу даних можна розділити на три маленьких: Chat, User, Purchase, — тоді кожна частина системи зможе масштабуватися незалежно від інших, враховуючи індивідуальні потреби та навантаження. Це покращить загальну продуктивність системи та забезпечить більшу стабільність: проблеми в одному компоненті не будуть безпосередньо впливати на інші.

Переваги:

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

Недоліки:

  • ускладнення логіки на рівні коду: потрібно правильно визначити, до якої бази робити запит;
  • складність інфраструктури;
  • об’єднання даних із різних БД стає непростим завданням;
  • труднощі роботи з транзакціями.

Шардинг

Суть цього методу — розділення однієї таблиці на декілька частин (шардів), кожна з яких зберігається на різних серверах.

Наприклад, у вас є популярна соціальна мережа з мільйонами користувачів. Щодня вони генерують великі об’єми даних: публікації, коментарі, лайки тощо. Одна база даних не зможе ефективно обробляти цей обсяг інформації, що призведе до уповільнення та можливих відмов. Використовуючи шардинг, ви зменшуєте навантаження на окремий сервер, розподіляючи дані та обробку запитів між декількома сегментами. Кожен із них має менший об’єм даних для обробки, завдяки чому зменшується час відгуку. Коли зʼявляється необхідність, ми можете додавати нові шарди, у такий спосіб масштабуючи систему.

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

Переваги:

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

Недоліки:

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

Денормалізація

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

Уявимо, що у вас є застосунок, у якому користувачі можуть спілкуватися в чатах з експертами. Вам потрібно віддавати клієнту список чатів разом з іменами співбесідників. Операція Join між двома дуже великими таблицями буде займати чимало часу. Ситуація погіршиться, якщо таких запитів буде багато. Щоби прискорити вибірку, можна перенести імена співбесідників до таблиці Chats, — тоді нам не потрібно робити Join.

Цей метод — досить ефективний, але потрібно відчувати межу, щоби дублі не повторювалися занадто часто. Інакше це призведе до неконсистентності даних.

Переваги:

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

Недоліки:

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

Горизонтальне партиціювання

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

Наприклад, у вас є велика база даних для вебмагазину, яка зберігає історію покупок користувачів. Таблиця Замовлення містить мільйони рядків, її обробка та аналіз із часом сповільнюються та стають неефективними. Крім того, резервне копіювання та відновлення такої великої таблиці може бути часозатратним. Можна розділити її на партиції за місяцями або роками. Наприклад, одна частина буде містити всі замовлення за січень 2023 року, інша — за лютий 2023 року тощо. Запити до БД, які обробляють лише певний діапазон даних (наприклад, замовлення за певний місяць), будуть швидше виконуватися, оскільки вони звертатимуться лише до однієї партиції, а не до усієї великої таблиці. Операції з управління даними (наприклад, видалення старих замовлень) можуть бути спрощені, оскільки можна просто видалити цілу частину.

Переваги:

  • зменшення розміру індексів, що суттєво прискорює операцію запису;
  • швидке видалення даних за певною ознакою, що не блокує інші частини таблиці;
  • простота налаштування та використання, адже зазвичай СУБД дає це «з коробки».

Недоліки:

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

Висновки

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

Тим, кому цікава тема масштабування баз даних, можу порекомендувати книгу «High Performance MySQL: Optimization, Backups, Replication, and More», а також цю статтю.

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось22
До обраногоВ обраному13
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Питання «самим вумним» — як може так статися, що вульгарна mysql master-slave row-based реплікація час від часу розвалюється через порушення foreign key цілісності? деталей не буде, бо не пам’ятаю вже їх, але факт той, що на slave додавався запис, fk для якого не існував. Яким чином щось могло вивалитися за транзакцію чи що могло трапитися ващє? Питаю чисто для може у кого є які життєві історії чи цікаві факти чи роздуми.

например в результате бага.
У того же SQL Server в своем (не такое и далёкое) прошлом был кейс, когда после набора хитроумных, но законных манипуляций можно было по выходу из транзакции иметь нарушение ФК

Зазвичай слейв не перевіряє референшиал констрейнтс. Відповідна зміна могла не доїхати з мастера ще.

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

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

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

row-based

Там навіть не вся таблиця лочиться. Що вже казати про іншу таблицю.
Хочеш стронг консістенсі — лоч всю базу. Тоді у тебе гарантований порядок, але останні дані не завжди останні. КАП теорему ще ніхто не обдурив)

Виглядає як на перформенс ревю для підвищеня рівня змусили написати реферат на давно розжовану тему🤷‍♂️

Виглядає як на перформенс ревю для підвищеня рівня змусили написати реферат на давно розжовану тему🤷‍♂️

Стаття дійстно скоріше «інтродактарі» (може й справді для рев’ю).
Але спочатку доіпались до мастер-слейв, а не до технічних детеалей, що власне показує рівень, який потребує аудиторія доу.
Статті вступного рівня теж потрібні.
А чи потрібен доу людям, які пишуть просунутіші статті — це відкрите питання.

Статті вступного рівня теж потрібні.

Я думав такі банальні речі навчають в університетах.

Я думав такі банальні речі навчають в університетах.

Ну я такі речі розповідаю студням :)
Але на жаль, це скоріше виключення ніж правило. Є купа курсів (при тому в універах, які на слуху) де обмежуються СКЛ. А розподілені БД взагалі не згадують, і це на ІПЗ.
Гірше від україномовної вступної статті точно не буде

Ви можете розповісти про свій досвід master slave.

Для чого? В інтернеті купа статтей на цю тему.

адже цю функцію мають усі сервери бази даних.

Здається тут пропущена частка «не». Цю функцію мають НЕ усі сервери баз даних.

Підхід реплікації Master/Master корисний, коли вашій системі потрібно виконувати операції запису у великій кількості, адже цю функцію мають усі сервери бази даних.

маю сумнів що всі сервери баз даних мають цю функцію, так щоб просто і «from scratch». Можливо SQL Server має в Azure, ще AWS Aurora нібито має (заявлено так). Навіть у великих клауд провайдерів не у кожного є підтримка multi-leader, оскільки це передбачає значно більше ніж просто «розбив дані, оновив конфіг і все». Це ще передбачає надійний вибір лідера, фейловер, реплікацію з strong consistency, і резолюшн конфліктів. По-моєму, якщо б все було так просто, то навіщо Meta прикручувала до MySql мультилідер реплікацію роками.

дякую за зауваження
прибрав це

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

гадаю тут диявол в деталях, що саме вони «вміли». Що на рахунок алгоритму консенсусу, фейловера (ручний, автоматичний?), типу реплікації, конфліктів. Я щось сумніваюсь що Твіттер, Мета вибирали 3rd party рішення типу Vitness чи розробляли власні просто від скуки. Що саме забезпечує цей конфіг?

Це вже зовсім інші питання. Я лиш відповів, що «сервери баз даних мають цю функцію, так щоб просто і „from scratch“».

ну для мене якщо говорять що мають — це готово до використання в продакшн без надбудови власних або 3rd party рішень. Ви мабуть маєте на увазі що мускул має передомови для розбивки по різним нодам. Просто ота вся інша частина, щоб довести це до робочого стану — досить значна

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

може й так
якщо не лінь, можна коротко: що надають штатні засоби? В контексті тих питань що я вище описував. Ну там ... фейловер мабуть ручний, так? Що відбувається коли один з лідерів падає? Реплікація синхронна чи ні? Якщо лідер підняли, як резолвати діф і можливі конфлікти (якщо вони можуть бути, бо може якщо 1 лідер падає то весь запис припиняється)
цікаво просто, з якими проблемами стикаються і як вирішують їх в не-фейсбук масштабах, звичайних

У варіанті mariadb-galera-maxscale:
1. реплікація синхронна
2. якщо нова нода має діф (піднята з могили чи з свіжого консістенсі-снапшота) то вона спочатку підтягується до рівня інших, перш, ніж почне брати участь в двофазному комміті.
3. фейловер в базі ручний, але тривіально автоматизується
4. галєра не виключає класичної реплікації. Кожна нода кластеру може бути мастером для рідонлі слейва, який, в свою чергу, буде мастером для шобли слейвів для читання/бекапів тощо.

www.youtube.com/...​FakLdTmm42TMxbN8PvVn5g4KJ
Перший плейліст у нього також добрий. Зісно, не чтиво на 10 хвилин, але і тема розкрита ширше.

Недоліки:
ризик втрати даних, якщо Master вийде з ладу до того, як всі дані реплікуються на Slave;

хтось недогуглив до типу реплікацій — sync/async

Наприклад якщо в Master сервер попаде ракета до того, як дані реплікувалися на Slave, ризик втрати даних існує, незалежно від типу реплікації.

о, Lead Back-End Engineer, який взагалі не чув про транзакції

Astrology

тепер взагалі все стало зрозуміло

Синхронна реплікація це мастхев для WEB проектів, особливо на бюджетному хостингу, по типу Hetzner ). В основному, самі розробники не радять її використовувати, так як це не дуже позитивно впливає на живучість севісу. Тому не думаю, що читач багато втратив.

ще один астролог...
можливість використовувати sync залежить в першу чергу від відстані (latency), щоб не вбити продуктивність master,
коли відстань надто велика, а ні втрачати закомітчені транзакції, ні чекати не хочеться — використовують наприклад комбіновану реплікацію
master -sync-> primary standby -async-> secondary standby

Я вас не ображав, але бачу що ви розбираетесь в темі. А що буде коли ваша синхронна репліка (primary standby) почне деградувати, або повністю вийде з ладу?

Я вас не ображав, але бачу що ви розбираетесь в темі. А що буде коли ваша синхронна репліка (primary standby) почне деградувати, або повністю вийде з ладу?

Дежурная смена SRE выведет её из синхронизации, починит, введёт обратно
всё это время держать нагрузку будут оставшиеся 2 синхронные реплики

Поки вони будуть це робити, сервіс буде деградувати, а вірогідність такої ситуації у вас x3. Я вже мовчу про бюджетність даного рішення.

Поки вони будуть це робити, сервіс буде деградувати,

Если у вас хреновые SRE — значит вам не важна ваша система

Я вже мовчу про бюджетність даного рішення.

Значит вам не нужна реплика и консистентность.

Можливо ви додасте контексту, яка саме база даних використовуеться у такій конфігурації? Думаю стаття написана у контексті MySQL/Postgres.

Таке можна побудувати на базі Galera+MaxScale. Галєра — то синхронна мультимастер реплікація, макскейл — то проксі с балансером та фейловером.

Performance: by design performance of the cluster cannot be higher than performance of the slowest node;

mariadb.com/...​luster-known-limitations

Галeру нiколи нe використовув бо вeсь час были якiсь критичнi обмeжeння i ось знову (а можe завжди було). Тодi питання, нахiба вона окрiм high availabiliy, якщо нe дозволяє скeйлити write опeрацiї. Просто вiд кластeра очiкуєш i горизонтального маштабування як по читанню, так i по запису.

Ну, не знаю, в мене слово «кластер» завжди викликає в пам’яті абревіатуру CAP, і чого саме чекати від того кластера залежить від того, в який кут його загнано. За все треба платити. За консістенсі та авейлабіліті доводиться платить проблемами з масштабуванням запису. Багатьох це влаштовує.

Можливо i так, а то лише мої очiкування по скeйлу write пeрформансу

Завжди можна пожертвувати консістенсі і підняти класичний асинхронний мультимастер — і буде вам масштабування по запису.

Ну зараз набирає обертів NewSQL, який обяцяє і консистентність і доступність і масштабування з коробки. Наприклад ми вирішили потестувати TiDB, він ± гарно прикидується MySQL і поки особливих проблем з ним не було.

Ну зараз набирає обертів NewSQL, який обяцяє і консистентність і доступність і масштабування з коробки.

А потім ви такий ідете і читаєте, що таке shared-nothing architecture і потрапляєте в запой від об’єму наіпалова :)
NewSQL класно працюють, коли у вас ОЛАП сценарій, а транзакції, якщо і є то вони по факту обмежені відношеннями між таблицями аля «1 основна сутність і її частини, які не є частинами іншої стуності» (дерево, а не граф)

Наприклад ми вирішили потестувати TiDB, він ± гарно прикидується MySQL і поки особливих проблем з ним не було.

Транзакції, що змінювали дані на більшості нод кластера були? Як ви моделювали нетворк партішенінг?

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

В теорії, при sync replication, транзакція на master’і закомітиться тільки після того, як slave теж її зареплікує.

На яких реляційних базах (СУБД) використовували ці підходи?
З останнього абзацу ніби випливає, що MySQL.
Є ще прогресивніший варіант MariaDB. Можете звернути увагу на стандартні інструменти типу Galera Cluster and MariaDB MaxScale.
Все залежить від типу задач, архітектури системи. Значно цікавіші в плані масштабування NoSQL рішення, де можна будувати кластери з десятків, або сотень і тисяч нод.
Значно цікавіше питання чому обирають саме реляційні бази даних, а не ті, які створювались саме для швидкого масштабування. Де це є «з коробки», просто добавляєте кілька нод, або десятків нод у кластер.
«Nebula is a video-on-demand streaming service provider.» це воно?

NoSQL, звичайно, цікаві але ж тема допису «Масштабування реляційних баз...». Покажіть мені пальцем того хто ніколи не стикався із проблемою масштабування реляційної бази)
Тай NoSQL не silver bullet. Особливо коли справа доходить до strict consistency.

Рішення: не використовувати реляційні бази там, де потрібне масштабуваня. ;)
Або використовуати те, де це вирішено на рівні СУБД і задовільняє потребам.

Рішення: не використовувати реляційні бази там, де потрібне масштабуваня. ;)

Ржака в тому, що реляціну модель просували якраз для ... вейт фор іт ... маштабування.
Є рішення типу Сноуфлейк. Я не знаю чк вони це роблять, але у них вийшла реляційна БД для БігДати (звісно у нас були дуже денормалізовані дані).
Та і в статті описані техніки, що дозволяють відносно легко для багатьох сценаріїв вирішити горизонтальне масштабування (Чомусь в статті не згадано вертикальне масштабування)

Рішення: не використовувати реляційні бази там, де потрібне масштабуваня

предлагаете использовать Eventual Consistency для платежных систем? (ну и в принципе для систем, где вам важен результат — та же новая почта, к примеру)

предлагаете использовать Eventual Consistency для платежных систем?

Коли ти відправляєш ваєр трансфер, який губиться і кілька місяців блукає десь між «прокладками», чи коли ти за щось заплатив картою, а через кілька днів бачиш в клієнт-банку що платіж повернувся як неопрацьований — що це, як не eventual consistency?

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

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

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

чому як аргумент на користь ACID часто наводяться платіжні системи,

Потому что «потерять деньги» єто куда хуже чем «ой, мои фоточки не сразу видні моим подрузякам»
ну и не следует забівать — откуда вообще появилось понятие «транзакция» :)

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

Да, можно даже из таких элемеентов построить систему, которая обеспечивает ACID.
Или можно сразу взять систему, которая єто обеспечивает.

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

Все трошки складніше.
ACID забезпечує надійність вузла обчислень. Але не забезпечує надійність в рамках розподіленої системи (CAP теорема).
Але якщо ви відмовитесь від ACID на вузлах, ви фактично будете мати не один, а вже два рівні з проблемами. На рівні вузлу та на рівні синхронізації хостів.

Дякую, але це трохи очевидно, ні?

Я вже навіть не знаю як формулювати думки на доу щоб не потрібно було по 100500 повторювати «але ж питання було в іншому» :) Моє питання, ще раз, було тільки в тому, чому як приклад «жахів» eventual consistency наводяться саме платіжні системи — які в якості прикладу дуже так собі, бо трансфер грошей від суб’єкта А до суб’єкта Б очевидно не є атомарною операцією, й багато чого може статись між тим як А лишився грошей, а Б їх отримав.

Умовна система обліку підходить в якості прикладу набагато краще, бо подвійний (в ідеальному світі ще й імутабельний) запис — отже будь-яка бізнес-операція завжди транслюється в 2+ бухгалтерських транзакцій (проводок), і втрата якоїсь з них розвалює баланс.

Умовна система обліку підходить в якості прикладу набагато краще, бо подвійний (в ідеальному світі ще й імутабельний) запис — отже будь-яка бізнес-операція завжди транслюється в 2+ бухгалтерських транзакцій (проводок), і втрата якоїсь з них розвалює баланс.

ACID це не тільки про транзакції, а перш за все про те, як гарантувати цілістність СУБД при сбоях. Фінансові проводки в СУБД можуть бути, а можут і не бути, а ось FKs та інші Constraints в RDBMS є завжди.

як гарантувати цілістність СУБД при сбоях

Ти якщо берешся за мою освіту (не знаю навіщо), роби це хоча б системно, а не на від**сь :) Механізми покращення durability в сучасних СУБД мають приблизно ніяке відношення до власне моделі даних (чим посгресовський WAL концептуально відрізняється від журналювання монги чи комітлогу кассандри, наприклад?). Чи ти маєш на увазі не апаратні збої, а баги на стороні апки (отже не «D» а «A» та/або «C»?)

Ти якщо берешся за мою освіту (не знаю навіщо), роби це хоча б системно, а не на від**сь :) Механізми покращення durability в сучасних СУБД мають приблизно ніяке відношення до власне моделі даних (чим посгресовський WAL концептуально відрізняється від журналювання монги чи комітлогу кассандри, наприклад?). Чи ти маєш на увазі не апаратні збої, а баги на стороні апки (отже не «D» а «A» та/або «C»?)

Там все має значення. RDBMS з її ACID заточена щоб уникати як логічних так і апаратних помилок. Апаратні фіксяться за рахунок журналів, локів, ізоляції транзакцій. Логічні — за рахунок нормалізації в реляційній моделі данних. Тож, якщо ти перейдеш на Монго, Касандра або інший NoSQL, консистентність ти можеш втратити вже на рівні проектування бази данних. Наприклад будеш ссилатися в різних документах референцом на одну ж ту саму сутність, але на рівні ядра СУБД валідність цього референса ніяк не буде перевірятися.

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

Ця гарантія доволі «ортогональна» саме до реляційної моделі даних. Ніщо не заважає чекати референси в умовній монзі (може вони навіть це вже мають? не дуже слідкую), але ж питання тут в тому що це погано масштабується горизонтально. Бо сутність на яку ти посилаєшся може бути бозна де (на ноді за тридев’ять земель), отже перевірка цілісності посилань в великій розподіленій системі може буде ектремально дорогим задоволенням. Тобто це як завжди про компроміси, а не про однозначні переваги чи недоліки.

Коли ти відправляєш ваєр трансфер, який губиться і кілька місяців блукає десь між «прокладками», чи коли ти за щось заплатив картою, а через кілька днів бачиш в клієнт-банку що платіж повернувся як неопрацьований — що це, як не eventual consistency?

Нет, єто не оно.

Дуже цікавий метод ведення дискусії (ні). Сорі, не маю часу та натхнення.

Дуже цікавий метод ведення дискусії (ні). Сорі, не маю часу та натхнення.

если вам нужные разъяснения чем «eventual consistency» отличается от бизнес-проблем прикладного софта — то да, дискутировать нам с вами не о чем.

Що таке «бізнес-проблеми прикладного софту» я взагалі не зрозумів, напевно це щось дуже розумне за межами моїх когнітивних здібностей. А щодо EC маю питаннячко. Наскільки мені відомо, eventual consistency — це певна (відносно слабка) гарантія розподіленої системи, яка стверджує що будь яка зміна даних в одному з вузлів з часом обов’язково буде відрефлексована іншими вузлами. Так чому ж, о просвітлений Гуру, це визначення не можна застосувати до будь-якої з глобальних платіжних систем?

Мне кажется, что если бы вам и правда было интересно моё мнение — вы бы не хамили задавая вопрос.
Но т.к. это не так, то ты, необразованный подован, идёшь искать ответы на свои вопросы — самостоятельно.
(применять то можно, но всё это приведёт, как я уже и говорил, к потере денег)

вы бы не хамили
то ты, необразованный подован

sapienti sat

Я так понимаю, вы таки обиделись когда вам нахамили в ответ? :)
quod erat demonstrandum

CQRS забули. З перевагою в тому, що можна заюзати окремі OLTP та OLAP бази, і навіть трансформувати схему при передачі з OLTP до OLAP.

По базам є класична книжка Кабанчик www.oreilly.com/...​plications/9781491903063
та менш класична реклама ScyllaDB www.scylladb.com/...​-a-free-open-source-book

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

Реально працює із коробки певно тільки сетап c з рід репліками і скейлом на читання без суттєвого геморою. Все інше виглядає як недо-nosql на стороні database клієнта і купою геморою на стороні менеджменту інфраструктури.

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

Той момент, коли коментатор відкрив для себе, що sql бази теж скейлять...

висновки багаторічного практичного досвіду, якщо маєш сумніви — спробуй подискутуй.

саме дискутувати не ризикну, проте цікаво почути думку)

є приклади масштабування реляційних бд — Meta недавно прикрутила Raft до mysql (легко нагуглите в meta engineering blog). Хоча на це пішло багато часу + не кожна компанія має такі можливості
але є певні штуки типу Citus, так? Стосовно NoSQL, якщо б це завжди підходило, то і Мета мабуть не морочилась би з mysql, тим паче що вони розробили cassandra, і гугл не створив би Spanner
є якісь причини чому вони так зробили, на вашу думку?

чому вони так зробили, на вашу думку?

Стаття «Building and deploying MySQL Raft at Meta».
ACID, транзакції(розподілені транзакції).

цю статтю я читав (раз я посилаюсь на неї), де там відповідь на питання «чому не nosql» ?

Вона не призначена дати відповідь на це питання. кейс який там вирішується — вдосконалення механізму failover для сиквельних баз(запис там не відскейлений або out of scope статті просто — один instance і багато реплік у різних регіонах) те що зробив перехід від semi sync replication під блокуванням до raft дало покращення у плані автоматизації, latency, reilability і тому подібне. це уже говорить що стандартна реплікація працює не ідеально по багатьох пунктах для їх скейлу і географії. Тобто вони не могли досягнути failover з необхідними їм атрибутами.

To help guarantee safety and avoid data loss during the complex promotion and failover operations, several automation daemons and scripts would use locking, orchestration steps, a fencing mechanism, and SMC, a service discovery system. It was a distributed setup, and it was difficult to accomplish this atomically. The automation became more complex and harder to maintain over time as more and more corner cases needed to be patched.

Але цей кейс доволі стандартний для багатьох rdbms — автоматичний фейловер на read replicas і обов’язковий для hot stand by сценаріїв.

Відповідаючи на питання, чому вони не взяли NoSql і не викинули SQL щоб вирішити це — скоріше за всех знаходиться у площині задач які вони вирішують з ним, підходами, кодовую базою що вони мають на ньому(грубо кажачу це історично так склалалося).
Взагалі розглядит ці кейси під призмою потреб індустрії розробки не варто — будь-який розробник, що керуються типовими потребами, буде в останню чергу розглядати допрацювання rdbms engine на рівня ядра, щоб подтіягнути його до рівня інструментів які вже доступні в альтернативних рішеннях out-of-the box, це начебто очевидний момент.

не зрозумів цей коммент.
«не доробляйте рдбмс, бо вже є носкуль з коробки» чи як?

так, можливо що історичні причини, як версія годиться, явних пояснень чому mysql я ніде не бачив
ну а що на рахунок Google Spanner? Мотив створення, за словами самих креаторів, те що їм не вистачало acid і доводилося городити транзакційність поверх nosql. Тож існують все ж таки випадки коли потрібні і класичні транзакції і multi-regional і multi-leader db ?

так, можливо що історичні причини, як версія годиться, явних пояснень чому mysql я ніде не бачив

дорого переписувати всю код базу на альтернативні підходи що мають кращий механізм failover і geo replication, легче було допрацювати failover в mysql. (для мене це очевидно).
При тих умовах в статті наче зрозуміло, чому технологічна компанія не міняє бази данних після багатьох років в продакшині, навіть якщо є рішення на ринку що можуть краще задовольнити якісь з нефункціональних атрибутів?Це також не є підтвержденням того що скейлити sql базу буде легше аж ніяк.

ну а що на рахунок Google Spanner? Мотив створення, за словами самих креаторів, те що їм не вистачало acid і доводилося городити транзакційність поверх nosql. Тож існують все ж таки випадки коли потрібні і класичні транзакції і multi-regional і multi-leader db ?

Це спосіб вирішити одну і туж задачу двумя різними шляхами, в данному випадку ми говоримо про атрибути acid — можна взяти distributed rdbms(spanner), яка має потрібні тобі характиристики(distributed query engine, acid transactions на рівні технології) і прийняти недоліки для цього класу рішень(high-write latency, limited SQL in regards to non-distributed SQL, complexity, budget може ще шось), або замодулювати ті ж самі атрибути на рівні бази що не має пітримки acid з якимись trade-off і прийняти теж відповідні недоліки(наприклад, в конкурентному середовищі, що для досягнення того самого эффекту що і consistency + isolation транзакції треба буде полягатись на retry операції після спрацювання optimistic concurrency control, для досягнення atomicity треба модулювати схему данних специфічним чином і т.д..)
Існування баз типу spanner(як їх ще позиціонуть як NewSQL) не доводить того що rdbms гарно скейляться, а навпаки тільки підверджує limitations distributed rdbms — в цьому легко переконатись поглянувши на обмеження в цих системах.

та я не заперечую що масштабування реляційних бд це вельми складна штука і для цього потріба висококваліфікована команда db admins + devops

а які юзкейси можуть бути для цих NewSQL, які бізнес-сценарії, які дані і які патерни доступа? Я так сходу і не придумав де саме важливо мультирегіональна консистентність і транзакційність, тож ось що каже bing chat)

«Some of the use cases of Cloud Spanner are:

Financial Services: Cloud Spanner can be used to build financial trading systems that require low-latency transactions and high throughput
Gaming: Cloud Spanner can be used to build real-time multiplayer games that require low-latency transactions and high throughput
Retail: Cloud Spanner can be used to build e-commerce systems that require low-latency transactions and high throughput »

або замодулювати ті ж самі атрибути на рівні бази що не має пітримки acid з якимись trade-off і прийняти теж відповідні недоліки(наприклад, в конкурентному середовищі, що для досягнення того самого эффекту що і consistency + isolation транзакції треба буде полягатись на retry операції після спрацювання optimistic concurrency control, для досягнення atomicity треба модулювати схему данних специфічним чином і т.д..)

а я якось думав що досягнути acid поверх nosql не так просто. Наприклад як досягнути зміну даних в різних таблицях так щоб транзакційно, в nosql ? Ще ж Cassandra не підтримує джойни, так? Тобто треба або денормалізувати, або джойнити в памяті. Тобто паттерни доступа і те як храняться дані, вже накладають значні обмеження.
Наскільки я вас зрозумів, ви маєте на увазі мати версію в кожному рекорді, і повторювати операції якщо версія змінилася. Тобто якщо треба оновити order + shipment (суто штучний приклад, може їх можна оновлювати і окремо насправді), треба успішно пройти вставку з перевіркою версії для обох? В реляційних бд в разі часткового фейла транзакція відкатує всі ентіті, але ж тут транзакції не буде, тож можлива ситуація що десь апдейт зафейлився, а десь пройшов, і що тоді робити?
якщо ж рознести дані по різним сервісам і бд, то там теж складно досягти транзакційність (Saga pattern, або 2phase commit, і те і інше непросто)

Наскільки я вас зрозумів, ви маєте на увазі мати версію в кожному рекорді, і повторювати операції якщо версія змінилася. Тобто якщо треба оновити order + shipment (суто штучний приклад, може їх можна оновлювати і окремо насправді), треба успішно пройти вставку з перевіркою версії для обох?

Суто штучне рішення — в cassandra це має бути одна таблиця order_shipment, що підтримує atomic update і не потребує join. Якщо конфлікт може вирішити система вона перечитує останній стейт і ретраїть операцію з перевіркою реальних бізнесс правил на рівні цього агрегату. Якщо далі конфлікт система вирішити не здатна — вона повертає управління юзеру і далі юзер вирішує що робити далі. Данний підхід задоволняє всі вимоги ACID транзакції.

Наприклад як досягнути зміну даних в різних таблицях так щоб транзакційно, в nosql

Є купи нереляційних технологій що пітримують транзакційні атомарні операції на запис в відокремлених складових бази — коллекції, стріми і тому подібне. там де не має , терба модулювати на рівні того елементу, що дозволяє це. В Cassandra є батчі вони атомарні, якщо не важлива isolation — будь-ласка. Для більшості випадків з простими стратегіями розолву конфліктів типу lww, або там де їх немає цього більш ніж достатньо навіть без роллбеків. Там де є реалні конфлікт треба модулювати з урахування специфіки бази.

дякую, хороша відповідь і діалог

Вартість рішення. В NoSQL надійність та решта переваг через подвійне-потрійне зберігання даних, не було можливості транзакцій як в SQL. Там може бути ще кілька відмінностей.
Міграція даних з тисяч серверів це дорого. Ці дані не коштують стільки, щоб на їх міграцію витрачати багато коштів. Питання перенавчання інженерів, наявних методик роботи, інструментів, процедур, які вже реалізовані. Це система 24*7, як в ній на ходу міняти ноди сховища даних на щось інше? Може і є якісь рішення. Це ж не банк на добу (кілька годин) зупинити для міграції.

Master/Master

За тобою вже виїхали люди з Африки

Світ відійшов від термінології «master/slave» на користь «primary/standby».

а ще process / controller & allowlist / blocklist амість white / black list’ів. Що це дало по перформансу поки неясно...

Світ відійшов від термінології «master/slave» на користь «primary/standby».

1) Ні. Є купа альтернатив, найадекватніше напевне primary/replica, або як написали нижче leader/follower (але воно міслідінг трохи)
2) Точно не «standby», бо це паттерн/тактика для досягнення релаябіліті

Ок. Моя думка в іншому. Що світ не використовує більше master/slave :)

Ок. Моя думка в іншому. Що світ не використовує більше master/slave :

Ну тут я не можу сперечатись — це ваша думка. Але вона може відрізнятись від реальності :)

Мабуть ви не читаєте новини

Не вгадали. Я читав ці «новини», коли вони були новинами (у 2020 після справи про вбивство Флойда, хоча наче ще раніше були випадки).
Проблема в тому, що в 2023 дойоб за назву мастер-слейв репликація — це ознака дурника, що хоче одягнути біле пальто.
До речі, сам термін пішов чи то з гідравліки, чи то автобудування.

Реверт коммітів будете робити самі чи «всі дурники один я розумний»?

Реверт коммітів будете робити самі чи «всі дурники один я розумний»?

Вы знаете, наличие этих коммитов вовсе не доказывает что «весь мир умный»
Это доказывает только то, что хозяева репозитариев в гробу видели бодаться с придурковатыми борцунами

Підписатись на коментарі