Freigeben über


Kornplatzierung

Orleans stellt sicher, dass wenn ein Grain-Aufruf erfolgt, eine Instanz dieses Grain im Arbeitsspeicher auf einem Server im Cluster zur Bearbeitung der Anfrage verfügbar ist. Wenn das Korn derzeit nicht im Cluster aktiv ist, wählt Orleans einen Server aus, um das Korn zu aktivieren. Dieser Prozess wird als Grain Placement bezeichnet. Die Platzierung ist auch eine Möglichkeit Orleans um die Last auszugleichen: Gleichmäßig platzierte arbeitsintensive Einheiten tragen dazu bei, die Arbeitslast über den Cluster zu verteilen.

Der Platzierungsprozess in Orleans ist vollständig konfigurierbar. Wählen Sie aus standardmäßigen Platzierungsrichtlinien wie zufällig, lokal bevorzugt und lastbasiert, oder konfigurieren Sie benutzerdefinierte Logik. Dies ermöglicht volle Flexibilität bei der Entscheidung, wo Getreide entsteht. Platzieren Sie z. B. Getreide auf einem Server in der Nähe der Ressourcen, mit denen sie arbeiten müssen, oder nahe an anderen Getreiden, mit denen sie kommunizieren. Wählt standardmäßig Orleans einen zufällig kompatiblen Server aus.

Konfigurieren Sie die Platzierungsstrategie Orleans , die global oder pro Kornklasse verwendet.

Zufällige Platzierung

Orleans wählt zufällig einen Server von den kompatiblen Servern im Cluster aus. Um diese Platzierungsstrategie zu konfigurieren, fügen Sie die RandomPlacementAttribute Grainklasse hinzu.

Lokale Platzierung

Wenn der lokale Server kompatibel ist, Orleans wählt er den lokalen Server aus. Andernfalls wird ein zufälliger Server ausgewählt. Konfigurieren Sie diese Platzierungsstrategie, indem Sie das PreferLocalPlacementAttribute zur Grain-Klasse hinzufügen.

Hashbasierte Platzierung

Orleans Hashiert die Korn-ID in eine nicht-negative Ganzzahl und wendet eine Modulo-Operation mit der Anzahl kompatibler Server an. Anschließend wird der entsprechende Server aus der Liste der kompatiblen Server ausgewählt, die nach Serveradresse sortiert sind. Beachten Sie, dass diese Platzierung nicht garantiert stabil bleibt, wenn sich die Clustermitgliedschaft ändert. Insbesondere kann das Hinzufügen, Entfernen oder Neustarten von Servern den für eine bestimmte Korn-ID ausgewählten Server ändern. Da Getreide, das mithilfe dieser Strategie im Getreideverzeichnis registriert wird, platziert wird, hat die Änderung der Platzierungsentscheidung aufgrund von Mitgliedschaftsänderungen üblicherweise keinen spürbaren Effekt.

Konfigurieren Sie diese Platzierungsstrategie, indem Sie das HashBasedPlacementAttribute zur Grain-Klasse hinzufügen.

Platzierung auf Basis der Aktivierungsanzahl

Diese Platzierungsstrategie versucht, neue Getreideaktivierungen auf dem am wenigsten stark geladenen Server basierend auf der Anzahl der zuletzt ausgelasteten Getreide zu platzieren. Es enthält einen Mechanismus, bei dem alle Server regelmäßig ihre Gesamtaktivierungsanzahl auf allen anderen Servern veröffentlichen. Der Verantwortliche für die Platzierung wählt dann einen Server aus, bei dem die wenigsten Aktivierungen vorhergesagt werden, indem er die zuletzt gemeldete Aktivierungsanzahl untersucht und die aktuelle Anzahl basierend auf den kürzlich vom Platzierungsdirektor auf dem aktuellen Server durchgeführten Aktivierungen prognostiziert. Der Director wählt mehrere Server zufällig aus, wenn diese Vorhersage vorgenommen wird, um zu vermeiden, dass mehrere separate Server denselben Server überladen. Standardmäßig werden zwei Server zufällig ausgewählt, aber dieser Wert kann über ActivationCountBasedPlacementOptionskonfiguriert werden.

Dieser Algorithmus basiert auf der These The Power of Two Choices in Randomized Load Balancing von Michael David Mitzenmacher. Es wird auch in Nginx für den verteilten Lastenausgleich verwendet, wie im Artikel NGINX und der "Power of Two Choices" Load-Balancing Algorithmus beschrieben.

Konfigurieren Sie diese Platzierungsstrategie, indem Sie das ActivationCountBasedPlacementAttribute zur Grain-Klasse hinzufügen.

Zustandslose Workerplatzierung

Zustandslose Workerplatzierung ist eine spezielle Platzierungsstrategie, die von zustandslosen Workern Grainsverwendet wird. Diese Platzierung funktioniert fast identisch wie PreferLocalPlacement, mit der Ausnahme, dass jeder Server mehrere Aktivierungen desselben Grains haben kann und das Grain nicht im Grain-Verzeichnis registriert wird, da es keine Notwendigkeit gibt.

Konfigurieren Sie diese Platzierungsstrategie, indem Sie das StatelessWorkerAttribute zur Grain-Klasse hinzufügen.

Silo-rollenbasierte Platzierung

Dies ist eine deterministische Platzierungsstrategie, die Getreide auf Silos mit einer bestimmten Rolle platziert. Konfigurieren Sie diese Platzierungsstrategie, indem Sie das SiloRoleBasedPlacementAttribute zur Grain-Klasse hinzufügen.

Ressourcenoptimierte Platzierung

Die ressourcenoptimierte Platzierungsstrategie versucht, Clusterressourcen zu optimieren, indem die Kornaktivierungen auf Basis des verfügbaren Arbeitsspeichers und der CPU-Auslastung über Silos hinweg ausgeglichen werden. Sie weist Laufzeitstatistiken Gewichtungen zu, um unterschiedliche Ressourcen zu priorisieren und eine normalisierte Bewertung für jeden Silo zu berechnen. Das Silo mit der niedrigsten Bewertung wird für die Platzierung der bevorstehenden Aktivierung ausgewählt. Die Normalisierung stellt sicher, dass jede Eigenschaft proportional zur Gesamtbewertung beiträgt. Passen Sie die Gewichtungen basierend ResourceOptimizedPlacementOptions auf bestimmten Anforderungen und Prioritäten für verschiedene Ressourcen an.

Darüber hinaus bietet diese Platzierungsstrategie die Möglichkeit, eine stärkere Vorliebe für das lokale Silo zu entwickeln (dasjenige, das das Ersuchen zur Durchführung einer neuen Platzierung erhält), um als Ziel für die Aktivierung ausgewählt zu werden. Steuern Sie dies über die LocalSiloPreferenceMargin Eigenschaft, Teil der Optionen.

Ein adaptiver Online-Algorithmus bietet außerdem einen Glättungseffekt, der schnelle Signalabbrüche verhindert, indem das Signal in einen polynomähnlichen Zerfallsprozess umgewandelt wird. Dies ist besonders wichtig für die CPU-Auslastung und trägt insgesamt dazu bei, die Ressourcensättigung auf Silos, insbesondere neu eingebundene, zu vermeiden.

Dieser Algorithmus basiert auf der ressourcenbasierten Platzierung mit kooperativer Dualmodus-Kalman-Filterung.

Konfigurieren Sie diese Platzierungsstrategie, indem Sie das ResourceOptimizedPlacementAttribute zur Grain-Klasse hinzufügen.

Auswählen einer Platzierungsstrategie

Die Auswahl der geeigneten Kornplatzierungsstrategie, die über die Standardwerte Orleans hinausgeht, erfordert Überwachung und Auswertung. Die Wahl sollte auf der Größe und Komplexität, den Workloadmerkmalen und der Bereitstellungsumgebung der App basieren.

Zufällige Platzierung basiert auf dem Gesetz großer Zahlen, daher ist es in der Regel ein guter Standardwert für unvorhersehbare Lasten, die sich über viele Getreide verteilt (10.000 oder mehr).

Die auf Aktivierungszähler basierende Platzierung enthält auch ein Zufallselement und beruht auf dem Prinzip "Power of Two Choices" (Prinzip der Wahl zwischen zwei Optionen). Dies ist ein häufig verwendeter Algorithmus für den verteilten Lastenausgleich und wird in beliebten Lastenausgleichsmodulen verwendet. Silos veröffentlichen häufig Laufzeitstatistiken für andere Silos im Cluster, darunter:

  • Verfügbarer Arbeitsspeicher, gesamter physischer Speicher und Speicherauslastung.
  • CPU-Auslastung.
  • Die Gesamtzahl der Aktivierungen und die Anzahl der kürzlich aktiven Aktivierungen.
    • Ein gleitendes Fenster von Aktivierungen, die in den letzten Sekunden aktiv sind, manchmal auch als Aktivierungsarbeitssatz bezeichnet.

Aus diesen Statistiken werden derzeit nur Aktivierungsanzahlen verwendet, um die Last eines bestimmten Silos zu ermitteln.

Experimentieren Sie letztendlich mit verschiedenen Strategien, und überwachen Sie Leistungsmetriken, um die beste Passform zu ermitteln. Die Auswahl der richtigen Kornplatzierungsstrategie optimiert die Leistung, Skalierbarkeit und Kosteneffizienz von Orleans Apps.

Konfigurieren der Standardplatzierungsstrategie

Orleans verwendet zufällige Platzierung, es sei denn, der Standardwert wird außer Kraft gesetzt. Überschreiben Sie die Standardplatzierungsstrategie, indem Sie während der Konfiguration eine Implementierung von PlacementStrategy registrieren.

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

Konfigurieren der Platzierungsstrategie für ein Korn

Konfigurieren Sie die Platzierungsstrategie für einen Korntyp, indem Sie der Kornklasse das entsprechende Attribut hinzufügen. Relevante Attribute werden in den oben genannten Abschnitten für Platzierungsstrategien angegeben.

Beispiel für eine benutzerdefinierte Platzierungsstrategie

Definieren Sie zunächst eine Klasse, die die IPlacementDirector Schnittstelle implementiert, die eine einzelne Methode erfordert. Gehen Sie in diesem Beispiel davon aus, dass eine Funktion GetSiloNumber definiert ist, die eine Silonummer zurückgibt, wenn das Guid Korn erstellt werden soll.

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]);
    }
}

Definieren Sie dann zwei Klassen, um die Zuweisung von Getreideklassen zur Strategie zu ermöglichen:

[Serializable]
public sealed class SamplePlacementStrategy : PlacementStrategy
{
}

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

Markieren Sie dann alle Kornklassen, die diese Strategie mit dem Attribut verwenden möchten:

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

Registrieren Sie schließlich die Strategie beim Erstellen der ISiloHost:

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>();
}

Ein zweites einfaches Beispiel zur weiteren Verwendung des Platzierungskontexts finden Sie im PreferLocalPlacementDirectorOrleans Quell-Repository.