Udostępnij za pośrednictwem


Umieszczanie ziarna

Orleans zapewnia, że po wywołaniu ziarna jest instancja tego ziarna dostępna w pamięci na serwerach w klastrze do obsługi żądania. Jeśli ziarno nie jest obecnie aktywne w klastrze, Orleans wybiera jeden z serwerów, aby aktywować ziarno. Jest to nazywane umieszczaniem ziarna . Umieszczanie jest również jednym ze sposobów równoważenia obciążenia: równomierne rozmieszczanie aktywnych ziaren pomaga wyrównać obciążenie w klastrze.

Proces umieszczania w Orleans jest w pełni konfigurowalny: deweloperzy mogą wybierać spośród zestawów wbudowanych zasad umieszczania, takich jak losowe, preferujące lokalność i oparte na obciążeniu lub logika niestandardowa. Dzięki temu można w pełni elastycznie decydować, gdzie tworzone są ziarna. Na przykład ziarna można umieścić na serwerze w pobliżu zasobów, na których muszą działać, lub blisko innych ziaren, z którymi się komunikują. Domyślnie Orleans wybierze losowy serwer zgodny.

Strategia umieszczania, której używa Orleans, może być skonfigurowana globalnie lub w zależności od klasy ziarna.

Losowe umieszczanie

Serwer jest losowo wybierany z zgodnych serwerów w klastrze. Ta strategia umieszczania jest konfigurowana przez dodanie RandomPlacementAttribute do ziarna.

Umieszczanie lokalne

Jeśli serwer lokalny jest zgodny, wybierz serwer lokalny, w przeciwnym razie wybierz losowy serwer. Ta strategia umieszczania jest konfigurowana przez dodanie PreferLocalPlacementAttribute do ziarna.

Umieszczanie oparte na haszach

Przekształć identyfikator ziarna do nieujemnej liczby całkowitej i wykonaj operację modulo z liczbą zgodnych serwerów. Wybierz odpowiedni serwer z listy zgodnych serwerów uporządkowanych według adresu serwera. Należy pamiętać, że nie gwarantuje to stabilności w miarę zmiany członkostwa w klastrze. W szczególności dodawanie, usuwanie lub ponowne uruchamianie serwerów może zmienić serwer wybrany dla danego identyfikatora ziarna. Ponieważ ziarna umieszczone za pomocą tej strategii są rejestrowane w katalogu ziarna, zmiana w decyzji o umieszczeniu w wyniku zmian członkostwa zazwyczaj nie ma zauważalnego wpływu.

Ta strategia umieszczania jest konfigurowana przez dodanie HashBasedPlacementAttribute do ziarna.

Umieszczanie na podstawie liczby aktywacji

Ta strategia umieszczania ma na celu umieszczenie nowych aktywacji ziarna na serwerze o najmniejszym obciążeniu na podstawie liczby ostatnio zajętych ziarna. Obejmuje on mechanizm, w którym wszystkie serwery okresowo publikują łączną liczbę aktywacji na wszystkich innych serwerach. Następnie dyrektor umieszczania wybiera serwer, który ma mieć najmniejszą liczbę aktywacji, sprawdzając ostatnio zgłoszoną liczbę aktywacji i przewiduje bieżącą liczbę aktywacji na podstawie ostatnich liczby aktywacji dokonanych przez dyrektora umieszczania na bieżącym serwerze. Dyrektor wybiera kilka serwerów losowo podczas przewidywania, aby uniknąć przeciążenia wielu oddzielnych serwerów tego samego serwera. Domyślnie dwa serwery są wybierane losowo, ale ta wartość jest konfigurowalna za pośrednictwem ActivationCountBasedPlacementOptions.

Ten algorytm opiera się na tezie Moc dwóch wyborów w losowym równoważeniu obciążenia Michaela Davida Mitzenmacherai jest również używany w NGINX do rozproszonego równoważenia obciążenia, zgodnie z opisem w artykule NGINX i "Moc dwóch wyborów" Load-Balancing Algorytm.

Ta strategia rozmieszczania konfigurowana jest przez dodanie ActivationCountBasedPlacementAttribute do ziarna.

Umieszczanie bezstanowych pracowników

Strategia umieszczania bezstanowych procesów roboczych to specjalna metoda używana przez bezstanowi pracownicy ziarna. To rozmieszczenie działa niemal identycznie z PreferLocalPlacement z wyjątkiem tego, że każdy serwer może mieć wiele aktywacji tego samego ziarna, a ziarno nie jest zarejestrowane w katalogu ziaren, ponieważ nie ma takiej potrzeby.

Ta strategia umieszczania jest konfigurowana przez dodanie StatelessWorkerAttribute do ziarna.

Umieszczanie oparte na rolach silosowych

Deterministyczna strategia umieszczania, która umieszcza ziarna na silosach z określoną rolą. Ta strategia umiejscowienia jest konfigurowana poprzez dodanie SiloRoleBasedPlacementAttribute do ziarna.

Umieszczanie zoptymalizowane pod kątem zasobów

Strategia optymalizacji rozmieszczenia zasobów dąży do optymalizacji zasobów klastra, równoważąc aktywacje ziaren między silosami na podstawie dostępnej pamięci i użycia procesora. Przypisuje wagi do statystyk środowiska uruchomieniowego w celu nadania priorytetów różnym zasobom i oblicza znormalizowany wynik dla każdego silosu. Silos o najniższym wyniku jest wybierany do umieszczenia nadchodzącej aktywacji. Normalizacja gwarantuje, że każda właściwość przyczynia się proporcjonalnie do ogólnego wyniku. Wagi można regulować za pomocą ResourceOptimizedPlacementOptions na podstawie specyficznych dla użytkownika wymagań i priorytetów dotyczących różnych zasobów.

Ponadto ta strategia umiejscowienia ujawnia możliwość silniejszego preferowania dla lokalnego silosu (, który otrzymał żądanie utworzenia nowego miejsca) jako celu aktywacji. Jest to kontrolowane za pośrednictwem właściwości LocalSiloPreferenceMargin, która jest częścią opcji.

Ponadto algorytm adaptacyjny online, , zapewnia efekt wygładzenia, który pozwala uniknąć szybkich spadków sygnału, przekształcając go w proces rozpadu przypominający wielomian. Jest to szczególnie ważne w przypadku użycia CPU, a ogólnie przyczynia się do uniknięcia nasycenia zasobów na silosach, zwłaszcza nowo dołączonych.

Ten algorytm opiera się na: rozmieszczaniu opartym na zasobach z kooperatywnym filtrowaniem Kalmana w trybie podwójnym

Ta strategia umieszczania jest konfigurowana przez dodanie ResourceOptimizedPlacementAttribute do ziarna.

Wybieranie strategii umieszczania

Aby wybrać odpowiednią strategię rozmieszczenia ziarna poza wartościami domyślnymi zapewnianymi przez Orleans, konieczne jest monitorowanie i ocena deweloperska. Wybór strategii umieszczania powinien być oparty na rozmiarze i złożoności aplikacji, właściwości obciążenia i środowisku wdrażania.

Umieszczanie losowe opiera się na Law of Large Numbers, więc zwykle jest to dobra wartość domyślna, gdy istnieje nieprzewidywalne obciążenie rozłożone na dużą liczbę ziarna (10 000 plus).

Umieszczanie oparte na liczbie aktywacji ma również element losowy, oparty na zasadzie Power of Two Choices, która jest powszechnie używanym algorytmem rozproszonego równoważenia obciążenia i jest używany w popularnych modułach równoważenia obciążenia. Silosy często publikują statystyki operacyjne do innych silosów w klastrze, w tym:

  • Dostępna pamięć, łączna ilość pamięci fizycznej i użycie pamięci.
  • Użycie procesora
  • Łączna liczba aktywacji i ostatnio aktywna liczba aktywacji.
    • Przesuwane okno aktywacji aktywnych w ciągu ostatnich kilku sekund, czasami nazywane roboczym zestawem aktywacji.

Z tych statystyk obecnie używane są tylko liczby aktywacji w celu określenia obciążenia dla danego silosu.

Ostatecznie należy eksperymentować z różnymi strategiami i monitorować metryki wydajności, aby określić najlepsze dopasowanie. Wybierając odpowiednią strategię umieszczania ziarna, możesz zoptymalizować wydajność, skalowalność i opłacalność aplikacji Orleans.

Konfigurowanie domyślnej strategii umieszczania

Orleans będzie używać losowego umieszczania, chyba że wartość domyślna zostanie zastąpiona. Domyślną strategię umieszczania można zastąpić, rejestrując implementację PlacementStrategy podczas konfiguracji:

siloBuilder.ConfigureServices(services =>
    services.AddSingleton<PlacementStrategy, MyPlacementStrategy>());

Konfigurowanie strategii umieszczania dla ziarna

Strategia umieszczania dla typu ziarna jest konfigurowana przez dodanie odpowiedniego atrybutu w klasie ziarna. Atrybuty są określone w sekcjach strategii rozmieszczenia.

Przykładowa strategia niestandardowego umieszczania

Najpierw zdefiniuj klasę, która implementuje interfejs IPlacementDirector wymagający jednej metody. W tym przykładzie przyjęto założenie, że masz zdefiniowaną funkcję GetSiloNumber, która zwróci numer silosu, biorąc pod uwagę Guid ziarna, który ma zostać utworzony.

public class SamplePlacementStrategyFixedSiloDirector : IPlacementDirector
{
    public Task<SiloAddress> OnAddActivation(
        PlacementStrategy strategy,
        PlacementTarget target,
        IPlacementContext context)
    {
        var silos = context.GetCompatibleSilos(target).OrderBy(s => s).ToArray();
        int silo = GetSiloNumber(target.GrainIdentity.PrimaryKey, silos.Length);

        return Task.FromResult(silos[silo]);
    }
}

Następnie należy zdefiniować dwie klasy, aby umożliwić przypisanie klas ziarna do strategii:

[Serializable]
public sealed class SamplePlacementStrategy : PlacementStrategy
{
}

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class SamplePlacementStrategyAttribute : PlacementAttribute
{
    public SamplePlacementStrategyAttribute() :
        base(new SamplePlacementStrategy())
    {
    }
}

Następnie wystarczy oznaczyć wszystkie pożądane klasy ziarna, przypisując im atrybut:

[SamplePlacementStrategy]
public class MyGrain : Grain, IMyGrain
{
    // ...
}

Na koniec zarejestruj strategię, gdy budujesz SiloHost:

private static async Task<ISiloHost> StartSilo()
{
    var builder = new HostBuilder(c =>
    {
        // normal configuration methods omitted for brevity
        c.ConfigureServices(ConfigureServices);
    });

    var host = builder.Build();
    await host.StartAsync();

    return host;
}

private static void ConfigureServices(IServiceCollection services)
{
    services.AddPlacementDirector<SamplePlacementStrategy, SamplePlacementStrategyFixedSiloDirector>();
}

Drugi prosty przykład pokazujący dalsze użycie kontekstu umieszczania można znaleźć w PreferLocalPlacementDirector w repozytorium źródłowym Orleans.