Niedawno przeczytałem ten znakomity artykuł na temat architektury mikrousług: http://www.infoq.com/articles/microservices-intro
Stwierdza, że po załadowaniu strony internetowej na Amazon, ponad 100 mikrousług współpracuje w celu obsługi tej strony.
W tym artykule opisano, że cała komunikacja między mikrousługami może odbywać się wyłącznie za pośrednictwem interfejsu API. Moje pytanie brzmi: dlaczego tak źle jest powiedzieć, że wszystkie zapisy bazy danych mogą przechodzić tylko przez interfejs API, ale można czytać bezpośrednio z baz danych różnych mikrousług. Można na przykład powiedzieć, że tylko kilka widoków bazy danych jest dostępnych poza mikrousługą, dzięki czemu zespół obsługujący mikrousługę wie, że tak długo, jak utrzymują te widoki nienaruszone, mogą zmieniać strukturę bazy danych swojej mikro usługi chcieć.
Czy coś mi umyka? Czy istnieje jakiś inny powód, dla którego dane powinny być odczytywane tylko przez interfejs API?
Nie trzeba dodawać, że moja firma jest znacznie mniejsza niż Amazon (i zawsze będzie), a maksymalna liczba użytkowników, jaką możemy mieć, to około 5 milionów.
Odpowiedzi:
Bazy danych nie są zbyt dobre w ukrywaniu informacji, co jest całkiem prawdopodobne, ponieważ ich zadaniem jest ujawnianie informacji. Ale to czyni je kiepskim narzędziem, jeśli chodzi o enkapsulację. Dlaczego chcesz enkapsulacji?
Scenariusz: wiążesz kilka komponentów bezpośrednio z RDBMS i widzisz, że jeden konkretny komponent staje się „wąskim gardłem”, dla którego możesz chcieć denormalizować bazę danych, ale nie możesz tego zrobić, ponieważ wpłynęłoby to na wszystkie inne komponenty. Możesz nawet zdać sobie sprawę, że lepiej byłoby ze sklepem z dokumentami lub bazą danych grafów niż z RDBMS. Jeśli dane są enkapsulowane przez mały API, masz realistyczną szansę na reimplementację wspomnianego API w dowolny sposób. Możesz przezroczyście wstawiać warstwy pamięci podręcznej, a co nie.
Grzebanie w warstwie magazynującej bezpośrednio z warstwy aplikacyjnej jest diametralnym przeciwieństwem tego, co sugeruje zasada inwersji zależności .
źródło
Co jest ważniejsze i ważniejsze w mikroserwisie: jego interfejs API lub schemat bazy danych? API, ponieważ taka jest jego umowa z resztą świata. Schemat bazy danych jest po prostu wygodnym sposobem przechowywania danych zarządzanych przez usługę, miejmy nadzieję zorganizowanym w sposób optymalizujący wydajność mikrousług. Zespół programistów powinien mieć swobodę reorganizacji tego schematu - lub przejścia na zupełnie inne rozwiązanie magazynu danych - w dowolnym momencie. Reszta świata nie powinna się tym przejmować. Reszta świata dba o zmiany API, ponieważ API jest umową.
Teraz, jeśli zajrzysz do ich bazy danych
Dwa ostatnie punkty mogą się nie zdarzyć, jeśli masz dostęp tylko do odczytu, ale pozostałe punkty to więcej niż wystarczający powód. Współużytkowane bazy danych to zła rzecz.
Mniej doświadczeni programiści (lub ci, którzy się nie uczą) często postrzegają bazę danych jako ważniejszą od usługi, postrzegają bazę danych jako prawdziwą rzecz, a usługa tylko sposobem na dotarcie do niej. To jest odwrotna sytuacja.
źródło
Architektura Microservice jest trudna do opisania, ale najlepszym sposobem na jej rozważenie jest połączenie architektury zorientowanej na komponenty i architektury zorientowanej na usługi. Oprogramowanie jako pakiet składa się z wielu komponentów dla małych firm z bardzo specyficzną odpowiedzialnością domeny biznesowej. Ich interfejs do świata zewnętrznego w ramach świadczonych usług lub wymaganych usług odbywa się za pośrednictwem interfejsu API jasno określonych usług.
Pisanie do, a nawet czytanie z bazy danych znajdującej się poza domeną biznesową komponentów jest niezgodne z tym stylem architektury.
Głównym tego powodem jest to, że interfejs API dostarczany za pośrednictwem usługi przez inny komponent oprogramowania ma uzasadnione oczekiwania, że interfejs API najprawdopodobniej będzie kompatybilny wstecz, gdy pojawią się nowe wersje komponentu świadczącego usługę. Jeśli jestem programistą komponentu „zapewniającego”, muszę się tylko martwić kompatybilnością wsteczną z moim interfejsem API. Jeśli wiem, że istnieją trzy inne zespoły programistów, które pisały niestandardowe zapytania bezpośrednio do mojej bazy danych, moja praca stała się znacznie bardziej skomplikowana.
Co gorsza, być może ten inny zespół, który to napisał, jest w trakcie sprintu w krytycznym projekcie i nie może teraz zaakceptować tej zmiany z twojego komponentu. Teraz rozwój oprogramowania dla twojego komponentu w domenie biznesowej, którą posiadasz, jest napędzany przez rozwój w innej domenie biznesowej.
Pełna interakcja za pośrednictwem usług zmniejsza sprzężenie między różnymi komponentami oprogramowania, więc takie sytuacje nie występują tak często. Jeśli chodzi o inne komponenty korzystające z widoku w bazie danych, masz większą możliwość, aby widok był kompatybilny wstecz, jeśli ktoś napisałby przeciwko niemu zapytania. Nadal uważam jednak, że powinien to być wyjątek i należy to zrobić tylko w przypadku raportowania lub przetwarzania wsadowego, w którym aplikacja będzie musiała odczytać ogromne ilości danych.
Oczywiście działa to dobrze w dużych rozproszonych zespołach, w których zespoły programistyczne są oddzielone przez domenę biznesową, taką jak Amazon. Jeśli jesteś małym sklepem programistycznym, nadal możesz skorzystać z tego modelu, zwłaszcza jeśli chcesz szybko przygotować się do dużego projektu, ale także, jeśli masz do czynienia z oprogramowaniem dostawcy.
źródło
W ciągu ostatnich 20 lat widziałem kilka dużych modułowych projektów baz danych i widziałem scenariusz sugerowany przez Davida już kilka razy, w którym aplikacje mają dostęp do zapisu do własnego schematu / zestawu tabel i dostęp do odczytu do innego schematu / zestaw tabel. Najczęściej te dane, do których aplikacja / moduł uzyskuje dostęp tylko do odczytu, można opisać jako „dane podstawowe” .
W tym czasie nie widziałem problemów, które sugerują wcześniejsze odpowiedzi, powinienem był je zobaczyć, dlatego uważam, że warto przyjrzeć się bardziej szczegółowo kwestiom poruszonym w poprzednich odpowiedziach.
Zgadzam się z tym komentarzem, z wyjątkiem tego, że jest to również argument za lokalną kopią danych do odczytania przez mikrousługę. Oznacza to, że większość dojrzałych baz danych obsługuje replikację, więc bez wysiłku programisty „dane podstawowe” można fizycznie replikować do bazy danych mikrousług, jeśli jest to pożądane lub potrzebne.
Niektórzy mogą rozpoznać to w starszych postaciach jako „korporacyjna baza danych” replikująca podstawowe tabele do „departamentalnej bazy danych”. Chodzi o to, że ogólnie dobrze jest, jeśli baza danych robi to za nas z wbudowaną replikacją zmienionych danych (tylko delty, w formie binarnej i przy minimalnym koszcie do źródłowej bazy danych).
I odwrotnie, gdy nasze wybory bazy danych nie pozwalają na tę „gotową” obsługę replikacji, możemy przejść do sytuacji, w której chcemy wypchnąć „dane podstawowe” do baz danych mikrousług, co może spowodować znaczny wysiłek programisty i być również znacznie mniej wydajnym mechanizmem.
Dla mnie to stwierdzenie jest po prostu nieprawidłowe. Denormalizacja jest zmianą „addytywną”, a nie „przełomową” i żadna aplikacja nie powinna ulec awarii z powodu denormalizacji.
Jedynym sposobem, w jaki ta przerwa aplikacji jest, gdy kod aplikacji używa czegoś takiego jak „wybierz * ...” i nie obsługuje dodatkowej kolumny. Dla mnie to byłby błąd w aplikacji?
Jak denormalizacja może uszkodzić aplikację? Dla mnie to brzmi jak FUD.
Tak, aplikacja jest teraz zależna od schematu bazy danych i implikuje to, że powinien to być poważny problem. Chociaż dodanie jakiejkolwiek dodatkowej zależności jest oczywiście nie idealne, moim doświadczeniem jest to, że zależność od schematu bazy danych nie była problemem, więc dlaczego tak może być? Czy właśnie miałem szczęście?
Dane podstawowe
Schemat, do którego zazwyczaj możemy chcieć, aby mikrousługa miała dostęp tylko do odczytu, jest najczęściej określany jako „ dane podstawowe ” dla przedsiębiorstwa. Ma podstawowe dane, które są niezbędne dla przedsiębiorstwa.
Historycznie oznacza to, że schemat, od którego dodajemy zależność, jest zarówno dojrzały, jak i stabilny (nieco fundamentalny dla przedsiębiorstwa i niezmienny).
Normalizacja
Jeśli 3 projektantów baz danych pójdzie i zaprojektuje znormalizowany schemat db, otrzymają ten sam projekt. Ok, może być jakieś odmiany 4NF / 5NF, ale niewiele. Co więcej, istnieje szereg pytań, które projektant może zadać w celu walidacji modelu, aby projektant mógł mieć pewność, że dotarł do 4NF (czy jestem zbyt optymistyczny? Czy ludzie mają trudności z dostaniem się do 4NF?).
aktualizacja: Przez 4NF tutaj mam na myśli, że wszystkie tabele w schemacie osiągnęły najwyższą normalną formę do 4NF (wszystkie tabele zostały odpowiednio znormalizowane do 4NF).
Wierzę, że proces projektowania normalizacji jest powodem, dla którego projektanci baz danych są ogólnie zadowoleni z idei polegania na znormalizowanym schemacie bazy danych.
Proces normalizacji przenosi projekt DB do znanego „poprawnego” projektu, a zmiany z niego powinny być denormalizacją pod względem wydajności.
Gdyby 3 programistów dostało projekt do wdrożenia (jako kod), oczekiwane byłyby 3 różne implementacje (potencjalnie bardzo różne).
Dla mnie potencjalnie jest kwestia „wiary w normalizację”.
Łamanie zmian schematu?
Denormalizacja, dodawanie kolumn, zmiana kolumn w celu zwiększenia przestrzeni dyskowej, rozszerzenie projektu o nowe tabele itp. To niezłomne zmiany, a projektanci DB, którzy osiągnęli normalną 4 klasę, będą tego pewni.
Przerwanie zmian jest oczywiście możliwe przez upuszczenie kolumn / tabel lub zmianę typu podziału. Możliwe, że tak, ale w praktyce nie spotkałem tu żadnych problemów. Być może dlatego, że zrozumiano, jakie są przełomowe zmiany i że zostały one dobrze zarządzane?
Chciałbym usłyszeć przypadki łamania zmian schematu w kontekście wspólnych schematów tylko do odczytu.
Chociaż zgadzam się z tym stwierdzeniem, myślę, że istnieje ważne zastrzeżenie, które moglibyśmy usłyszeć od architekta korporacyjnego: „Dane żyją wiecznie” . Oznacza to, że chociaż API może być najważniejszą rzeczą, dane są również dość ważne dla całego przedsiębiorstwa i będą ważne przez bardzo długi czas.
Na przykład, gdy istnieje potrzeba zapełnienia hurtowni danych dla analizy biznesowej, wówczas schemat i obsługa CDC stają się ważne z perspektywy raportowania biznesowego, niezależnie od interfejsu API.
Masz problemy z interfejsami API?
Teraz, gdyby interfejsy API były idealne i łatwe, wszystkie punkty są dyskusyjne, ponieważ zawsze wybieramy interfejs API, a nie lokalny dostęp tylko do odczytu. Motywacją nawet do rozważenia lokalnego dostępu tylko do odczytu jest to, że mogą wystąpić pewne problemy z używaniem interfejsów API, których unika dostęp lokalny.
Optymalizacja API:
LinkedIn ma ciekawą prezentację (od 2009 r.) Na temat optymalizacji API i dlaczego jest dla nich ważna na ich skalę. http://www.slideshare.net/linkedin/building-consistent-restful-apis-in-a-highperformance-environment
Krótko mówiąc, gdy interfejs API musi obsługiwać wiele różnych przypadków użycia, może łatwo przejść do sytuacji, w której obsługuje jeden przypadek użycia optymalnie, a pozostałe dość słabo z perspektywy sieci i bazy danych.
Jeśli interfejs API nie ma takiego samego wyrafinowania jak LinkedIn, możesz łatwo uzyskać scenariusze, w których:
Tak, możemy oczywiście dodać buforowanie do API, ale ostatecznie wywołanie API jest wywołaniem zdalnym i istnieje szereg optymalizacji dostępnych dla programistów, gdy dane są lokalne.
Podejrzewam, że istnieje grupa ludzi, którzy mogliby to dodać:
Ta odpowiedź jest zdecydowanie za długa. Przeprosiny!!
źródło
Zarządzanie stanem (potencjalnie bazą danych) można wdrożyć w kontenerze Microservice i udostępnić za pośrednictwem interfejsu API. Baza danych Microservice nie jest widoczna dla innych systemów poza kontenerem - tylko API. Alternatywnie możesz mieć inną usługę (np. Pamięć podręczną) zarządzać stanem za pośrednictwem interfejsu API. Kluczową różnicą w architekturze jest posiadanie wszystkich zależności Microservice (innych niż wywołania API do innych usług) w jednym przenośnym kontenerze. Jeśli tego nie dostaniesz, wróć i przestudiuj architekturę.
źródło