Aplikacja multi tenant

Wprowadzenie

Większość aplikacji, jakie tworzymy, to tak zwane aplikacje single tenant. Czyli mamy jedną instancję aplikacji dla pojedynczego klienta/firmy/organizacji, lub w ogóle nie myślimy o takich rzeczach na poziomie samej aplikacji. Gdy pojawia się druga firma, to po prostu stawiamy dla niej nową instancję i wszyscy są zadowoleni.

Są natomiast sytuacje, w których taki model działania aplikacji nie sprawdzi się. Na przykład w aplikacjach SaaS (software as a service) stawianie dla każdego klienta nowej/dedykowanej instancji aplikacji może okazać się nieefektywne. W takich sytuacjach aplikacja multi tenant może okazać się dużo lepszym rozwiązaniem.

Tym wpisem chciałbym zacząć mini serię wpisów na blogu na temat tworzenia aplikacji multi tenant w .NET. W najbliższych tygodniach będzie pojawiać się więcej wpisów, pokazujących tworzenie kolejnych elementów aplikacji multi tenant.

Czym jest aplikacja multi tenant?

W aplikacji single tenant, jak wspomniałem we wstępie, każdy klient ma swoją dedykowaną instancję aplikacji. Można to przedstawić na schemacie (ikona użytkownika symbolizuje klienta/firmę/organizację/tenanta):

Podejście single tenant

Natomiast w aplikacji multi tenant z jednej instancji użytkowników korzysta wielu klientów, gdzie nawet często dane wszystkich organizacji znajdują się w tej samej bazie danych:

Podejście multi tenant z jedną bazą danych.

W podejściu multi tenant pojawia się pojęcie organizacji (tenant), która grupuje dane oraz operacje w aplikacji w niezależne byty. Tak jak na przykład w Azure DevOps po zalogowaniu się, musimy w pierwszej kolejności wybrać organizację, w ramach której chcemy aktualnie pracować. Zmiany w konfiguracji jednej organizacji nie wypływają na działanie innej organizacji.

Pod spodem wykorzystywany jest katalog (np. dedykowana baza danych), w której znajdują się informacje o wszystkich organizacjach/tenantach w aplikacji i użytkownikach do nich przypisanych. Później dodanie nowej organizacji sprowadza się bardzo często do dodania informacji o niej w katalogu bez konieczności wykonywania operacji w samej infrastrukturze aplikacji – na przykład stawiania nowego App Service w Azure.

Darmowy kurs Visual Studio

Pracując z setkami programistów, zauważyłem, że większość osób nie pracuje efektywnie w Visual Studio. W skrajnych przypadkach korzystali z kopiowania z wykorzystaniem menu Edit. Wiem, że to dziwne, ale naprawdę niektórzy tak pracują. Dlatego postanowiłem stworzyć kurs Visual Studio – aby pomóc koleżankom i kolegom w efektywniejszej pracy.

Przygotowałem 30 lekcji e-mail, w których pokażę Ci, w jaki sposób pracować efektywniej i szybciej w Visual Studio. Poznasz dodatki, bez których nie wyobrażam sobie pracy w tym IDE.

Po więcej informacji zapraszam na dedykowaną stronę kursu: Darmowy Kurs Visual Studio.

Quiz C#

Ostatnio przygotowałem również quiz C#, w którym możesz sprawdzić swoją wiedzę. Podejmiesz wyzwanie?

Plusy aplikacji multi tenant

Jak to w życiu bywa plusy i minusy jakiegoś rozwiązania są mocno subiektywne i zależą od konkretnej sytuacji. Dlatego jakiś plus w niektórych sytuacjach może się okazać minusem. Poniżej lista plusów (a jeszcze niżej lista minusów) podejścia multi tenant. W zależności od konkretnego sposobu implementacji aplikacji multi tenant może się okazać, że poszczególne punkty będą przechodzić z plusów do minusów i na odwrót.

Poniżej moja lista plusów i minusów podejścia multi tenant.

Koszty działania

Jednym z plusów działania aplikacji w modelu multi tenant jest maksymalizacja wykorzystywanych zasobów, a co za tym idzie obniżenie kosztów działania aplikacji. W aplikacji single tenant na ogół każda z aplikacji ma swoje dedykowane zasoby – na przykład baza danych, App Service Plan, maszyna wirtualna, czy nawet fizyczny serwer.

W sytuacji gdy aplikacja ma małe obciążenie, może się okazać, że większość zasobów jest niewykorzystywana, a w wielu przypadkach (np. w przypadku chmury) musimy płacić za czas działania, czy gotowości zasobu niezależnie od tego, czy jest wykorzystywany, czy nie. Czym więcej różnych zasobów wykorzystujemy, tym większy jest koszt działania pojedynczej instancji aplikacji.

Natomiast w aplikacji multi tenant, z racji tego, że mamy jedną instancję aplikacji, możemy te same zasoby wykorzystywać dla wszystkich organizacji. Co sprowadza się do tego, że często na przykład jedna maszyna wirtualna jest w stanie obsłużyć wiele organizacji. Gdzie w podejściu single tenant mielibyśmy wiele maszyn – jedną per organizacja. W multi tenant dodajemy nowe zasoby w momencie, gdy zaczyna nam ich brakować. A nie w sytuacji, gdy dodajemy nową organizację.

Dzięki temu jesteśmy w stanie zaoszczędzić pieniądze, bo na przykład wystarczy nam jedna trochę mocniejsza maszyna (np. za 100$), zamiast 10 mniejszych maszyn (za 50$) per organizacja. Czym więcej różnych zasobów w aplikacji wykorzystujemy, tym większa może być różnica w kosztach.

Oczywiście część zasobów jesteśmy w stanie łatwo i bez dodatkowej pracy współdzielić w podejściu single tenant. Na przykład w Azure na jeden App Service Plan możemy wdrożyć wiele aplikacji i w ten sposób zmaksymalizować zużycie zasobów, ale nie wszystkie zasoby jesteśmy w stanie w ten sposób łatwo współdzielić.

Łatwość utrzymania

Kolejnym plusem aplikacji multi tenant jest jej łatwiejsze utrzymanie. Mam tutaj na myśli to, że mamy jedną instancję aplikacji zamiast wielu. Więc na przykład wdrożenie nowej wersji aplikacji jest łatwiejsze, bo robimy to raz na jednej instancji zamiast wiele razy. Oczywiście ma to też swoje minusy, ale o tym w kolejnej sekcji.

Również monitorowanie działania aplikacji jest łatwiejsze. Nie musimy sprawdzać wielu aplikacji, czy w jakiś sposób agregować informacji. Reagowanie na problemy jest również łatwiejsze, bo nie musimy szukać jakiej instancji aplikacji dotyczy problem.

W efekcie łatwość utrzymania powoduje również mniejsze koszty utrzymania aplikacji.

Łatwiejsze wdrażanie nowych organizacji

W przypadku aplikacji single tenant na ogół uruchomienie aplikacji dla nowego klienta/organizacji zajmuje trochę czasu. Oczywiście przy większej ilości organizacji można próbować automatyzować ten proces (np. korzystając z infrastructure as a code). Ale prawie zawsze będzie to jakiś większy lub mniejszy narzut.

Natomiast w przypadku aplikacji multi tenant dodanie nowej organizacji może sprowadzać się do dodania kilku rekordów w bazie danych. Szczególnie gdy zastosujemy podejście z jedną bazą danych.

Większa wydajność per organizacja

Związku z tym, że w podejściu multi tenant łączymy zasoby we wspólną pulę, to bardzo często okazuje się, że udaje nam się osiągnąć większą wydajność/szybkość działania aplikacji per tenant. Na ogół poszczególne organizacje w różny sposób wykorzystują aplikację. Dzięki wspólnym zasobom, takie niewykorzystane moce są pożytkowane przez pozostałe organizacje, gdy przy izolowanych zasobach taka moc by się marnowała.

Tak jak pisałem wyżej, w niektórych sytuacjach jesteśmy to w stanie osiągnąć bez konieczności tworzenia aplikacji multi tenant (np. poprzez współdzielenie App Service Plan).

Z drugiej strony ten plus może być również minusem. Szczególnie w przypadku, gdy jedna z organizacji zaczyna wykorzystywać ponadprzeciętną ilość zasobów – patrz minus „uciążliwy sąsiad”.

Minusy podejścia multi tenant

Większy koszt tworzenia aplikacji

Jednym z największych minusów podejścia multi tenant jest dodatkowy narzut związany z rozwojem aplikacji. W zależności od konkretnego podejścia ten narzut może być większy (np. jedna baza danych) lub mniejszy (np. dedykowane bazy danych).

Z jednej strony mamy obsługę katalogu z organizacjami/tenantami, czyli czegoś, czego w ogóle nie ma w aplikacji single tenant. Z drugiej strony w samej aplikacji musimy w jakiś sposób poprawnie obsługiwać kontekst danego tenanta.

Na przykład w podejściu z dedykowaną bazą danych dla jednego tenanta wystarczy tylko na początku obsługi żądania odpowiednio zbudować connection stringa do bazy. Nie jest to jakoś mocno skomplikowane czy czasochłonne. Natomiast w podejściu z jedną bazą ten narzut na ogół będzie już znaczny.

Dlatego może nie zawsze warto od razu myśleć o tym, aby nasza aplikacja była multi tenant. Szczególnie w sytuacji, gdy nie mamy pewności, czy w ogóle to kiedyś wykorzystamy.

Więcej testów

Minus ten podlega pod zwiększony koszt tworzenia aplikacji, ale chciałem to dodatkowo zaznaczyć. Szczególnie, że to bardzo ważny aspekt.

W przypadku aplikacji multi tenant mamy dodatkową grupę testów, w ramach której upewniamy się, czy nie następuje wymieszanie się danych między organizacjami. Jest to bardzo ważne, bo myślę, że jednym z największych problemów, jakie możemy mieć w aplikacji, jest to, że jedna organizacja widzi dane innej organizacji. Taka sytuacja w dobie RODO i innych tego typu regulacji może nas bardzo dużo kosztować.

Szczególnie ten rodzaj testów jest bardzo ważny, w przypadku gdy wykorzystujemy podejście z jedną bazą, gdzie każdy z rekordów w tabelach jest przypisany do jakieś organizacji (np. poprzez kolumnę TenantId). Wcześniej czy później zdarzy nam się pominąć warunek z TenantId, a lepiej, aby ten problem został wyłapany podczas testów, a nie przez klienta na produkcji.

Uciążliwy sąsiąd

Jak wspominałem przy plusach, czasami może się okazać, że niektóre organizacje wykorzystują ponadprzeciętną ilość zasobów. Niestety przy wspólnych zasobach może się okazać, że zacznie to wpływać na pozostałe organizacje. Czyli mamy tak zwanego uciążliwego sąsiada.

W takiej sytuacji musimy pomyśleć o jakichś sposobach limitowania zasobów lub priorytetowania zadań innych organizacji, aby nie okazało się, że na przykład w kolejce kolejne 100k wiadomości dotyczy tylko jednej organizacji. A to wpłynie negatywnie na działanie innych organizacji w naszym systemie.

Trudniejsze udostępnianie nowej wersji dla wybranych organizacji

Z racji tego, że mamy jedną instancję aplikacji może się okazać, że będzie nam trudniej udostępnić nowe wersje aplikacji pojedynczym organizacją.

Bardzo często zdarza się tak, że mamy zaprzyjaźnionych klientów, którzy są bardziej tolerancyjni na jakieś błędy i którzy mogą być naszymi beta testerami nowszych wersji aplikacji. W przypadku aplikacji single tenant wystarczy wdrożyć nową wersję aplikacji na ich dedykowane środowisko, a gdy dadzą nam zielone światło, możemy wdrażać aplikację pozostałym organizacjom.

W przypadku aplikacji multi tenant jest to trudniejsze. Możemy oczywiście zaimplementować podejście feature switch, które umożliwia uruchamianie funkcjonalności poszczególnym organizacjom, ale to zawsze jakiś dodatkowy narzut.

Możemy również posiadać dwie instancje aplikacji – z aktualną wersją aplikacji i nowszą. A następnie na poziomie jakiegoś application gateway odpowiednio kierować ruch na podstawie TenantId, jednak to również powoduje kolejne problemy.

Brak lub trudniejsze dostosowanie aplikacji pod organizację

Podobnie jak w przypadku udostępniania nowych wersji, tak i dostosowanie aplikacji pod pojedyncze organizacje w podejściu multi tenant jest bardziej utrudnione. Można wykorzystać wspomniane wcześniej feature switch, ale w praktyce bardzo często rezygnuje się z tego elementu.

W przypadku single tenant na ogół wystarczyło utworzyć dedykowany branch, w którym nanieślibyśmy dedykowane zmiany. Oczywiście to podejście ma swoje problemy, ale w początkowej fazie rozwoju projektu zdecydowanie jest wystarczające.

Podsumowanie

W tym wpisie skupiłem się na wprowadzeniu w tematykę tworzenia aplikacji multi tenant. Głównie pokazałem różne plusy i minusy tego podejścia w stosunku do klasycznego podejścia single tenant. W kolejnych wpisach z tej mini serii zajmiemy się już poszczególnymi aspektami tworzenia aplikacji multi tenant z przykładami w .NET 5.

Szkolenie modularny monolit w .NET 5

Szkolenie modularny monolit w .NET 5

Zainteresował Ciebie ten temat? A może chcesz więcej? Jak tak to zapraszam na moje autorskie szkolenie o modularnym monolicie w .NET.

3 thoughts on “Aplikacja multi tenant

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.