Umieszczanie ziarna

Orleans Zapewnia, że po wywołaniu ziarna jest wystąpienie tego ziarna dostępne w pamięci na niektórych serwerach w klastrze w celu obsługi żądania. Jeśli ziarno nie jest obecnie aktywne w klastrze, Orleans wybiera jeden z serwerów, na których ma być aktywowane ziarno. Jest to nazywane umieszczaniem ziarna. Umieszczanie jest również jednym ze sposobów równoważenia obciążenia: równomierne umieszczanie zajętych ziarna pomaga nawet w obciążeniu w klastrze.

Proces umieszczania w programie Orleans jest w pełni konfigurowalny: deweloperzy mogą wybierać spośród wbudowanych zasad umieszczania, takich jak losowe, preferowane lokalnie i oparte na obciążeniach lub niestandardowa logika. 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 ziarna, z którymi komunikują się. Domyślnie Orleans wybierze losowy serwer zgodny.

Strategia umieszczania używana Orleans przez program można skonfigurować globalnie lub na klasę szczegółową.

Losowe umieszczanie

Serwer jest losowo wybierany z zgodnych serwerów w klastrze. Ta strategia umieszczania jest konfigurowana przez dodanie elementu 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 elementu PreferLocalPlacementAttribute do ziarna.

Umieszczanie oparte na skrótach

Skrót identyfikatora ziarna do nieujemnej liczby całkowitej i modulo go 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 przy użyciu tej strategii są rejestrowane w katalogu ziarna, ta zmiana decyzji umieszczania, ponieważ zmiany członkostwa zwykle nie mają zauważalnego efektu.

Ta strategia umieszczania jest konfigurowana przez dodanie elementu 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 prognozując bieżącą liczbę aktywacji na podstawie najnowszej liczby aktywacji dokonanej przez dyrektora umieszczania na bieżącym serwerze. Dyrektor wybiera kilka serwerów losowo podczas przewidywania, próbując uniknąć wielu oddzielnych serwerów przeciążenia tego samego serwera. Domyślnie dwa serwery są wybierane losowo, ale ta wartość można skonfigurować za pomocą polecenia ActivationCountBasedPlacementOptions.

Ten algorytm opiera się na tezie The Power of Two Choices in Randomized Load Balancing by Michael David Mitzenmacher, a także jest używany w Nginx do równoważenia obciążenia rozproszonego, zgodnie z opisem w artykule NGINX i "Power of Two Choices" Load-Balancing Algorithm.

Ta strategia umieszczania jest konfigurowana przez dodanie elementu ActivationCountBasedPlacementAttribute do ziarna.

Umieszczanie bezstanowych procesów roboczych

Umieszczanie bezstanowych procesów roboczych to specjalna strategia umieszczania używana przez bezstanowe ziarna procesów roboczych. Umieszczanie to działa niemal identycznie PreferLocalPlacement z tą różnicą, że każdy serwer może mieć wiele aktywacji tego samego ziarna, a ziarno nie jest zarejestrowane w katalogu ziarna, ponieważ nie ma potrzeby.

Ta strategia umieszczania jest konfigurowana przez dodanie elementu StatelessWorkerAttribute do ziarna.

Umieszczanie na podstawie ról silosu

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

Wybieranie strategii umieszczania

Wybranie odpowiedniej strategii umieszczania ziarna poza wartościami domyślnymi, które Orleans zapewnia, wymaga monitorowania i oceny deweloperów. 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 ustawieniu Prawa dużych liczb, dlatego zazwyczaj jest to dobra wartość domyślna, gdy występuje nieprzewidywalne rozłożenie obciążenia 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 czasu wykonywania w innych silosach w klastrze, w tym:

  • Dostępna pamięć, łączna ilość pamięci fizycznej i użycie pamięci.
  • Użycie procesora CPU.
  • Łączna liczba aktywacji i ostatnio aktywna liczba aktywacji.
    • Przesuwane okno aktywacji, które były aktywne w ciągu ostatnich kilku sekund, czasami nazywane zestawem roboczym 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 efektywność kosztów 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ę podczas konfigurowania PlacementStrategy :

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. Odpowiednie atrybuty są określone w sekcjach strategii umieszczania.

Przykładowa strategia umieszczania niestandardowego

Najpierw zdefiniuj klasę, która implementuje IPlacementDirector interfejs, wymagając 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 ziarno, które ma zostać utworzone.

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 klasy ziarna, których chcesz użyć z atrybutem :

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

Na koniec zarejestruj strategię podczas tworzenia elementu 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.AddSingletonNamedService<
        PlacementStrategy, SamplePlacementStrategy>(
            nameof(SamplePlacementStrategy));

    services.AddSingletonKeyedService<
        Type, IPlacementDirector, SamplePlacementStrategyFixedSiloDirector>(
            typeof(SamplePlacementStrategy));
}

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