Czy w mikrousługach jest to pojedyncza baza danych, czy pojedyncza instancja bazy danych dla każdej usługi?

50

Rozumiem, że każda usługa w architekturze mikrousług powinna mieć własną bazę danych. Czy jednak posiadanie własnej bazy danych oznacza po prostu posiadanie innej bazy danych w tej samej instancji bazy danych lub dosłownie posiadanie innej instancji bazy danych?

Przez to nie mam na myśli udostępniania baz danych, co jest nie-nie, ale raczej instancja bazy danych.

Na przykład, jeśli korzystam z AWS i mam 3 usługi, to czy tworzę 3 bazy danych dla każdej usługi w pojedynczej instancji RDS, czy też tworzę 3 instancje RDS, z których każda zawiera bazę danych, która jest używana niezależnie przez każdą z 3 usług?

Jeśli lepszym pomysłem jest używanie wielu baz danych w jednej instancji RDS, czy uda mu się pokonać cel posiadania niezależnych usług, ponieważ:

  1. Zasób instancji RDS zostanie udostępniony między usługami. Czy usługa A, która w danym czasie może intensywnie korzystać z bazy danych, wpłynie na usługę B, która korzysta z innej bazy danych, ale w tej samej instancji RDS?

  2. Wszystkie usługi będą zależały od wersji bazy danych w tej instancji RDS.

ksenon
źródło
8
Jest to wszystko, co najlepiej spełnia twoje konkretne wymagania.
Robert Harvey
1
Nie jestem pewien, czy nazwałbym siebie ekspertem w zakresie „mikrousług”, ale możesz mieć dowolne konfiguracje i dbs. Możesz mieć bazę danych odczytywaną przez jedną usługę i zapisywaną przez inną. Lub alternatywnie możesz mieć tylko 1 db (lub mniej technicznie) dla całego systemu.
Mark Rogers
Oto dobra lektura na ten temat: plainoldobjects.com/2015/09/02/...
RandomUs1r
Przeczytaj o „zasadzie pojedynczej odpowiedzialności”. Czy zastanawiałeś się nad wdrożeniem „mikrousługi bazy danych”, z której korzystają inne mikrousługi?
ChuckCottrill

Odpowiedzi:

20

To naprawdę zależy od wymagań dotyczących skalowalności oraz od tego, jak / jeśli instancje mikrousług muszą współpracować, aby zapewnić jeden wynik. Pomaga wiedzieć, jakie są kompromisy:

Wszystko to w jednej bazie danych

  • Łatwiejsza konfiguracja
  • Nie jest wymagana koordynacja ani komunikacja z innymi wystąpieniami usługi
  • Łatwiej odkryć pełny zestaw danych
  • Wydajność systemu ograniczona wydajnością bazy danych

Utrzymywanie baz danych osobno

  • Pełna odpowiedź na żądanie może być rozłożona na instancje mikrousług
  • W takim przypadku zwiększyłeś komunikację i negocjacje w celu rozwiązania żądania
  • Obsługa danych w przypadku utraty węzła mikrousług (nawet gdy baza danych jest nadal uruchomiona, nie można się do niej dostać, dopóki nowa z odpowiednią konfiguracją nie zostanie przywrócona)
  • Zwiększona złożoność konfiguracji

Jaki problem rozwiązujesz?

W niektórych przypadkach martwisz się tylko ulotnymi danymi. Jeśli baza danych ulegnie awarii, nie jest to duży problem. W takich przypadkach możesz nawet nie potrzebować bazy danych na początek. Po prostu zachowaj to wszystko w pamięci i spraw, aby wszystko było niezwykle szybkie. To najłatwiejsze rozwiązanie do pracy.

W innych przypadkach potrzebujesz integralności danych, ale twoja baza danych może zwiększyć swoją pojemność w zależności od liczby posiadanych węzłów. W takim przypadku pojedyncza baza danych jest prawdopodobnie więcej niż wystarczająca, a samodzielne zarządzanie jej odpowiedzią jest właściwą odpowiedzią.

Między nimi jest wiele przypadków. Na przykład możesz mieć bazy danych specyficzne dla regionu, więc dla każdego wystąpienia usługi w innym regionie masz osobną bazę danych. Zazwyczaj bazy danych z fragmentowaniem nie radzą sobie dobrze w różnych regionach, więc jest to sposób na nieco zlokalizowanie danych i samodzielną kontrolę koordynacji.

Doktryna i rzeczywistość

Przeczytałem wiele artykułów o mikrousługach i ich modułowości. Zalecenia obejmują zakres od frontonu, mikrousług i warstwy danych jako całości do współużytkowania bazy danych i / lub kodu frontonu dla wszystkich instancji. Zwykle większa izolacja zapewnia największą skalowalność, ale wiąże się to ze zwiększoną złożonością.

Jeśli Twoja mikrousługa jest bardzo obciążona obliczeniami, rozsądnie jest pozwolić na skalowanie liczby tych mikrousług zgodnie z potrzebami - udostępnianie bazy danych lub nawet kodu frontonu nie zaszkodzi ani nie utrudni takiego podejścia.

W rzeczywistości konkretne potrzeby twojego projektu będą wymagały innego zestawu kompromisów, aby wykonać pracę w odpowiednim czasie i poradzić sobie z mierzonym obciążeniem systemu (plus trochę więcej). Uważaj w pełni izolowany front-end, mikrousługę i trio warstwy danych za wzniosły cel. Im większe zapotrzebowanie na system, tym bliżej tego celu prawdopodobnie będziesz musiał być. Nie jesteśmy wszyscy [insert name of highly successful web entity here]i nie zaczęli się tam, gdzie są teraz. Czasami musisz po prostu zacząć od sytuacji mniej niż idealnej i być z tego zadowolonym.

Berin Loritsch
źródło
71

Zakładając, że masz pewne usługi, które mogą korzystać z tego samego rodzaju systemu DB i wersji, jeśli używasz różnych instancji bazy danych lub db, to decyzja, której nie powinieneś podejmować w czasie projektowania. Zamiast tego powinieneś być w stanie podjąć decyzję w czasie wdrażania, co możesz po prostu skonfigurować. Zaprojektuj swoje usługi tak, aby były niezależne od miejsca, w którym przechowywane są bazy danych innych usług.

Podczas pracy możesz zacząć od jednej instancji, a jeśli system działa dobrze, zostaw to w ten sposób. Jeśli jednak zauważysz, że nie skaluje się to dobrze dla twojego systemu, ponieważ różne bazy danych w jednym wystąpieniu współużytkują zbyt wiele zasobów, zawsze możesz użyć różnych wystąpień, jeśli to pomoże.

Dlatego usługa nie narusza architektury mikrousług tylko dlatego, że pozwalasz dwóm z nich współdzielić jakiś zasób - narusza to, gdy udostępnianie zasobu staje się obowiązkowe.

Doktor Brown
źródło
Ten rodzaj brzmi jak przedwczesna optymalizacja. Co się stanie, jeśli zużyte zasoby nigdy nie zasługują na dodatkowe wystąpienia? Potem zmarnowałeś czas na budowanie elastyczności
reggaeguitar
5
@reggaeguitar: koszty tego zwykle powinny być znikome - w rzeczywistości w przypadku architektury mikrousług może być więcej wysiłku w próbie scentralizowania konfiguracji bazy danych między różnymi usługami niż utrzymywanie lokalizacji db dla każdej usługi indywidualnie konfigurowalnej. Co więcej, istotą architektury mikrousług jest wysoka skalowalność, jeśli nie jest to potrzebne, nie należy podejmować decyzji o mikrousługach.
Doc Brown
1
@DocBrown To ma sens, dziękuję za odpowiedź!
reggaeguitar
13

To nie ma znaczenia

Jedynym scenariuszem, w którym teoretycznie może mieć znaczenie, jest migracja jednej usługi do innej wersji bazy danych. Ale nawet wtedy nie ma prawdziwej różnicy między posiadaniem oddzielnych instancji od początku a migracją tej jednej usługi ze współużytkowanej instancji do osobnej. Powiedziałbym, że posiadanie oddzielnych instancji tylko z powodu tego scenariusza jest przykładem YAGNI.

Michael Borgwardt
źródło
1
Zakładając, że dana usługa ma duże obciążenie w pojedynczej instancji RDS, czy w końcu zużyje zasoby w tej instancji i wpłynie na inne usługi korzystające z tej samej instancji RDS?
ksenon
1
@xenon: tak, ale to jest powód, aby pomyśleć o poprawie wydajności RDS poprzez tuning, lepszy sprzęt lub klastrowanie, a nie o zmianie architektury systemu - jeśli ta usługa pozostawia przepustowość dla innych usług, wkrótce skończy się jej pojemność wszystko samo w sobie. Myślę jednak, że możesz mieć specjalne wymagania, że ​​przeciążona usługa nie może wpływać na innych. Niektóre RDS mogą w rzeczywistości nadal zezwalać na to w pojedynczej instancji, definiując ograniczenia zasobów dla poszczególnych użytkowników.
Michael Borgwardt,
scenariusz, w którym ma to znaczenie, to sytuacja, w której instancja mikrousług ma swój własny stan. Następnie powinien zostać wdrożony z własną instancją db, która może być również wąskim gardłem wydajności
Ewan
3

Instancja RDS jest pojedynczą skrzynką. Jeśli masz wiele baz danych w jednej instancji, współużytkują one procesor / pamięć itp.

Jeśli wydajność mikrousług zależy od wydajności bazy danych : należy wdrożyć wiele kopii mikrousług, z których każda korzysta z innej bazy danych, ale z każdą bazą danych w tej samej instancji RDS. Jest bez sensu * (z wyjątkiem przełączania awaryjnego). Twój klaster mikrousług będzie działał z tą samą prędkością co pojedynczy mikrousługa

Powiedziałbym jednak , że mikrousługa związana z wydajnością bazy danych jest niezwykła.

Zwykle mikrousługa pobiera dane z bazy danych, wykonuje logikę i zapisuje pewne informacje z powrotem do bazy danych. Wąskim gardłem wydajności jest logika , a nie wybór i / lub wstawianie.

W takim przypadku możesz po prostu udostępnić tę samą bazę danych we wszystkich instancjach mikrousług

Ewan
źródło
Muszę zakwestionować twoje twierdzenie, że logika stanowi wąskie gardło, a nie baza danych. Z mojego doświadczenia wynika , że najbardziej prawdopodobnym miejscem do znalezienia poprawy wydajności jest baza danych.
RubberDuck,
hmm tak, ale na pewno te ulepszenia wydajności uzyskuje się poprzez przeniesienie logiki out of db i do służby. Gdy to zrobisz, TO logika stanie się wąskim gardłem
Ewan
1
Zazwyczaj nie. Te ulepszenia pochodzą z dostrajania indeksów i zapytań.
RubberDuck,
cóż, w moim doświadczeniu byłoby to niezwykłe. Nie chodzi o to, że zwykle nie ma miejsca na te ulepszenia, ale że po usunięciu naprawdę złych rzeczy baza danych jest nadal czynnikiem ograniczającym.
Ewan
1

Celem zachowania poufności bazy danych dla usługi jest hermetyzacja. Twoja mikrousługa to czarna skrzynka, z której inne usługi w systemie będą korzystać za pośrednictwem publicznego interfejsu.

Istnieją dwie płaszczyzny, na których działa to kapsułkowanie:

  • Pierwszy jest logiczny na poziomie aplikacji. Twoja usługa jest właścicielem niektórych obiektów biznesowych w systemie i musi utrzymywać stan tych obiektów. To, że niektóre konkretne bazy danych wspierają te obiekty biznesowe, jest jedynie szczegółem implementacji. Prowadząc oddzielną bazę danych, uniemożliwiasz innym usługom dostęp backdoora do Twojej implementacji, zmuszając je do korzystania z publicznego interfejsu. Celem jest czysta architektura i zdyscyplinowane programowanie. To, gdzie dokładnie znajduje się baza danych, nie ma znaczenia na tym poziomie, o ile usługa ma odpowiednie szczegóły połączenia, aby ją znaleźć.

  • Drugi poziom działa. Nawet, jeśli Twój projekt jest idealną czarną skrzynką, jak zauważyłeś, różne prace skupione na jednym komputerze mogą konkurować o zasoby. Jest to dobry powód, aby umieścić osobne logiczne bazy danych na osobnych komputerach. Jak zauważyły ​​inne odpowiedzi, jeśli twoje potrzeby nie są bardzo wymagające, a budżet jest napięty, jest to pragmatyczny argument za kolokacją na jednym komputerze. Jednak, jak zawsze, kompromisy: ta konfiguracja może wymagać większej opieki nad dzieckiem w miarę rozwoju systemu. Jeśli pozwala na to budżet, prawie zawsze wolę dwa osobne małe komputery do wykonania dwóch zadań niż współdzielenie jednego większego komputera.

ben autor
źródło
1

Myślę, że może to być nieco bardziej teoretyczne. Jednym z motywujących pomysłów mikrousług jest wspólny proces przekazywania wiadomości. Mikrousługa jest jak aktor w modelu aktora. Oznacza to, że każdy proces utrzymuje swój stan lokalny, a jedynym sposobem na uzyskanie dostępu do stanu innego procesu jest wysłanie wiadomości (i nawet wtedy drugi proces może odpowiedzieć, jak chce na te wiadomości). Pod pojęciem „każda mikrousługa ma swoją własną bazę danych”, tak naprawdę stan procesu (tj. Mikrousługa) jest lokalny i prywatny . W dużej mierze sugeruje to, że „baza danych” powinna być kolokowanaz mikrousługą, tj. „baza danych” powinna być przechowywana i wykonywana w tym samym węźle logicznym co mikrousługa. Różne „instancje” mikrousług są osobnymi procesami, dlatego też każda powinna mieć własną „bazę danych”.

Globalna baza danych lub baza danych współdzielona między mikrousługami, a nawet instancjami mikrousług, stanowiłaby z tego punktu widzenia stan współdzielony. „Odpowiednim” sposobem na poradzenie sobie z tym z perspektywy mikrousług jest udostępnianie wspólnej bazy danych za pośrednictwem mikrousług „bazy danych”. Inne mikrousługi, które chciałyby wiedzieć o zawartości bazy danych, wysyłałyby wiadomości do tej „mikrousługi bazy danych”. Zazwyczaj nie eliminuje to potrzeby stanu lokalnego (tj. „Baz danych” instancji mikrousług) dla oryginalnych mikrousług! Jakie zmiany reprezentuje ten stan lokalny. Zamiast przechowywać „User Sally jest administratorem”, zapisuje „Mikrousługa bazy danych powiedziała„ User Sally jest administratorem pięć minut temu ”. Innymi słowy, o stanie innych mikrousług.

Zaletą tego jest to, że każda mikrousługa jest samodzielna. To sprawia, że ​​mikrousługa jest atomową jednostką awarii. (W większości) nie musisz się martwić o mikrousługę w częściowo częściowo funkcjonalnym stanie. Oczywiście problem został przeniesiony do sieci mikrousług. Mikrousługa może nie być w stanie wykonać żądanej funkcji z powodu niemożności skontaktowania się z innymi mikrousługami. Korzyścią jest jednak to, że mikrousługa będzie w dobrze zdefiniowanym stanie i może być w stanie oferować usługi o obniżonej jakości lub ograniczone, np. Poprzez wypracowanie przestarzałych przekonań. Minusem jest to, że bardzo trudno jest uzyskać spójną migawkę systemu jako całości i może być dość (niepożądana) redundancja i duplikacja.

Oczywiście nie sugeruje się umieszczania instancji Oracle w każdym kontenerze Docker. Po pierwsze, nie każda mikrousługa potrzebuje „bazy danych”. Niektóre procesy nie wymagają żadnego trwałego stanu do poprawnego działania. Na przykład mikrousługa, która tłumaczy dwa protokoły, niekoniecznie potrzebuje żadnego trwałego stanu. Gdy bowiem potrzebny jest stan trwały, słowo „baza danych” to tylko słowo „stan trwały”. Może to być plik z JSON, baza danych Sqlite lub lokalnie działająca kopia Oracle, jeśli chcesz, lub dowolny inny sposób lokalnietrwałe przechowywanie danych. Jeśli „baza danych” nie jest lokalna, to z perspektywy czystych mikrousług należy ją traktować jak osobną (mikro) usługę. W tym celu nigdy nie ma sensu, aby instancja RDS była „bazą danych” dla mikrousług. Ponownie, perspektywa nie polega na „grupie mikrousług z ich własnymi bazami danych RDS”, ale „grupie mikrousług, które komunikują się z bazami danych RDS”. W tym momencie nie ma znaczenia, czy dane są przechowywane w tej samej instancji bazy danych, czy nie.

Pragmatycznie architektura mikrousług powoduje ogromną złożoność. Ta złożoność to tylko cena poważnego radzenia sobie z częściową awarią. Dla wielu jest to przesada, która prawdopodobnie nie jest warta korzyści. Powinieneś swobodnie projektować swój system w jakikolwiek sposób, który wydaje się najbardziej korzystny. Istnieje duża szansa, że ​​obawy związane z prostotą i wydajnością mogą prowadzić do odchyleń od architektury czystej mikrousług. Kosztem będzie dodatkowe sprzężenie, które wprowadza własne złożoności, takie jak niewidoczne interakcje między usługami oraz ograniczenia swobody wdrażania i skalowania według własnego uznania.

Derek Elkins
źródło
„z powodu niemożności skontaktowania się z innymi mikrousługami”. - Myślałem, że Mikrousługi nigdy nie powinny kontaktować się z innymi mikrousługami?
Marc