Чому так погано читати дані з бази даних, "власником" якої є інша мікросервіс


64

Я нещодавно прочитав цю чудову статтю про архітектуру мікросервісів: http://www.infoq.com/articles/microservices-intro

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

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

Я чогось тут пропускаю? Чи є якась інша причина, чому дані слід читати лише через API?

Потрібно сказати, що моя компанія значно менша, ніж Amazon (і завжди буде такою), і максимальна кількість користувачів, яких ми коли-небудь можемо мати, становить близько 5 мільйонів.


Ще одним загальним фактором, який не згадується у відповідях, є те, що при записі в базу даних локальне кешування, навіть просте відображення O / R, може отримувати несвіжі дані при негайному зверненні до бази даних. Якщо ви розглядаєте можливість обходу API µservice з міркувань швидкості, цілком можливо, що архітектура µservice була занадто далеко.
Joop Eggen

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

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

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

Відповіді:


69

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

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

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


1
Це чудовий момент! Одне, що мене менше турбує, - це те, що Postgres тепер має підтримку як для зберігання документів, так і для RDBMS ( безtheloop.com/articles/2014-09-30-postgresql-nosql ). Ваша думка все-таки є дійсною, і я буду її уважно розглядати.
Девід

3
Це не повинно робити вас менш занепокоєним @David тільки тому, що інструмент може щось зробити, не означає, що зміна не порушить багато речей. Це сенс мати ступінь відокремленості - ви можете повністю змінити дані за API, не змінюючи того, що бачить користувач. Я тут виступаю як база даних ... поки те, що бачить клієнт, є тим самим, ви можете змінити допоміжну програму скільки завгодно.
Бен

1
@David Хоча це цікава новина, вона описала сценарій, який я дуже цікавий. Якщо ви зміните свою схему БД з реляційної на документ, що базується на документі, вона матиме однаковий вплив на всіх залежних від неї: вам доведеться переписати всі запити. Існує також кошмар необхідності розгортати всі ці зміни одразу, щоб підтримувати сумісність між компонентами по всій системі.
back2dos

1
@David: Обмеження доступу до кількох чітко визначених представлень, можливо, означає створити інший API з деякими перевагами, які випливають із ним. Поки це лише перегляди, ви, однак, обмежені для доступу лише для читання. А наявність компонента залежить від API сервісу та API перегляду робить його дуже крихким. Отже, якщо ви створюєте компонент залежно від представлень, ви заздалегідь визначили його лише для читання або з високим обслуговуванням. Я тут пахну технічним боргом. Також ви можете додати горизонтальний розділ таким чином, щоб ваша база даних не дозволяла вам.
back2dos

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

55

Що важливіше та найважливіше у мікросервісі: його API чи його базі даних? API, тому що це його договір з рештою світу. Схема бази даних - це просто зручний спосіб зберігання даних, керованих службою, сподіваючись, організований таким чином, що оптимізує продуктивність мікросервісу. Команда розробників повинна вільно реорганізувати цю схему - або перейти на зовсім інше рішення сховища даних - у будь-який час. Інший світ не повинен байдуже. Решта світу піклується, коли API змінюється, тому що API є договором.

Тепер, якщо ви заглянете в їх базу даних

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

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

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


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

15

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

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

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

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

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

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


4

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

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

Сценарій: ви прив’язуєте пару компонентів до RDBMS безпосередньо, і ви бачите, що один конкретний компонент стає продуктивним вирізом

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

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

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

можливо, ви хочете денормалізувати базу даних, але ви не можете, оскільки це вплине на всі інші компоненти

Для мене це твердження просто невірне. Денормалізація - це "адитивна" зміна, а не "руйнівна зміна", і жодна заявка не повинна порушуватися через денормалізацію.

Єдиний спосіб цього розбиття програми полягає в тому, що код програми використовує щось на кшталт "select * ..." і не обробляє зайвий стовпець. Для мене це буде помилка в додатку?

Як денормалізація може порушити програму? Мені це здається FUD.

Залежність схеми:

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

Основні дані

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

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

Нормалізація

Якщо 3 дизайнерів баз даних перейдуть і спроектують нормалізовану схему db, вони опиняться в одній конструкції. Гаразд, може бути певна варіація 4NF / 5NF, але не дуже. Більше того, існує ряд питань, які дизайнер може задати, щоб підтвердити модель, щоб дизайнер міг бути впевненим, що вони потрапили до 4NF (я занадто оптимістичний? Чи люди намагаються потрапити до 4NF?).

оновлення: Під 4NF тут я маю на увазі, що всі таблиці в схемі дісталися до їх найвищої нормальної форми до 4NF (усі таблиці нормалізувались до 4NF).

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

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

  1. Можливі варіанти на основі типів БД, що підтримуються (JSON, ARRAY, підтримка типу Geo тощо)
  2. Деякі можуть заперечити варіацію на основі 4NF / 5NF
  3. Ми виключаємо фізичні зміни (тому що це не має значення)
  4. Ми обмежуємо це дизайном OLTP, а не дизайном DW, оскільки це схеми, до яких ми хочемо надати доступ лише для читання

Якби 3 програмісти, де їм було призначено реалізувати (як код), очікування було б для 3-х різних реалізацій (потенційно дуже різних).

Для мене потенційно виникає питання "віри в нормалізацію".

Порушення змін схеми?

Денормалізація, додавання стовпців, зміна стовпців для більшого зберігання, розширення дизайну новими таблицями тощо - це все безперебійні зміни, і дизайнери БД, які дісталися до 4-ї нормальної форми, будуть впевнені в цьому.

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

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

Що важливіше та найважливіше у мікросервісі: його API чи його базі даних? API, тому що це його договір з рештою світу.

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

Наприклад, коли виникає вимога заповнити сховище даних для бізнес-аналізу, то схема та підтримка CDC набувають важливого значення з точки зору ділової звітності незалежно від API.

Проблеми з API?

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

What motivates people to desire local read-only access?

Оптимізація API:

LinkedIn провели цікаву презентацію (з 2009 р.) Щодо оптимізації їх API та чому це важливо для них в їх масштабі. http://www.slideshare.net/linkedin/building-consistent-restful-apis-in-a-highperformance-en Environment

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

Якщо API не має тієї самої складності, як LinkedIn, то ви можете легко отримати сценарії, де:

  • API отримує набагато більше даних, ніж потрібно (марно)
  • API Chatty API, куди вам доведеться дзвонити API багато разів

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

Я підозрюю, що там є набір людей, які можуть додати його як:

  • Низька реплікація основних даних у базу даних мікросервісу (без витрат на розробку та технічно ефективна)
  • Віра в нормалізацію та стійкість програм до змін схеми
  • Можливість легко оптимізувати кожен випадок використання та потенційно уникнути балакучих / марнотратних / неефективних віддалених дзвінків API
  • Плюс ще деякі переваги з точки зору обмежень та узгодженого дизайну

Ця відповідь задовго вийшла. Вибачення !!


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

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

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

0

Управління державою (можливо, це база даних) може бути розгорнута в контейнер мікросервісу та відкрита через API. База даних мікросервісу не видима для інших систем поза контейнером - лише API. Крім того, ви можете мати іншу службу (наприклад, кеш), керуючи станом через API. Наявність усіх залежностей Microservice (крім викликів API до інших служб) у межах одного розгорнутого контейнера є ключовою відмінністю в архітектурі. Якщо цього не отримати, поверніться і вивчіть архітектуру.

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