Skalowanie w usłudze Service Fabric

Usługa Azure Service Fabric ułatwia tworzenie skalowalnych aplikacji przez zarządzanie usługami, partycjami i replikami w węzłach klastra. Uruchamianie wielu obciążeń na tym samym sprzęcie umożliwia maksymalne wykorzystanie zasobów, ale także zapewnia elastyczność w zakresie sposobu skalowania obciążeń. W tym filmie wideo z kanałem Channel 9 opisano sposób tworzenia skalowalnych aplikacji mikrousług:

Skalowanie w usłudze Service Fabric odbywa się na kilka różnych sposobów:

  1. Skalowanie przez utworzenie lub usunięcie wystąpień usługi bezstanowej
  2. Skalowanie przez utworzenie lub usunięcie nowych nazwanych usług
  3. Skalowanie przez utworzenie lub usunięcie nowych nazwanych wystąpień aplikacji
  4. Skalowanie przy użyciu usług partycjonowanych
  5. Skalowanie przez dodawanie i usuwanie węzłów z klastra
  6. Skalowanie przy użyciu metryk Resource Manager klastra

Skalowanie przez utworzenie lub usunięcie wystąpień usługi bezstanowej

Jednym z najprostszych sposobów skalowania w ramach usługi Service Fabric działa z usługami bezstanowymi. Podczas tworzenia usługi bezstanowej możesz zdefiniować element InstanceCount. InstanceCount Określa liczbę uruchomionych kopii kodu tej usługi tworzonych podczas uruchamiania usługi. Załóżmy na przykład, że w klastrze znajduje się 100 węzłów. Załóżmy również, że usługa jest tworzona z wartością InstanceCount 10. W czasie wykonywania te 10 uruchomionych kopii kodu może stać się zbyt zajęte (lub nie może być wystarczająco zajęte). Jednym ze sposobów skalowania tego obciążenia jest zmiana liczby wystąpień. Na przykład część kodu monitorowania lub zarządzania może zmienić istniejącą liczbę wystąpień na 50 lub 5, w zależności od tego, czy obciążenie musi być skalowane w poziomie na podstawie obciążenia.

C#:

StatelessServiceUpdateDescription updateDescription = new StatelessServiceUpdateDescription(); 
updateDescription.InstanceCount = 50;
await fabricClient.ServiceManager.UpdateServiceAsync(new Uri("fabric:/app/service"), updateDescription);

Program PowerShell:

Update-ServiceFabricService -Stateless -ServiceName $serviceName -InstanceCount 50

Używanie dynamicznej liczby wystąpień

W szczególności w przypadku usług bezstanowych usługa Service Fabric oferuje automatyczny sposób zmiany liczby wystąpień. Dzięki temu usługa może dynamicznie skalować się z liczbą dostępnych węzłów. Sposobem wyrażenia zgody na to zachowanie jest ustawienie liczby wystąpień = -1. InstanceCount = -1 to instrukcja usługi Service Fabric z informacją "Uruchom tę usługę bezstanową na każdym węźle". Jeśli liczba węzłów ulegnie zmianie, usługa Service Fabric automatycznie zmienia liczbę wystąpień tak, aby odpowiadała, upewniając się, że usługa jest uruchomiona na wszystkich prawidłowych węzłach.

C#:

StatelessServiceDescription serviceDescription = new StatelessServiceDescription();
//Set other service properties necessary for creation....
serviceDescription.InstanceCount = -1;
await fc.ServiceManager.CreateServiceAsync(serviceDescription);

Program PowerShell:

New-ServiceFabricService -ApplicationName $applicationName -ServiceName $serviceName -ServiceTypeName $serviceTypeName -Stateless -PartitionSchemeSingleton -InstanceCount "-1"

Skalowanie przez utworzenie lub usunięcie nowych nazwanych usług

Nazwane wystąpienie usługi jest konkretnym wystąpieniem typu usługi (zobacz cykl życia aplikacji usługi Service Fabric) w obrębie niektórych nazwanych wystąpień aplikacji w klastrze.

Nowe nazwane wystąpienia usługi można tworzyć (lub usuwać), ponieważ usługi stają się mniej lub bardziej zajęte. Dzięki temu żądania mogą być rozmieszczone w większej liczbie wystąpień usługi, co zwykle pozwala zmniejszyć obciążenie istniejących usług. Podczas tworzenia usług klaster usługi Service Fabric Resource Manager umieszcza usługi w klastrze w sposób rozproszony. Dokładne decyzje są zależne od metryk w klastrze i innych reguł umieszczania. Usługi można utworzyć na kilka różnych sposobów, ale najczęściej są to akcje administracyjne, takie jak wywołanie New-ServiceFabricServicemetody , lub przez kod wywołujący CreateServiceAsyncmetodę . CreateServiceAsync można nawet wywołać z poziomu innych usług uruchomionych w klastrze.

Dynamiczne tworzenie usług może być używane w różnych scenariuszach i jest typowym wzorcem. Rozważmy na przykład usługę stanową reprezentującą określony przepływ pracy. Wywołania reprezentujące pracę będą wyświetlane w tej usłudze, a ta usługa wykona kroki dla tego przepływu pracy i zarejestruje postęp.

Jak utworzyć tę konkretną skalę usług? Usługa może być wielodostępna w jakiejś formie i akceptować wywołania i uruchamiać kroki dla wielu różnych wystąpień tego samego przepływu pracy jednocześnie. Jednak może to sprawić, że kod będzie bardziej złożony, ponieważ teraz musi martwić się o wiele różnych wystąpień tego samego przepływu pracy, na różnych etapach i od różnych klientów. Ponadto obsługa wielu przepływów pracy w tym samym czasie nie rozwiązuje problemu ze skalowaniem. Dzieje się tak, ponieważ w pewnym momencie ta usługa będzie zużywać zbyt wiele zasobów, aby zmieścić się na określonej maszynie. Wiele usług, które nie zostały utworzone dla tego wzorca, również doświadcza trudności z powodu niektórych z natury wąskich gardeł lub spowolnienia w kodzie. Tego typu problemy powodują, że usługa nie działa, gdy liczba przepływów pracy współbieżnych, które śledzi, staje się większa.

Rozwiązaniem jest utworzenie wystąpienia tej usługi dla każdego innego wystąpienia przepływu pracy, które chcesz śledzić. Jest to doskonały wzorzec i działa niezależnie od tego, czy usługa jest bezstanowa, czy stanowa. Aby ten wzorzec działał, zazwyczaj istnieje inna usługa, która działa jako "Usługa menedżera obciążeń". Zadaniem tej usługi jest odbieranie żądań i kierowanie tych żądań do innych usług. Menedżer może dynamicznie utworzyć wystąpienie usługi obciążenia po odebraniu komunikatu, a następnie przekazać żądania do tych usług. Usługa menedżera może również odbierać wywołania zwrotne, gdy dana usługa przepływu pracy ukończy swoje zadanie. Gdy menedżer odbierze te wywołania zwrotne, może usunąć to wystąpienie usługi przepływu pracy lub pozostawić je, jeśli oczekuje się więcej wywołań.

Zaawansowane wersje tego typu menedżera mogą nawet tworzyć pule usług, którymi zarządza. Pula pomaga upewnić się, że gdy pojawi się nowe żądanie, nie musi czekać na uruchomienie usługi. Zamiast tego menedżer może po prostu wybrać usługę przepływu pracy, która nie jest obecnie zajęta z puli lub losowo kierować. Utrzymywanie dostępnej puli usług sprawia, że obsługa nowych żądań jest szybsza, ponieważ jest mniej prawdopodobne, że żądanie musi czekać na wznowienie nowej usługi. Tworzenie nowych usług jest szybkie, ale nie bezpłatne ani natychmiastowe. Pula pomaga zminimalizować czas oczekiwania żądania przed jego obsługą. Ten wzorzec menedżera i puli często jest widoczny, gdy czasy odpowiedzi mają największe znaczenie. Kolejkowanie żądania i tworzenie usługi w tle, a następnie przekazywanie jej w tle jest również popularnym wzorcem menedżera, ponieważ tworzy i usuwa usługi na podstawie pewnego śledzenia ilości pracy, która obecnie ma oczekujące usługi.

Skalowanie przez utworzenie lub usunięcie nowych nazwanych wystąpień aplikacji

Tworzenie i usuwanie całych wystąpień aplikacji jest podobne do wzorca tworzenia i usuwania usług. W przypadku tego wzorca istnieje pewna usługa menedżera, która podejmuje decyzję na podstawie żądań, które widzi, i informacji, które otrzymuje od innych usług wewnątrz klastra.

Kiedy należy utworzyć nowe nazwane wystąpienie aplikacji, zamiast tworzyć nowe nazwane wystąpienia usługi w niektórych już istniejących aplikacjach? Istnieje kilka przypadków:

  • Nowe wystąpienie aplikacji jest przeznaczone dla klienta, którego kod musi działać w ramach określonych ustawień tożsamości lub zabezpieczeń.
    • Usługa Service Fabric umożliwia definiowanie różnych pakietów kodu do uruchamiania w ramach określonych tożsamości. Aby uruchomić ten sam pakiet kodu w ramach różnych tożsamości, aktywacje muszą być wykonywane w różnych wystąpieniach aplikacji. Rozważmy przypadek, w którym wdrożono obciążenia istniejącego klienta. Mogą one działać w ramach określonej tożsamości, dzięki czemu można monitorować i kontrolować ich dostęp do innych zasobów, takich jak zdalne bazy danych lub inne systemy. W takim przypadku, gdy nowy klient zarejestruje się, prawdopodobnie nie chcesz aktywować kodu w tym samym kontekście (obszar procesu). Chociaż można, utrudnia to kodowi usługi działanie w kontekście określonej tożsamości. Zazwyczaj trzeba mieć więcej zabezpieczeń, izolacji i kodu zarządzania tożsamościami. Zamiast używać różnych nazwanych wystąpień usługi w ramach tego samego wystąpienia aplikacji, dlatego w tym samym obszarze procesu można użyć różnych wystąpień aplikacji usługi Service Fabric. Ułatwia to definiowanie różnych kontekstów tożsamości.
  • Nowe wystąpienie aplikacji służy również jako środek konfiguracji
    • Domyślnie wszystkie nazwane wystąpienia usługi określonego typu usługi w ramach wystąpienia aplikacji będą uruchamiane w tym samym procesie na danym węźle. Oznacza to, że chociaż każde wystąpienie usługi można skonfigurować inaczej, jest to skomplikowane. Usługi muszą mieć token, którego używają, aby wyszukać konfigurację w pakiecie konfiguracji. Zazwyczaj jest to tylko nazwa usługi. Działa to dobrze, ale łączy konfigurację z nazwami poszczególnych nazwanych wystąpień usługi w ramach tego wystąpienia aplikacji. Może to być mylące i trudne do zarządzania, ponieważ konfiguracja jest zwykle artefaktem czasu projektowania z wartościami specyficznymi dla wystąpienia aplikacji. Tworzenie większej liczby usług zawsze oznacza więcej uaktualnień aplikacji, aby zmienić informacje w pakietach konfiguracji lub wdrożyć nowe, aby nowe usługi mogły wyszukać określone informacje. Często łatwiej jest utworzyć zupełnie nowe nazwane wystąpienie aplikacji. Następnie możesz użyć parametrów aplikacji, aby ustawić dowolną konfigurację niezbędną dla usług. Dzięki temu wszystkie usługi utworzone w ramach tego nazwanego wystąpienia aplikacji mogą dziedziczyć określone ustawienia konfiguracji. Na przykład zamiast mieć jeden plik konfiguracji z ustawieniami i dostosowaniami dla każdego klienta, takich jak wpisy tajne lub limity zasobów klienta, zamiast tego będziesz mieć inne wystąpienie aplikacji dla każdego klienta z tymi ustawieniami zastąpionymi.
  • Nowa aplikacja służy jako granica uaktualnienia
    • W usłudze Service Fabric różne nazwane wystąpienia aplikacji służą jako granice uaktualniania. Uaktualnienie jednego nazwanego wystąpienia aplikacji nie wpłynie na kod uruchomiony przez inne nazwane wystąpienie aplikacji. Różne aplikacje będą uruchamiać różne wersje tego samego kodu w tych samych węzłach. Może to być czynnikiem, gdy trzeba podjąć decyzję o skalowaniu, ponieważ możesz wybrać, czy nowy kod powinien być zgodny z tymi samymi uaktualnieniami co inna usługa, czy nie. Załóżmy na przykład, że wywołanie jest dostarczane do usługi menedżera, która jest odpowiedzialna za skalowanie obciążeń określonego klienta przez dynamiczne tworzenie i usuwanie usług. W takim przypadku wywołanie dotyczy obciążenia skojarzonego z nowym klientem. Większość klientów, takich jak odizolowanie się od siebie, nie tylko ze względów bezpieczeństwa i konfiguracji wymienionych wcześniej, ale dlatego, że zapewnia większą elastyczność w zakresie uruchamiania określonych wersji oprogramowania i wybierania podczas uaktualniania. Możesz również utworzyć nowe wystąpienie aplikacji i utworzyć tam usługę po prostu w celu dalszego partycjonowania ilości usług, których dotyczy każde uaktualnienie. Oddzielne wystąpienia aplikacji zapewniają większy stopień szczegółowości podczas uaktualniania aplikacji, a także umożliwiają testowanie A/B i wdrożenia Blue/Green.
  • Istniejące wystąpienie aplikacji jest pełne
    • W usłudze Service Fabric pojemność aplikacji jest pojęciem, którego można użyć do kontrolowania ilości zasobów dostępnych dla określonych wystąpień aplikacji. Możesz na przykład zdecydować, że dana usługa musi mieć utworzone inne wystąpienie w celu skalowania. Jednak to wystąpienie aplikacji jest poza pojemnością dla określonej metryki. Jeśli ten konkretny klient lub obciążenie nadal powinny otrzymać więcej zasobów, możesz zwiększyć istniejącą pojemność dla tej aplikacji lub utworzyć nową aplikację.

Skalowanie na poziomie partycji

Usługa Service Fabric obsługuje partycjonowanie. Partycjonowanie dzieli usługę na kilka sekcji logicznych i fizycznych, z których każda działa niezależnie. Jest to przydatne w przypadku usług stanowych, ponieważ żaden zestaw replik nie musi obsługiwać wszystkich wywołań i manipulować wszystkim stanem jednocześnie. Omówienie partycjonowania zawiera informacje dotyczące typów obsługiwanych schematów partycjonowania. Repliki każdej partycji są rozłożone na węzły w klastrze, dystrybuując obciążenie tej usługi i zapewniając, że ani usługa jako całość, ani żadna partycja nie ma jednego punktu awarii.

Rozważ usługę, która używa schematu partycjonowania o zakresie z niskim kluczem 0, wysokim kluczem 99 i liczbą partycji 4. W klastrze z trzema węzłami usługa może zostać ułożona z czterema replikami, które współużytkujące zasoby w każdym węźle, jak pokazano poniżej:

Układ partycji z trzema węzłami

Jeśli zwiększysz liczbę węzłów, usługa Service Fabric przeniesie tam niektóre z istniejących replik. Załóżmy na przykład, że liczba węzłów zwiększa się do czterech, a repliki są redystrybuowane. Teraz usługa ma teraz trzy repliki uruchomione w każdym węźle, z których każda należy do różnych partycji. Umożliwia to lepsze wykorzystanie zasobów, ponieważ nowy węzeł nie jest zimny. Zazwyczaj zwiększa to również wydajność, ponieważ każda usługa ma więcej dostępnych zasobów.

Układ partycji z czterema węzłami

Skalowanie przy użyciu klastra usługi Service Fabric Resource Manager i metryk

Metryki to sposób wyrażania użycia zasobów przez usługi Service Fabric. Użycie metryk daje klastrowi Resource Manager możliwość reorganizacji i optymalizacji układu klastra. Na przykład w klastrze może być mnóstwo zasobów, ale mogą nie być przydzielane do usług, które obecnie wykonują pracę. Użycie metryk umożliwia klastrowi Resource Manager reorganizację klastra w celu zapewnienia, że usługi mają dostęp do dostępnych zasobów.

Skalowanie przez dodawanie i usuwanie węzłów z klastra

Inną opcją skalowania za pomocą usługi Service Fabric jest zmiana rozmiaru klastra. Zmiana rozmiaru klastra oznacza dodawanie lub usuwanie węzłów dla co najmniej jednego typu węzła w klastrze. Rozważmy na przykład przypadek, w którym wszystkie węzły w klastrze są gorące. Oznacza to, że zasoby klastra są prawie wszystkie używane. W takim przypadku dodanie kolejnych węzłów do klastra jest najlepszym sposobem skalowania. Po dołączeniu nowych węzłów do klastra klaster usługi Service Fabric Resource Manager przenosi do nich usługi, co powoduje mniejsze całkowite obciążenie istniejących węzłów. W przypadku usług bezstanowych z liczbą wystąpień = -1 kolejne wystąpienia usługi są tworzone automatycznie. Dzięki temu niektóre wywołania mogą przejść z istniejących węzłów do nowych węzłów.

Aby uzyskać więcej informacji, zobacz Skalowanie klastra.

Wybieranie platformy

Ze względu na różnice implementacji między systemami operacyjnymi wybór usługi Service Fabric z systemem Windows lub Linux może być istotną częścią skalowania aplikacji. Jedną z potencjalnych barier jest sposób wykonywania rejestrowania etapowego. Usługa Service Fabric w systemie Windows używa sterownika jądra dla dziennika jeden na maszynę współużytkowanego między replikami usługi stanowej. Ten dziennik waży około 8 GB. Z kolei system Linux używa dziennika przejściowego o wartości 256 MB dla każdej repliki, dzięki czemu jest mniej idealny dla aplikacji, które chcą zmaksymalizować liczbę lekkich replik usług uruchomionych w danym węźle. Te różnice w wymaganiach dotyczących magazynu tymczasowego mogą potencjalnie informować żądaną platformę wdrożenia klastra usługi Service Fabric.

Zebranie wszystkich elementów

Przyjrzyjmy się wszystkim pomysłom, które omówiliśmy tutaj i omówimy za pomocą przykładu. Rozważ następującą usługę: próbujesz utworzyć usługę, która działa jako książka adresowa, trzymając się nazw i informacji kontaktowych.

Bezpośrednio przed tobą masz kilka pytań związanych ze skalowaniem: Ilu użytkowników będziesz mieć? Ile kontaktów będzie przechowywać każdy użytkownik? Próba uzyskania tego wszystkiego, gdy tworzysz usługę po raz pierwszy, jest trudna. Załóżmy, że zamierzasz korzystać z jednej usługi statycznej z określoną liczbą partycji. Konsekwencje wybrania nieprawidłowej liczby partycji mogą spowodować problemy ze skalowaniem później. Podobnie, nawet jeśli wybierzesz odpowiednią liczbę, możesz nie mieć wszystkich potrzebnych informacji. Na przykład należy również zdecydować o rozmiarze klastra z góry, zarówno pod względem liczby węzłów, jak i ich rozmiarów. Zwykle trudno jest przewidzieć, ile zasobów usługa będzie zużywać przez cały okres istnienia. Może być również trudno wiedzieć z wyprzedzeniem wzorzec ruchu, który usługa rzeczywiście widzi. Na przykład może ludzie dodają i usuwają swoje kontakty tylko w pierwszej kolejności rano, a może jest dystrybuowana równomiernie w ciągu dnia. Na podstawie tego może być konieczne dynamiczne skalowanie w poziomie i w poziomie. Być może możesz nauczyć się przewidywać, kiedy będzie konieczne skalowanie w poziomie i w poziomie, ale prawdopodobnie konieczne będzie reagowanie na zmieniające się użycie zasobów przez usługę. Może to obejmować zmianę rozmiaru klastra w celu zapewnienia większej ilości zasobów podczas reorganizacji użycia istniejących zasobów nie wystarczy.

Ale dlaczego nawet spróbować wybrać pojedynczy schemat partycji dla wszystkich użytkowników? Dlaczego warto ograniczyć siebie do jednej usługi i jednego klastra statycznego? Rzeczywista sytuacja jest zwykle bardziej dynamiczna.

Podczas tworzenia na potrzeby skalowania należy wziąć pod uwagę następujący wzorzec dynamiczny. Może być konieczne dostosowanie go do swojej sytuacji:

  1. Zamiast próbować z góry wybrać schemat partycjonowania dla wszystkich, utwórz "usługę menedżera".
  2. Zadaniem usługi menedżera jest przyjrzenie się informacjom o kliencie podczas tworzenia konta usługi. Następnie w zależności od tych informacji usługa menedżera tworzy wystąpienie rzeczywistej usługi contact-storage tylko dla tego klienta. Jeśli wymagają one określonej konfiguracji, izolacji lub uaktualnień, możesz również zdecydować się na uruchomienie wystąpienia aplikacji dla tego klienta.

Ten wzorzec tworzenia dynamicznego ma wiele korzyści:

  • Nie próbujesz odgadnąć poprawnej liczby partycji dla wszystkich użytkowników z góry lub utworzyć pojedynczą usługę, która jest nieskończenie skalowalna samodzielnie.
  • Różni użytkownicy nie muszą mieć tej samej liczby partycji, liczby replik, ograniczeń umieszczania, metryk, obciążeń domyślnych, nazw usług, ustawień DNS ani żadnych innych właściwości określonych na poziomie usługi lub aplikacji.
  • Uzyskasz dodatkową segmentację danych. Każdy klient ma własną kopię usługi
    • Każda obsługa klienta może być skonfigurowana inaczej i udzielać więcej lub mniej zasobów, z większą lub mniejszą liczbą partycji lub replik zgodnie z potrzebami w zależności od ich oczekiwanej skali.
      • Załóżmy na przykład, że klient zapłacił za warstwę "Gold" — może uzyskać więcej replik lub większą liczbę partycji oraz potencjalnie zasoby przeznaczone dla swoich usług za pośrednictwem metryk i pojemności aplikacji.
      • Albo mówią, że dostarczyli informacje wskazujące liczbę potrzebnych kontaktów: "Mały" — otrzymają tylko kilka partycji, a nawet mogą zostać umieszczone w puli usług udostępnionych innym klientom.
  • Nie uruchamiasz wielu wystąpień usługi ani replik, gdy czekasz, aż klienci będą się pojawić
  • Jeśli klient kiedykolwiek opuści usługę, usunięcie ich informacji z usługi jest tak proste, jak usunięcie przez menedżera tej usługi lub utworzonej aplikacji.

Następne kroki

Aby uzyskać więcej informacji na temat pojęć związanych z usługą Service Fabric, zobacz następujące artykuły: