Як поводитися з обмеженнями сторонніх ключів при переході від моноліту до мікропослуг?


18

Моя команда переходить з монолітного додатку ASP.NET на .NET Core та Kubernetes. Зміни коду, здається, відбуватимуться так само добре, як і можна очікувати, але там, де моя команда стикається з великим розбратом, є навколо бази даних.

Наразі у нас є досить велика база даних SQL Server, в якій зберігаються всі дані для всього нашого бізнесу. Я пропоную, щоб ми розділили базу даних аналогічно поділу коду - каталогічні дані в одній (логічній) базі даних, інвентарні дані в іншій, замовлення в іншій і т. Д. - і кожен мікросервіс став братами для своєї бази даних .

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

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

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


5
Референтна цілісність надзвичайно цінна. Чи справді вузьким місцем є масштаб бази даних? Вам дійсно потрібна масштабованість у стилі мікросервісу? Ви краще за мене знаєте, чи підходить така зміна архітектури для вашої організації, але, будь ласка, врахуйте, що це просто не дуже підходить для багатьох випадків використання. Можливо, існують й інші способи масштабування з більш привабливими компромісами. Наприклад, якщо запитів до бази даних за секунду занадто високі, можливо, потрібна реплікація бази даних. І ви можете горизонтально масштабувати веб-сервери, не використовуючи мікросервіси.
амон

Хороші бали. Ми розглядаємо деякі з цих варіантів для короткострокових прибутків. Хоча перехід до мікросервісів - це довга гра. На мою думку, це дозволить нам масштабуватись роками, а не місяцями.
Реймонд Сальтреллі

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

@amon Зробіть це відповіддю, і я його схвалюю. Це хороше питання, і плюси і мінуси потрібно справедливо представляти.
mcottle

@mcottle нормально, зробили!
амон

Відповіді:


19

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

Ця (на жаль, досить тривала) відповідь буде звучати трохи на кшталт "мікросервіси погані, моноліти на все життя!", Але це не мій намір. Моя думка полягає в тому, що мікросервіси та розподілені бази даних можуть вирішувати різні проблеми, але не маючи власних питань. Для того, щоб зробити вагомий аргумент для вашої архітектури, ви повинні показати, що ці проблеми не застосовуються, їх можна пом'якшити і що ця архітектура є найкращим вибором для потреб вашого бізнесу.

Поширювані дані важко.

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

Атомні оновлення, транзакції, послідовність / референтна цілісність та довговічність є надзвичайно цінними, і від них не слід неодмінно відмовлятися. Мало сенсу мати дані, якщо вони неповні, застарілі або відверто неправильні. Якщо у вас є ACID як бізнес-вимога, але ви використовуєте технологію баз даних, яка не може запропонувати її нестандартно (наприклад, багато баз даних NoSQL або архітектура DB-на-мікросервіс), ваша програма повинна заповнити прогалину та надати ці гарантії.

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

    Наприклад, розглянемо читання аналізів Джепсена відомих систем розподілених баз даних , можливо, починаючи з аналізу Кассандри . Я не розумію половини цього аналізу, але TL; DR полягає в тому, що розподілені системи є настільки складними, що навіть провідні в галузі проекти іноді помиляються з ними, таким чином, що можуть здаватися очевидними заднім числом.

  • Розподілені системи також передбачають більші зусилля з розробки. У певній мірі існує прямий компроміс між витратами на розробку або випаданням грошей на обладнання для запікання.

Приклад: звисаючі посилання

На практиці ви не повинні дивитися на інформатику, а на вимоги вашого бізнесу, щоб дізнатися, чи можна і як кислоту розслабити. Наприклад, багато зовнішньополітичних відносин можуть бути не такі важливі, як вони здаються. Розглянемо товар - категорія n: m співвідношення. У RDBMS ми можемо використовувати обмеження із зовнішнім ключем, щоб лише існуючі продукти та існуючі категорії могли бути частиною цього взаємозв'язку. Що станеться, якщо ми запровадимо окремі послуги товарів і категорій, а товар або категорію буде видалено?

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

  • Зауважте, що для цього може знадобитися рівень програми для JOINдекількох баз даних / мікросервісів, який просто переміщує обробку з сервера баз даних до вашої програми. Це збільшує загальне навантаження та має переміщувати додаткові дані по мережі.

  • Це може зіпсуватися з пагінацією. Наприклад, ви вимагаєте подати наступні 25 продуктів із категорії та відфільтрувати недоступні продукти з цієї відповіді. Зараз у вашій програмі відображається 23 продукти. Теоретично, сторінка з нульовими продуктами також була б можливою!

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

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

Приклад: паралельні замовлення

Тепер замість цього розглянемо співвідношення товару - замовлення. Що відбувається з замовленням, якщо товар видалено чи змінено? Гаразд, ми можемо просто скопіювати відповідні дані товару у запис замовлення, щоб вони були доступними - торговий простір на диску для простоти. Але що робити, якщо ціна товару змінюється або товар стає недоступним безпосередньо перед тим, як зробити замовлення на цей товар? У розподіленій системі для розповсюдження ефектів потрібен час, і порядок, ймовірно, пройде із застарілими даними.

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

Але, можливо, це не є можливим, наприклад, для налаштувань із великою сумісністю. Поміркуйте, що 3000 людей, які поспішають придбати квитки на концерт протягом перших 10 секунд, і припустимо, що для зміни доступності потрібно 10 хвилин для просування. Яка ймовірність продажу останнього квитка декільком людям? Залежить від того, як розбираються ці зіткнення, але, використовуючи розподіл Пуассона, λ = 3000 / (10s / 10ms) = 3ми отримуємо P(k > 1) = 1 - P(k = 0) - P(k = 1) = 80%шанс зіткнення за інтервал 10 мс. Незалежно від того, що продажа та скасування більшості ваших замовлень можливі без вчинення шахрайства, це може призвести до цікавої розмови з вашим юридичним департаментом.

Прагматизм означає збирання вишні найкращими рисами.

Хороша новина полягає в тому, що вам не доведеться переходити до моделі розподіленої бази даних, якщо цього не потрібно. Ніхто не відкликає ваше членство в клубі мікросервісів, якщо ви не робите мікросервіси «належним чином», оскільки такого клубу немає - і немає жодного вірного способу побудови мікросервісів.

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

Можна масштабувати без мікросервісів.

Мікросервіси мають дві основні переваги:

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

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

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

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

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

У вас є сильний бізнес-випадок?

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

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

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

Є також великий компонент YAGNI для масштабованості. В умовах невизначеності, це стратегічне бізнес-рішення щодо нарощування масштабованості зараз (нижчі загальні витрати, але пов'язані з можливими витратами і можуть не знадобитися) порівняно з відстроченням певної роботи щодо масштабованості (більші загальні витрати при необхідності, але у вас є краща ідея фактичного масштабу). Це передусім не технічне рішення.


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

1
@alan Збережені процедури можна використовувати для хорошого, але вони створюють дві проблеми з продуктивністю: (1) Більш складні запити складніше для оптимізації бази даних. (2) Використання sprocs означає більше роботи на сервері БД. ОП хоче розколоти БД, щоб масштабувати подальший масштаб, але уникнення складних паростків може вже забезпечити цей простір. Звичайно, проростки та складні запити також можуть бути хорошими для продуктивності, наприклад, коли вони мінімізують кількість даних, які повинні бути передані з БД для відповіді на запит. Розщеплення БД погіршить цю проблему, коли потрібні приєднання між серверами.
Амон

0

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


-1

Ваша позиція правдоподібна і правильна.

Як переконати забарвлених у вовни db наркоманів, хоча інше питання. Я б сказав, що у вас є два варіанти.

  1. Знайдіть конкретний приклад, коли БД досягла своїх меж. У вас є, наприклад, "архівні таблиці"? Чому це нормально? Яку максимальну кількість замовлень за секунду ви можете взяти? Показати, що БД не відповідає вимогам, і ваше рішення їх виправляє.

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


1
Я не -1, але, щоб це було гарною відповіддю, я втратив би прискіпливу точку 2 і розширюю питання про те, коли буде доречно потреба у кількох базах даних. Я не думаю, що таблиці архівів - це обов'язково антипатерн у базах даних, які не підтримують, не розбивають розділи. В базі даних, яку я зараз використовую, є близько 130 ГБ даних з 26 таблицями> 10М рядків, а продуктивність недостатньо віддалена, щоб розбити базу даних; тож я дуже скептично налаштований і мені хочеться почути, чому це гарна ідея, і коли це потрібно зробити - ця відповідь є найближчим, що я бачив досі.
mcottle

добре. Я згадую архівні таблиці, оскільки вони придушують обмеження FK. це тріск в обладунках. розщеплення мікросервісом - це не розмір ДБ, а це зберігає ваші мікросервіси. Якщо ви не можете вимкнути його та викинути, це насправді не мікросервіс. повторно 2. ОП згадує MF, вони можуть буквально найняти його / думки прийти і сказати їм розділити db
Ewan

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

Найкращий аргумент для бази даних на послугу - це обмеження підключення. Нечасто застосовувати пул з'єднань, тому кожна мікросервіс вже потребує декількох підключень до екземпляра бази даних, тоді ви можете мати кілька примірників кожної з цих мікросервісів, кожен з яких має власний пул. Врешті все може прийти в голову, коли ви просто вичерпали здатність бази даних обробляти всі з'єднання, які вона отримує.
Кріс Пратт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.