suchen
HeimBackend-EntwicklungGolangWie gehen Kubernetes-Operatoren mit Parallelität um?

Ursprünglich auf meinem Blog gepostet

Standardmäßig verarbeiten Operatoren, die mit Kubebuilder und Controller-Runtime erstellt wurden, jeweils eine einzelne Abgleichsanforderung. Dies ist eine sinnvolle Einstellung, da es für Betreiberentwickler einfacher ist, über die Logik in ihren Anwendungen nachzudenken und diese zu debuggen. Es schränkt auch den Durchsatz vom Controller zu den Kubernetes-Kernressourcen wie ectd und dem API-Server ein.

Aber was passiert, wenn sich Ihre Arbeitswarteschlange staut und sich die durchschnittlichen Abstimmungszeiten verlängern, weil Anfragen in der Warteschlange stehen bleiben und auf ihre Bearbeitung warten? Zum Glück für uns enthält eine Controller-Laufzeit-Controller-Struktur ein MaxConcurrentReconciles-Feld (wie ich bereits in meinem Kubebuilder-Tipps-Artikel erwähnt habe). Mit dieser Option können Sie die Anzahl gleichzeitiger Abgleichsschleifen festlegen, die in einem einzelnen Controller ausgeführt werden. Mit einem Wert über 1 können Sie also mehrere Kubernetes-Ressourcen gleichzeitig abgleichen.

Zu Beginn meiner Operator-Reise hatte ich eine Frage: Wie können wir garantieren, dass dieselbe Ressource nicht gleichzeitig von zwei oder mehr Goroutinen abgeglichen wird? Wenn MaxConcurrentReconciles auf über 1 gesetzt ist, könnte dies zu allen möglichen Race-Conditions und unerwünschtem Verhalten führen, da sich der Zustand eines Objekts innerhalb einer Abgleichsschleife durch einen Nebeneffekt einer externen Quelle (eine Abgleichsschleife, die in einem anderen Thread läuft) ändern könnte. .

Ich habe eine Weile darüber nachgedacht und sogar einen sync.Map-basierten Ansatz implementiert, der es einer Goroutine ermöglichen würde, eine Sperre für eine bestimmte Ressource zu erhalten (basierend auf ihrem Namespace/Namen).

Es stellte sich heraus, dass all dieser Aufwand umsonst war, da ich kürzlich (in einem k8s-Slack-Kanal) erfahren habe, dass die Controller-Workqueue diese Funktion bereits enthält! Allerdings mit einer einfacheren Implementierung.

Dies ist eine kurze Geschichte darüber, wie die Arbeitswarteschlange eines K8S-Controllers garantiert, dass eindeutige Ressourcen nacheinander abgeglichen werden. Selbst wenn MaxConcurrentReconciles auf über 1 eingestellt ist, können Sie sicher sein, dass jeweils nur eine einzige Abstimmungsfunktion auf eine bestimmte Ressource wirkt.

client-go/util

Controller-Runtime verwendet die Bibliothek client-go/util/workqueue, um die zugrunde liegende Abstimmungswarteschlange zu implementieren. In der doc.go-Datei des Pakets heißt es in einem Kommentar, dass die Arbeitswarteschlange diese Eigenschaften unterstützt:

  • Fair: Artikel werden in der Reihenfolge verarbeitet, in der sie hinzugefügt werden.
  • Geizig: Ein einzelner Artikel wird nicht mehrmals gleichzeitig verarbeitet. Wenn ein Artikel mehrmals hinzugefügt wird, bevor er verarbeitet werden kann, wird er nur einmal verarbeitet.
  • Mehrere Verbraucher und Produzenten. Insbesondere ist es zulässig, dass ein Artikel während der Verarbeitung erneut in die Warteschlange gestellt wird.
  • Benachrichtigungen zum Herunterfahren.

Moment mal... Meine Antwort ist genau hier im zweiten Aufzählungspunkt, der „Geizigen“-Eigenschaft! Laut diesen Dokumenten wird die Warteschlange dieses Parallelitätsproblem automatisch für mich lösen, ohne dass ich eine einzige Codezeile schreiben muss. Lassen Sie uns die Implementierung durchgehen.

Wie funktioniert die Arbeitswarteschlange?

Die Arbeitswarteschlangenstruktur verfügt über drei Hauptmethoden: Hinzufügen, Abrufen und Fertig. Innerhalb eines Controllers würde ein Informer der Arbeitswarteschlange Abstimmungsanforderungen (Namespace-Namen generischer k8s-Ressourcen) hinzufügen. Eine in einer separaten Goroutine ausgeführte Abgleichsschleife würde dann die nächste Anforderung aus der Warteschlange abrufen (blockieren, wenn sie leer ist). Die Schleife würde die benutzerdefinierte Logik ausführen, die in den Controller geschrieben ist, und dann würde der Controller „Done“ in der Warteschlange aufrufen und die Abgleichsanforderung als Argument übergeben. Dadurch würde der Prozess erneut beginnen und die Abgleichsschleife würde Get aufrufen, um das nächste Arbeitselement abzurufen.

Dies ähnelt der Verarbeitung von Nachrichten in RabbitMQ, wo ein Mitarbeiter ein Element aus der Warteschlange entfernt, es verarbeitet und dann eine „Bestätigung“ an den Nachrichtenbroker zurücksendet, die angibt, dass die Verarbeitung abgeschlossen ist und das Element sicher aus der Warteschlange entfernt werden kann die Warteschlange.

Dennoch habe ich einen Operator in der Produktion, der die Infrastruktur von QuestDB Cloud betreibt, und wollte sicherstellen, dass die Arbeitswarteschlange wie angekündigt funktioniert. Also hat a einen Schnelltest geschrieben, um sein Verhalten zu validieren.

Ein kleiner Test

Hier ist ein einfacher Test, der die Eigenschaft „Geizig“ validiert:

package main_test

import (
    "testing"

    "github.com/stretchr/testify/assert"

    "k8s.io/client-go/util/workqueue"
)

func TestWorkqueueStingyProperty(t *testing.T) {

    type Request int

    // Create a new workqueue and add a request
    wq := workqueue.New()
    wq.Add(Request(1))
    assert.Equal(t, wq.Len(), 1)

    // Subsequent adds of an identical object
    // should still result in a single queued one
    wq.Add(Request(1))
    wq.Add(Request(1))
    assert.Equal(t, wq.Len(), 1)

    // Getting the object should remove it from the queue
    // At this point, the controller is processing the request
    obj, _ := wq.Get()
    req := obj.(Request)
    assert.Equal(t, wq.Len(), 0)

    // But re-adding an identical request before it is marked as "Done"
    // should be a no-op, since we don't want to process it simultaneously
    // with the first one
    wq.Add(Request(1))
    assert.Equal(t, wq.Len(), 0)

    // Once the original request is marked as Done, the second
    // instance of the object will be now available for processing
    wq.Done(req)
    assert.Equal(t, wq.Len(), 1)

    // And since it is available for processing, it will be
    // returned by a Get call
    wq.Get()
    assert.Equal(t, wq.Len(), 0)
}

Da die Arbeitswarteschlange unter der Haube einen Mutex verwendet, ist dieses Verhalten threadsicher. Selbst wenn ich also mehr Tests schreiben würde, bei denen mehrere Goroutinen gleichzeitig mit hoher Geschwindigkeit aus der Warteschlange lesen und schreiben würden, um sie zu durchbrechen, wäre das tatsächliche Verhalten der Arbeitswarteschlange dasselbe wie das unseres Single-Threaded-Tests.

Es ist nicht alles verloren

How do Kubernetes Operators Handle Concurrency?

In den Kubernetes-Standardbibliotheken verstecken sich viele kleine Juwelen wie dieses, von denen sich einige an nicht so offensichtlichen Orten befinden (wie eine Controller-Laufzeit-Arbeitswarteschlange im Go-Client-Paket). Trotz dieser und ähnlicher Entdeckungen, die ich in der Vergangenheit gemacht habe, habe ich immer noch das Gefühl, dass meine früheren Versuche, diese Probleme zu lösen, keine völlige Zeitverschwendung sind. Sie zwingen Sie dazu, kritisch über grundlegende Probleme beim Rechnen mit verteilten Systemen nachzudenken, und helfen Ihnen, besser zu verstehen, was unter der Haube vor sich geht. Wenn ich also herausgefunden habe, dass „Kubernetes es geschafft hat“, bin ich erleichtert, dass ich meine Codebasis vereinfachen und vielleicht einige unnötige Komponententests entfernen kann.

Das obige ist der detaillierte Inhalt vonWie gehen Kubernetes-Operatoren mit Parallelität um?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Testcode, der auf Init -Funktionen in Go beruhtTestcode, der auf Init -Funktionen in Go beruhtMay 03, 2025 am 12:20 AM

WHENTETINGGOCODEWITHITHIFTFUNKTIONEN, UseExplicitsetupFunctionSesparatetestFilestoavoidDependencyonInitfunctionsideffecte.1) UsexplicitsetupFunctionStocontrolGlobalvariableInitialization.2) CreateSeparatetestBilestobypaNitInitInitialization und

Vergleich des Fehlerbehandlungsansatzes von GO mit anderen SprachenVergleich des Fehlerbehandlungsansatzes von GO mit anderen SprachenMay 03, 2025 am 12:20 AM

Go'serrorhandlingreturnserrorsasvalues,unlikeJavaandPythonwhichuseexceptions.1)Go'smethodensuresexpliciterrorhandling,promotingrobustcodebutincreasingverbosity.2)JavaandPython'sexceptionsallowforcleanercodebutcanleadtooverlookederrorsifnotmanagedcare

Best Practices für die Gestaltung effektiver Schnittstellen in GoBest Practices für die Gestaltung effektiver Schnittstellen in GoMay 03, 2025 am 12:18 AM

AneffectiveInterfaceingoisminimal, klar und PromotesLoosecoUPLing.1) MinimizetHeinTeInflexibilityAndaseaseFIMPlementation.2) Verwenden SieInterfacesForAbRactractionTosWapImplementationswithoutchangingCallingCode.3) DesignOntierablieger-verwendiginter-Per-ChodestomockDomockDepep

Zentralisierte Fehlerbehandlungsstrategien in GoZentralisierte Fehlerbehandlungsstrategien in GoMay 03, 2025 am 12:17 AM

Zentraler Fehlerbehebung kann die Lesbarkeit und Wartbarkeit von Code in GO -Sprache verbessern. Zu den Implementierungsmethoden und -vorteilen gehören: 1. Separate Fehlerbehandlungslogik aus der Geschäftslogik und vereinfachen Code. 2. Gewährleisten Sie die Konsistenz der Fehlerbehandlung durch zentraler Handhabung. 3. Verwenden Sie die Aufhebung und erholen Sie sich, um Panik zu erfassen und zu verarbeiten, um die Robustheit der Programme zu verbessern.

Alternativen zu Init -Funktionen für die Paketinitialisierung in GoAlternativen zu Init -Funktionen für die Paketinitialisierung in GoMay 03, 2025 am 12:17 AM

INGO, AlternativestoinitFunktionenincludecustonializationFunctions undsingletons.1) CustomInitializationFunctionsGlowexplicitControloverwhenInitializationOcccurs, NützfordelayedorConditionalSetups.2) SingletonsensOneOnitializationConconcurent

Geben Sie Behauptungen ein und geben Sie Schalter mit GO -Schnittstellen einGeben Sie Behauptungen ein und geben Sie Schalter mit GO -Schnittstellen einMay 02, 2025 am 12:20 AM

GoHandlesInterfacesAndTypeassertionSeffective, EnhancingCodeFlexibilityandrobustness.1) TypenSerionsallowruntimetypeCking, AsseenWithThapeInterfaceandCircletype.2) TypeSwitcheshandlemultipletypesiepy, nützlich, nützlich, nützlich

Verwenden von fehlern.is und fehler.as für die Fehlerinspektion in GOVerwenden von fehlern.is und fehler.as für die Fehlerinspektion in GOMay 02, 2025 am 12:11 AM

GO -Sprachfehlerhandhabung wird flexibler und durch Fehler lesbarer. IS und Fehler.as Funktionen. 1.Erors.IS wird verwendet, um zu prüfen, ob der Fehler dem angegebenen Fehler entspricht und für die Verarbeitung der Fehlerkette geeignet ist. 2.Errors.as können nicht nur den Fehlertyp überprüfen, sondern auch den Fehler in einen bestimmten Typ konvertieren, der zum Extrahieren von Fehlerinformationen geeignet ist. Die Verwendung dieser Funktionen kann die Fehlerbehandlungslogik der Fehlerbehandlung vereinfachen, aber auf die korrekte Abgabe von Fehlerketten achten und eine übermäßige Abhängigkeit vermeiden, um die Komplexität der Code zu verhindern.

Leistungsstimmung in Go: Optimierung Ihrer AnwendungenLeistungsstimmung in Go: Optimierung Ihrer AnwendungenMay 02, 2025 am 12:06 AM

TomakegoapplicationsRunfasterandmorefficenty, UseProfilingTools, LeveragEconcurrency und Managemoryeffectiv.1) UsePPRofforCpuandMemoryProfilingToidentifyBottlenecks.2) NutzungsgoroutinesandchannelstoparallelizeTakesAmproveProveperance.3) Implementierung

See all articles

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Leistungsstarke integrierte PHP-Entwicklungsumgebung

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

SAP NetWeaver Server-Adapter für Eclipse

SAP NetWeaver Server-Adapter für Eclipse

Integrieren Sie Eclipse mit dem SAP NetWeaver-Anwendungsserver.