Circuit Breaker in Elasticsearch: Out-of-Memory-Fehler proaktiv verhindern
AI generated
_doc
_index
Elasticsearch / Speicherschutz
Circuit Breaker: Out-of-Memory-Fehler proaktiv verhindern
Field-Data-, Request- und In-Flight-Requests-Breaker im Detail

Ein Elasticsearch-Node, dem der Heap-Speicher ausgeht, reagiert nicht elegant: Statt einer kontrollierten Fehlermeldung droht im schlimmsten Fall ein kompletter Absturz des Node-Prozesses durch einen Out-of-Memory-Fehler der JVM, mit potenziellem Datenverlust und einem aufwändigen Recovery. Circuit Breaker sind Elasticsearchs eingebaute Verteidigungslinie gegen genau dieses Szenario: Sie überwachen den geschätzten Speicherverbrauch verschiedener Operationen und brechen eine Anfrage kontrolliert mit einer Fehlermeldung ab, statt die JVM tatsächlich an ihre Grenze zu bringen. Wer die verschiedenen Breaker-Typen, ihre typischen Auslöser und die richtige Diagnose bei einem ausgelösten Breaker versteht, kann Speicherprobleme erkennen, bevor sie zum kompletten Node-Ausfall eskalieren.

10 Min. Lesezeit Field-Data-Breaker Request- und In-Flight-Breaker Diagnose per Nodes-Stats-API

1. Warum Elasticsearch überhaupt Circuit Breaker braucht

Die JVM, auf der Elasticsearch läuft, arbeitet mit einem fest konfigurierten Heap-Speicher, dessen Größe beim Start des Node-Prozesses festgelegt wird. Überschreitet der tatsächliche Speicherbedarf diesen konfigurierten Heap, kann die JVM mit einem Out-of-Memory-Fehler abstürzen, was für den betroffenen Node einen unkontrollierten Neustart samt Shard-Recovery bedeutet, statt lediglich eine einzelne, überzogene Anfrage abzulehnen.

Ohne eine vorgelagerte Schutzschicht könnte bereits eine einzelne, schlecht konzipierte Aggregation oder Sortierung auf einem ungeeigneten Feld genug Speicher belegen, um den gesamten Node zum Absturz zu bringen und damit potenziell auch andere, völlig unabhängige Anfragen und Shards auf demselben Node in Mitleidenschaft zu ziehen. Circuit Breaker verhindern genau dieses Szenario, indem sie den geschätzten Speicherbedarf vor der eigentlichen Ausführung prüfen.

2. Der Parent Circuit Breaker als übergeordnete Guard-Rail

Der Parent Circuit Breaker bildet die oberste Grenze für den gemeinsamen, geschätzten Speicherverbrauch aller einzelnen Breaker zusammen und ist standardmäßig auf etwa 95 Prozent des konfigurierten JVM-Heaps eingestellt. Er greift, sobald die Summe aus Field-Data-, Request-, In-Flight-Requests- und weiteren Breakern diese Gesamtgrenze überschreitet, unabhängig davon, ob ein einzelner Breaker für sich genommen noch innerhalb seines eigenen Limits liegt.

Diese übergeordnete Grenze fängt insbesondere Fälle ab, in denen mehrere, für sich genommen unauffällige Operationen gleichzeitig ausgeführt werden und in Summe trotzdem den verfügbaren Heap überlasten würden. Ein einzelner, isoliert betrachteter Breaker-Wert allein reicht deshalb für eine vollständige Speicherdiagnose oft nicht aus, der Parent-Breaker-Status gehört immer mit ins Bild.

3. Field-Data-Breaker: Risiko bei Sortierung und Aggregation auf Text-Feldern

Der Field-Data-Breaker schützt vor übermäßigem Speicherverbrauch durch Field Data, jene In-Memory-Datenstruktur, die für Sortierungen, Aggregationen und Skript-Zugriffe auf analysierte Text-Felder benötigt wird, sofern kein geeignetes Keyword-Feld oder Doc-Values verwendet werden. Field Data muss für jedes betroffene Feld vollständig in den Heap geladen werden und wächst dabei proportional zur Anzahl der eindeutigen Terme im jeweiligen Feld.

In Magento-Kontexten tritt dieser Fall typischerweise auf, wenn versehentlich auf einem analysierten Textfeld wie einer Produktbeschreibung sortiert oder aggregiert wird, statt auf dem dafür vorgesehenen, nicht analysierten Keyword-Subfeld. Weil Field Data standardmäßig für Text-Felder deaktiviert ist, führt ein solcher Versuch meist zunächst zu einer expliziten Fehlermeldung, statt stillschweigend den Heap zu belasten, was das Problem in der Praxis früh sichtbar macht.

4. Request-Breaker: Schutz vor einzelnen teuren Anfragen

Der Request-Breaker schätzt den Speicherbedarf einer einzelnen Anfrage bereits während ihrer Ausführung, etwa für den Aufbau großer Aggregations-Buckets oder umfangreicher Sortierstrukturen, und bricht die Anfrage ab, sobald die geschätzte Speicherlast das konfigurierte Limit übersteigt. Anders als der Field-Data-Breaker betrifft er nicht nur Text-Feld-Zugriffe, sondern grundsätzlich jede Operation, die während der Ausführung signifikanten, temporären Speicher innerhalb einer einzelnen Anfrage benötigt.

Typische Auslöser sind Aggregationen mit sehr hoher Kardinalität, etwa eine Terms-Aggregation über ein Feld mit hunderttausenden eindeutigen Werten ohne sinnvolle Begrenzung der Bucket-Anzahl, oder tief verschachtelte Aggregationen mit vielen Ebenen, deren Speicherbedarf sich mit jeder zusätzlichen Ebene multipliziert. Ein ausgelöster Request-Breaker ist damit oft ein direkter Hinweis auf eine unpassend formulierte, zu wenig eingegrenzte Aggregation.

5. In-Flight-Requests-Breaker: Schutz vor Netzwerk-Puffer-Überlastung

Der In-Flight-Requests-Breaker überwacht den Speicherbedarf aller aktuell empfangenen, aber noch nicht vollständig verarbeiteten Transport- und HTTP-Anfragen. Er schützt damit vor einem Szenario, in dem sehr viele, gleichzeitig eintreffende Anfragen mit großen Payloads, etwa Bulk-Indexierungsanfragen mit großen Batch-Größen, gemeinsam so viel Pufferspeicher belegen, dass der Node ins Straucheln gerät, noch bevor die eigentliche Verarbeitung überhaupt begonnen hat.

Dieser Breaker ist besonders relevant bei hoher Indexierungslast, etwa während eines vollständigen Magento-Katalog-Reindex mit vielen parallelen Bulk-Requests. Wird dieser Breaker regelmäßig ausgelöst, ist häufig eine Reduzierung der Bulk-Batch-Größe oder der Anzahl gleichzeitiger Indexer-Threads die naheliegende Gegenmaßnahme, statt vorschnell das Breaker-Limit selbst zu erhöhen.

6. Typische Auslöser in Magento-Kontexten

Neben Sortierungen auf analysierten Textfeldern und hochkardinalen Aggregationen treten in Magento-Betrieb häufig noch zwei weitere Muster auf: unbegrenzte Facetten-Aggregationen in der Layered Navigation bei Kategorien mit sehr vielen unterschiedlichen Attributwerten, sowie sehr breite Scripted-Metric-Aggregationen für individuelle Preisberechnungen, die für jedes einzelne Dokument einen eigenen Skript-Kontext im Speicher aufbauen.

Auch ein plötzlicher Anstieg gleichzeitig ausgeführter, komplexer Facetten-Anfragen während eines Traffic-Peaks, etwa an einem Aktionstag, kann in Summe den Parent Circuit Breaker auslösen, selbst wenn jede einzelne Anfrage für sich genommen unauffällig wäre. Solche Lastspitzen sind ein guter Anlass, die Aggregations-Struktur der Layered Navigation grundsätzlich auf sinnvolle Bucket-Limits zu überprüfen.

7. Diagnose eines ausgelösten Circuit Breakers

Ein ausgelöster Circuit Breaker erzeugt eine klar erkennbare CircuitBreakingException in den Logs sowie in der HTTP-Antwort an den Client, inklusive Angabe des ausgelösten Breaker-Typs, des geschätzten Speicherbedarfs und des konfigurierten Limits. Diese Information ist der erste und wichtigste Ansatzpunkt, um die genaue Ursache einzugrenzen, statt pauschal von einem allgemeinen Speicherproblem auszugehen.

Die Nodes-Stats-API liefert zusätzlich pro Node und pro Breaker-Typ detaillierte Zähler, unter anderem die Anzahl der bisher ausgelösten Breaker-Ereignisse und den aktuell geschätzten Speicherverbrauch je Breaker. Ein kontinuierlicher Anstieg dieser Zähler über mehrere Tage hinweg deutet auf ein strukturelles Problem hin, ein einzelner, isolierter Ausschlag dagegen eher auf eine konkrete, schlecht formulierte Einzelanfrage.


# Breaker-Statistiken aller Nodes abfragen
curl "localhost:9200/_nodes/stats/breaker?pretty" \
  | jq '.nodes[].breakers | to_entries[] | {name: .key, tripped: .value.tripped}'

8. Tuning der Breaker-Limits: wann und wie vorsichtig anpassen

Die Standardwerte der einzelnen Circuit Breaker sind bewusst konservativ gewählt und sollten nicht als erste Reaktion auf einen ausgelösten Breaker pauschal erhöht werden, da eine Erhöhung lediglich den Sicherheitsabstand zum tatsächlichen Out-of-Memory-Fehler verkleinert, ohne das eigentliche, speicherintensive Anfragemuster zu beheben.

Eine moderate, gut begründete Anpassung ist sinnvoll, wenn Diagnose und Monitoring eindeutig zeigen, dass die Node-Hardware tatsächlich mehr Heap zur Verfügung hat, als die aktuellen Limits ausnutzen, und die auslösenden Anfragen bereits geprüft und als grundsätzlich notwendig eingestuft wurden. In diesem Fall werden die Limits über die Cluster-Settings-API schrittweise und mit engmaschiger Beobachtung angepasst, nie in einem großen Sprung.


PUT _cluster/settings
{
  "persistent": {
    "indices.breaker.request.limit": "50%",
    "indices.breaker.fielddata.limit": "30%"
  }
}

9. Präventive Maßnahmen statt reines Limit-Tuning

Nachhaltiger als das Anheben von Breaker-Limits ist die konsequente Vermeidung speicherintensiver Anfragemuster von vornherein: Sortierungen und Aggregationen ausschließlich auf Keyword-Feldern oder dedizierten Doc-Values-Feldern statt auf analysiertem Text, sowie sinnvolle, explizite Größenbegrenzungen bei jeder Terms- oder Composite-Aggregation.

Zusätzlich hilft ein regelmäßiger Blick in die Slow-Query-Logs, um Anfragemuster frühzeitig zu erkennen, die potenziell zu einem ausgelösten Breaker führen können, noch bevor sie unter realer Last tatsächlich eskalieren. Diese präventive Haltung reduziert die Notwendigkeit, die Breaker-Limits überhaupt anzufassen, und hält damit den eingebauten Sicherheitsabstand zur JVM-Speichergrenze vollständig erhalten.

Breaker-Typ Schützt vor Typischer Auslöser Gegenmaßnahme
Parent Gesamtspeicherverbrauch aller Breaker zusammen Viele gleichzeitige, einzeln unauffällige Anfragen Gesamtlast und Parallelität begrenzen
Field Data Speicherhunger durch Sortierung/Aggregation auf Text Sortierung auf analysiertem statt Keyword-Feld Doc-Values und Keyword-Subfelder nutzen
Request Speicherbedarf einer einzelnen Anfrage Hochkardinale oder tief verschachtelte Aggregation Bucket-Limits und Aggregationstiefe reduzieren
In-Flight Requests Pufferspeicher eingehender Anfragen Viele parallele Bulk-Indexierungsanfragen Bulk-Batch-Größe und Parallelität reduzieren

Mironsoft

Suchindex-Setup, Relevanz-Tuning und Magento-Suche

Magento-Suche, die die falschen Produkte zuerst zeigt?

Wir richten Elasticsearch oder OpenSearch für Magento sauber ein, tunen Relevanz und Facetten auf das tatsächliche Sortiment und optimieren Indexierungsprozesse für große Kataloge.

Relevanz-Tuning

Suchergebnisse und Facetten auf die tatsächlichen Kundenbedürfnisse abstimmen.

Such-Migration

Umstieg von Solr oder MySQL-Suche auf Elasticsearch/OpenSearch sauber begleiten.

Index-Performance

Indexierungsprozesse für große Kataloge zuverlässig und performant gestalten.

10. Zusammenfassung

Circuit Breaker in Elasticsearch: Das Wichtigste auf einen Blick

Grundproblem

Ohne Schutzmechanismus kann eine einzelne, speicherintensive Anfrage die JVM bis zum Out-of-Memory-Fehler und Node-Absturz treiben.

Breaker-Typen

Parent, Field Data, Request und In-Flight Requests schützen jeweils eine andere Ebene des Speicherverbrauchs vor Überlastung.

Typische Auslöser

Sortierung auf analysierten Textfeldern, hochkardinale Aggregationen und große parallele Bulk-Requests lösen Breaker am häufigsten aus.

Richtiger Umgang

Diagnose über Logs und Nodes-Stats-API vor jeder Limit-Erhöhung, präventive Anfrageoptimierung ist nachhaltiger als reines Tuning.

11. FAQ: Circuit Breaker in Elasticsearch: Das Wichtigste auf einen Blick

1Was passiert technisch, wenn ein Circuit Breaker auslöst?
Die betroffene Anfrage wird kontrolliert mit einer CircuitBreakingException abgebrochen, statt den Heap tatsächlich bis zum Out-of-Memory-Fehler zu belasten.
2Was ist der Unterschied zwischen dem Parent- und den einzelnen Breakern?
Der Parent Circuit Breaker begrenzt den gemeinsamen Speicherverbrauch aller einzelnen Breaker zusammen, unabhängig davon, ob jeder einzelne Breaker für sich innerhalb seines Limits liegt.
3Wann greift der Field-Data-Breaker typischerweise?
Wenn auf einem analysierten Textfeld statt auf einem Keyword-Feld oder Doc-Values sortiert oder aggregiert wird und dadurch Field Data in den Heap geladen werden müsste.
4Was ist eine typische Ursache für einen ausgelösten Request-Breaker?
Hochkardinale Terms-Aggregationen ohne sinnvolle Bucket-Begrenzung oder tief verschachtelte Aggregationen mit hohem Speicherbedarf pro Ausführung.
5Wofür ist der In-Flight-Requests-Breaker zuständig?
Er begrenzt den Pufferspeicher aller aktuell empfangenen, aber noch nicht verarbeiteten Anfragen, etwa bei vielen parallelen Bulk-Indexierungsanfragen.
6Wie erkennt man einen ausgelösten Breaker im Betrieb?
Über eine CircuitBreakingException in Logs und HTTP-Antwort sowie über Zähler pro Breaker-Typ in der Nodes-Stats-API.
7Sollte man Breaker-Limits nach dem ersten Auslösen sofort erhöhen?
Nein, zunächst sollte die auslösende Anfrage analysiert und wenn möglich optimiert werden, bevor überhaupt über eine Limit-Anpassung nachgedacht wird.
8Welche Magento-spezifischen Muster lösen Breaker besonders häufig aus?
Unbegrenzte Facetten-Aggregationen in der Layered Navigation und breite Scripted-Metric-Aggregationen für individuelle Preisberechnungen.
9Wie kann man Field-Data-Breaker-Probleme dauerhaft vermeiden?
Indem Sortierungen und Aggregationen konsequent auf Keyword-Feldern oder dedizierten Doc-Values-Feldern statt auf analysiertem Text ausgeführt werden.
10Was ist der Standardwert des Parent Circuit Breakers?
Standardmäßig etwa 95 Prozent des konfigurierten JVM-Heaps, wobei dieser Wert bewusst konservativ gewählt ist und nur mit Bedacht erhöht werden sollte.