Zdecentralizowane zarządzanie danymi - kapsułkowanie baz danych w mikrousługach [zamknięte]

23

Niedawno brałem udział w kursie na temat projektowania oprogramowania. Niedawno odbyła się dyskusja / zalecenie dotyczące zastosowania modelu „mikrousług”, w którym składniki usługi są podzielone na podskładniki mikrousług, które są możliwie najbardziej niezależne.

Jedną z wymienionych części było to, że zamiast postępować zgodnie z bardzo często obserwowanym modelem posiadania jednej bazy danych, z którą rozmawiają wszystkie mikrousługi, dla każdej z mikrousług miałbyś osobną bazę danych.

Lepsze sformułowanie i bardziej szczegółowe wyjaśnienie tego można znaleźć tutaj: http://martinfowler.com/articles/microservices.html w sekcji Zdecentralizowane zarządzanie danymi

najbardziej znacząca część mówi:

Mikrousługi preferują zezwalanie każdej usłudze na zarządzanie własną bazą danych, albo różnymi instancjami tej samej technologii baz danych, albo całkowicie różnymi systemami baz danych - podejście zwane trwałością Polyglot. Możesz użyć trwałości polyglot w monolicie, ale częściej pojawia się to w mikrousługach.

Rycina 4wprowadź opis zdjęcia tutaj

Podoba mi się ta koncepcja i, między innymi, postrzegam ją jako znaczną poprawę w zakresie konserwacji i posiadania projektów, w których pracuje wiele osób. To powiedziawszy, wcale nie jestem doświadczonym architektem oprogramowania. Czy ktoś kiedykolwiek próbował to wdrożyć? Na jakie korzyści i przeszkody wpadłeś?

ThinkBonobo
źródło
6
Nie jestem pewien, jak to pytanie jest poza zakresem dla programistów.stackexchange. Jest to pytanie o konkretną technikę oraz jej zalety i wady w celu ustalenia, kiedy użycie tej techniki jest uzasadnione. Obejrzałem prezentację i stronę z meta ( meta.stackexchange.com/questions/68384/… ). Czy możesz wyjaśnić, w jaki sposób powinienem poprawić pytanie?
ThinkBonobo,

Odpowiedzi:

35

Porozmawiajmy pozytywnie i negatywnie o podejściu mikrousługowym.

Pierwsze negatywy. Podczas tworzenia mikrousług dodajesz nieodłączną złożoność kodu. Dodajesz koszty ogólne. Utrudniasz replikację środowiska (np. Dla programistów). Utrudniasz debugowanie sporadycznych problemów.

Pozwól mi zilustrować prawdziwy minus. Rozważ hipotetycznie przypadek, w którym podczas generowania strony wywoływanych jest 100 mikrousług, z których każda robi właściwie 99,9% czasu. Ale w 0,05% przypadków dają one złe wyniki. I w 0,05% przypadków żądanie połączenia jest powolne, gdy, powiedzmy, wymagany jest limit czasu TCP / IP do nawiązania połączenia, co zajmuje 5 sekund. Około 90,5% czasu Twoje zapytanie działa idealnie. Ale w około 5% przypadków wyniki są błędne, a w około 5% przypadków strona jest powolna. I każda niepowtarzona powtórka ma inną przyczynę.

O ile nie zastanowisz się nad narzędziami do monitorowania, odtwarzania itp., Przerodzi się to w bałagan. Zwłaszcza gdy jedna mikrousługa wywołuje inną, która wywołuje kolejną głębokość kilku warstw. A gdy pojawią się problemy, z czasem będzie coraz gorzej.

OK, to brzmi jak koszmar (a więcej niż jedna firma stworzyła dla siebie ogromne problemy, idąc tą ścieżką). Sukces jest możliwy tylko wtedy, gdy wyraźnie zdajesz sobie sprawę z potencjalnego minusu i konsekwentnie pracujesz nad tym, aby go rozwiązać.

A co z tym monolitycznym podejściem?

Okazuje się, że aplikacja monolityczna jest tak samo łatwa do modularyzacji jak mikrousługi. A wywołanie funkcji jest zarówno tańsze, jak i bardziej niezawodne w praktyce niż wywołanie RPC. Możesz więc opracować to samo, z wyjątkiem tego, że jest bardziej niezawodny, działa szybciej i wymaga mniej kodu.

OK, więc dlaczego firmy wybierają podejście mikrousług?

Odpowiedź brzmi, ponieważ podczas skalowania istnieje ograniczenie tego, co można zrobić z aplikacją monolityczną. Po tylu użytkownikach, tylu żądaniach itd. Dochodzi się do punktu, w którym bazy danych nie skalują się, serwery WWW nie mogą przechowywać kodu w pamięci i tak dalej. Ponadto podejścia oparte na mikrousługach umożliwiają niezależne i przyrostowe aktualizacje aplikacji. Dlatego architektura mikrousług jest rozwiązaniem do skalowania aplikacji.

Moją osobistą zasadą jest to, że przejście od kodu w języku skryptowym (np. Python) do zoptymalizowanego C ++ ogólnie może poprawić 1-2 rzędy wielkości zarówno pod względem wydajności, jak i wykorzystania pamięci. Przejście do architektury rozproszonej zwiększa wymagania co do zasobów, ale umożliwia skalowanie w nieskończoność. Możesz sprawić, że architektura rozproszona będzie działać, ale jest to trudniejsze.

Dlatego powiedziałbym, że jeśli zaczynasz osobisty projekt, idź monolitycznie. Dowiedz się, jak to zrobić dobrze. Nie rozpowszechniaj, ponieważ (Google | eBay | Amazon | etc) są. Jeśli lądujesz w dużej firmie, która jest dystrybuowana, zwróć szczególną uwagę na to, jak działają, i nie spieprz tego. A jeśli skończysz z przejściem, bądź bardzo, bardzo ostrożny, ponieważ robisz coś trudnego, co łatwo jest bardzo, bardzo źle.

Ujawnienie, mam blisko 20-letnie doświadczenie w firmach każdej wielkości. I tak, widziałem zarówno monolityczne, jak i rozproszone architektury z bliska i osobiście. Opiera się na tym doświadczeniu, które mówię wam, że rozproszona architektura mikrousług jest naprawdę czymś, co robisz, ponieważ musisz, a nie dlatego, że jest w jakiś sposób czystsza i lepsza.

btilly
źródło
3
Niezwykle wnikliwa odpowiedź. Dziękujemy za przekazanie tej mądrości.
ThinkBonobo,
Oto ostatnie przemówienie Martina Fowlera (3.), które dotyczy kilku z tych kwestii.
Whymarrh
Czy istnieje sposób między monolitem a mikrousługami? Mam wielojęzyczną aplikację monolitu. Po pewnym czasie widzę, że powinienem podzielić na każdego najemcę. Każdy najemca powinien mieć własną instancję aplikacji, ale muszą udostępniać niektóre dane i musi to być pojedyncze / centralne miejsce. Mogę więc specjalnie dla tego utworzyć oddzielną usługę. Wygląda na to, że będę mieć kilka (nie tak mikro) aplikacji / usług. Czy robienie tego w ten sposób wydaje się rozsądne?
dariol,
@dariol Nie ma dobrej ścieżki uaktualnienia od monolitycznych do pełnych mikrousług poprzez środek „ładujemy wszędzie dużą wspólną bazę kodu, a następnie wykorzystujemy to, czego potrzebujemy”. Jednak rozsądne jest, aby zrobić to jako tymczasową łatkę, aby zaspokoić pilną potrzebę. A potem zacznij oddzielać prawdziwe mikrousługi, aż rdzeń będzie można wymienić. Powód, dla którego jest to trudne, ma związek z zarządzaniem zależnościami. Będziesz nadal bił: „Potrzebuję tego, ale to zależy od tego, zależy od tego… a teraz mam całą kulkę spaghetti”.
btilly,
Kolejny link Martina Fowlera na ten temat: Monolith First
driftcatcher
5

Z całego serca zgadzam się z odpowiedzią btilly, ale chciałem tylko dodać kolejny pozytyw dla Microservices, który moim zdaniem jest oryginalną inspiracją.

W świecie Microservices usługi są dostosowane do domen i są zarządzane przez oddzielne zespoły (jeden zespół może zarządzać wieloma usługami). Oznacza to, że każdy zespół może wydawać usługi całkowicie osobno i niezależnie od innych usług (przy założeniu prawidłowej wersji itp.).

Chociaż może się to wydawać trywialną korzyścią, rozważ przeciwnie w świecie monolitycznym. Tutaj, gdzie jedna część aplikacji musi być często aktualizowana, wpłynie to na cały projekt i wszelkie inne zespoły nad nim pracujące. Następnie trzeba wprowadzić harmonogram, recenzje itp., A cały proces zwalnia.

Jeśli chodzi o twój wybór, a także biorąc pod uwagę wymagania dotyczące skalowania, rozważ również wszelkie wymagane struktury zespołu. Zgadzam się z zaleceniem btilly, aby uruchomić Monolit, a następnie ustalić, gdzie mikrousługi mogą być korzystne, ale należy pamiętać, że skalowalność nie jest jedyną korzyścią.

PizzaTheHut
źródło
To prawda. Dalsza część artykułu dotyczy w szczególności tego, w jaki sposób zachęca do segmentacji według „możliwości biznesowych”. Jest to zdecydowanie kluczowa zaleta.
ThinkBonobo,
2

Pracowałem w miejscu, które miało sporo niezależnych źródeł danych. Umieścili je wszystkie w jednej bazie danych, ale w różnych schematach, do których dostęp miały usługi sieciowe. Chodziło o to, aby każda usługa miała dostęp tylko do minimalnej ilości danych wymaganych do wykonania pracy.

Nie było to duże obciążenie w porównaniu z monolityczną bazą danych, ale myślę, że było to głównie spowodowane charakterem danych, które były już w izolowanych grupach.

Usługi sieciowe zostały wywołane z kodu serwera WWW, który wygenerował stronę, więc jest to bardzo podobne do architektury mikrousług, choć być może nie jest tak mikro, jak sugeruje to słowo, i nie jest rozpowszechniane, chociaż mogły być (zauważ, że jeden WS wywołał aby uzyskać dane z usługi zewnętrznej, więc była tam 1 instancja rozproszonej usługi danych). Firma, która to zrobiła, była bardziej zainteresowana bezpieczeństwem niż skalą, jednak te usługi i usługi danych zapewniały bezpieczniejszą powierzchnię ataku, ponieważ nadająca się do wykorzystania wada w jednym nie dawała pełnego dostępu do całego systemu.

Roger Sessions w swoich doskonałych biuletynach Objectwatch opisał coś podobnego w swojej koncepcji Software Fortress (niestety biuletyny nie są już dostępne online, ale możesz kupić jego książkę).

gbjbaanb
źródło