von total_fields.limit bis zur Sanierung betroffener Indizes
Dynamisches Mapping wirkt bequem, bis ein einziger Index tausende Felder ansammelt und der Cluster-State so gross wird, dass jede Mapping-Aenderung spuerbar langsamer laeuft. Mapping-Explosion entsteht meist schleichend aus key-value-artigen Datenstrukturen, die ungebremst neue Felder erzeugen, und laesst sich mit klaren Limits, gezieltem dynamic:false und dem flattened-Datentyp zuverlaessig verhindern, bevor sie zum Produktionsproblem wird.
Inhaltsverzeichnis
- 1. Was Mapping-Explosion ist und warum sie den Cluster gefaehrdet
- 2. index.mapping.total_fields.limit verstehen und konfigurieren
- 3. Dynamic Mapping als Hauptursache
- 4. Symptome einer Mapping-Explosion erkennen
- 5. Der flattened-Datentyp als strukturelle Loesung
- 6. Nested- versus Object-Explosion bei Arrays
- 7. Weitere Field-Limits pro Anwendungsfall setzen
- 8. Monitoring: die Feldanzahl kontinuierlich beobachten
- 9. Sanierung eines bereits betroffenen Index
- 10. Zusammenfassung
- 11. FAQ
1. Was Mapping-Explosion ist und warum sie den Cluster gefaehrdet
Eine Mapping-Explosion entsteht, wenn ein Index durch dynamisches Mapping unkontrolliert immer mehr eindeutige Feldnamen ansammelt, oft im Bereich von zehntausenden bis hunderttausenden Feldern. Der Ausloeser ist typischerweise eine Datenstruktur, bei der Schluessel selbst variable Werte sind, etwa attributes.farbe_rot, attributes.groesse_42, attributes.material_baumwolle, wobei jeder neue Wert theoretisch ein neues Feld im Mapping erzeugt, statt als Wert eines festen Feldes gespeichert zu werden.
Das Problem einer Mapping-Explosion liegt nicht in der Anzahl der Dokumente, sondern in der Anzahl der eindeutigen Feldnamen im Mapping selbst. Jedes Feld erzeugt einen Eintrag im Cluster-State, der auf jedem Knoten des Clusters im Speicher gehalten und bei jeder Aenderung an alle Knoten repliziert wird. Ein aufgeblaehtes Mapping mit hunderttausenden Feldern macht den Cluster-State so gross, dass selbst triviale Operationen wie das Anlegen eines neuen Index spuerbar langsamer werden, weil der komplette State bei jeder Aenderung synchronisiert werden muss.
In schweren Faellen fuehrt eine Mapping-Explosion zu Out-of-Memory-Fehlern auf Master-Knoten, weil der Cluster-State vollstaendig im Heap gehalten wird. Suchanfragen mit Wildcard-Feldnamen oder Aggregationen ueber alle Felder werden dramatisch langsamer, und selbst einfache Mapping-Abfragen ueber _mapping liefern Antworten im Megabyte-Bereich, die selbst fuer Debugging-Zwecke kaum noch lesbar sind. Diese Kette von Symptomen macht deutlich, warum Mapping-Explosion praeventiv verhindert werden muss, statt sie im Nachhinein zu reparieren.
2. index.mapping.total_fields.limit verstehen und konfigurieren
Die erste Verteidigungslinie gegen Mapping-Explosion ist das Setting index.mapping.total_fields.limit, das die maximale Anzahl von Feldern pro Index festlegt. Der Standardwert liegt bei 1000, was fuer die meisten Anwendungsfaelle bereits grosszuegig bemessen ist. Sobald ein Dokument geschrieben wird, das dieses Limit ueberschreiten wuerde, lehnt Elasticsearch die Schreiboperation mit einem klaren Fehler ab, statt das Mapping stillschweigend unkontrolliert wachsen zu lassen.
Dieses Verhalten macht das Limit zu einem Fruehwarnsystem: statt einer schleichenden Mapping-Explosion, die erst Monate spaeter als Performance-Problem auffaellt, bricht die Applikation sofort mit einer nachvollziehbaren Fehlermeldung ab, sobald ein fehlerhaftes Datenmodell zu viele Felder erzeugen wuerde. Das zwingt Entwickler, das zugrunde liegende Datenmodell zu ueberdenken, statt das Limit reflexartig zu erhoehen.
PUT products/_settings
{
"index.mapping.total_fields.limit": 1500
}
# Check current field count against the limit
GET products/_mapping
GET products/_settings/index.mapping.total_fields.limit
Das Limit sollte niemals reflexartig erhoeht werden, um einen konkreten Fehler zu umgehen. Eine bewusste Erhoehung ist nur dann sinnvoll, wenn die Anzahl der Felder aus einer legitimen, begrenzten Anwendungsanforderung stammt, etwa einem Produktkatalog mit vielen echten, unterschiedlichen Attributtypen. Wird das Limit dagegen wegen key-value-artiger Daten erhoeht, verlagert das die Mapping-Explosion lediglich in die Zukunft, statt sie zu loesen.
3. Dynamic Mapping als Hauptursache
Die weitaus haeufigste Ursache fuer Mapping-Explosion ist unkontrolliertes dynamisches Mapping in Kombination mit Datenstrukturen, deren Schluessel selbst variable Werte sind. Ein typisches Beispiel: eine Anwendung speichert benutzerdefinierte Metadaten als flaches JSON-Objekt, in dem jeder Schluessel ein vom Endnutzer frei waehlbarer String ist. Jeder neue Schluessel, den irgendein Nutzer jemals verwendet, erzeugt ein permanentes neues Feld im Mapping, das nie wieder entfernt werden kann, ohne den Index neu aufzubauen.
Die strukturelle Loesung ist, dynamic: false oder dynamic: strict auf Indexebene zu setzen, sobald absehbar ist, dass Feldnamen aus variablem Nutzerinput stammen koennten. dynamic: false ignoriert unbekannte Felder beim Indexieren stillschweigend, sie werden im _source gespeichert, aber nicht durchsuchbar gemacht und erzeugen kein neues Mapping-Feld. dynamic: strict geht noch weiter und lehnt das gesamte Dokument mit einem Fehler ab, sobald es ein unbekanntes Feld enthaelt, was eine Mapping-Explosion strukturell unmoeglich macht, aber explizites Feld-Management erfordert.
PUT products
{
"mappings": {
"dynamic": "strict",
"properties": {
"sku": { "type": "keyword" },
"name": { "type": "text" },
"custom_attributes": {
"type": "flattened"
}
}
}
}
In diesem Beispiel wird das eigentliche Produktmapping strikt gehalten, waehrend variable, benutzerdefinierte Attribute gezielt in ein flattened-Feld ausgelagert werden, das beliebig viele Schluessel aufnehmen kann, ohne dass jeder Schluessel ein eigenes Mapping-Feld erzeugt. Diese Kombination aus striktem Mapping fuer bekannte Felder und einem flattened-Feld fuer unbekannte Attribute ist das Standardmuster zur Vermeidung von Mapping-Explosion.
4. Symptome einer Mapping-Explosion erkennen
Das fruehste erkennbare Symptom einer beginnenden Mapping-Explosion ist eine ungewoehnlich langsame GET _mapping-Antwort, deren Groesse im Vergleich zu frueheren Wochen deutlich zugenommen hat. Ein Mapping, das frueher wenige Kilobyte umfasste und ploetzlich mehrere Megabyte gross ist, deutet fast immer auf unkontrolliertes dynamisches Wachstum hin, selbst wenn das konfigurierte Field-Limit noch nicht erreicht ist.
Ein zweites Symptom zeigt sich in der Latenz von Cluster-State-Updates: jede Mapping-Aenderung, jeder neue Index und jedes Shard-Allocation-Event erfordert eine vollstaendige Synchronisation des Cluster-State auf allen Knoten. Bei fortgeschrittener Mapping-Explosion messen Monitoring-Systeme steigende Latenzen genau bei diesen Operationen, oft lange bevor Suchanfragen selbst spuerbar langsamer werden. Master-Knoten mit steigendem Heap-Verbrauch trotz stabiler Dokumentenzahl sind ein drittes verlaessliches Warnsignal, das auf ein wachsendes Mapping statt auf wachsende Datenmengen hindeutet.
5. Der flattened-Datentyp als strukturelle Loesung
Der flattened-Datentyp behandelt ein gesamtes JSON-Objekt als ein einziges Mapping-Feld, unabhaengig davon, wie viele Schluessel es tatsaechlich enthaelt. Statt fuer jeden Schluessel ein eigenes Feld im Mapping zu erzeugen, indexiert Elasticsearch alle Schluessel-Wert-Paare als eine Menge von Keyword-Tokens innerhalb dieses einen Feldes. Damit lassen sich exakte Term-Abfragen und Existenzpruefungen weiterhin durchfuehren, aber ohne dass jeder neue Schluessel die Mapping-Groesse erhoeht.
POST products/_doc
{
"sku": "SHIRT-001",
"custom_attributes": {
"farbe": "rot",
"groesse": "42",
"material": "baumwolle"
}
}
# Query into the flattened field with dot notation
GET products/_search
{
"query": {
"term": { "custom_attributes.farbe": "rot" }
}
}
Der Kompromiss beim flattened-Typ betrifft die Query-Faehigkeiten: Volltextsuche mit Analyzern, numerische Range-Queries und Aggregationen auf einzelnen Unterfeldern funktionieren nicht in derselben Tiefe wie bei explizit gemappten Feldern. Fuer echte Metadaten mit hoher Kardinalitaet an Schluesseln, bei denen exakte Treffer wichtiger sind als komplexe Analyse, ist dieser Kompromiss jedoch fast immer die richtige Entscheidung gegen eine drohende Mapping-Explosion.
6. Nested- versus Object-Explosion bei Arrays
Eine oft uebersehene Variante der Mapping-Explosion entsteht nicht durch variable Feldnamen, sondern durch tief verschachtelte Objektstrukturen in Arrays. Jedes Objekt-Feld auf jeder Verschachtelungsebene zaehlt zur Gesamtfeldanzahl, und ein Array mit vielen unterschiedlich strukturierten Objekten kann daher genauso viele Felder erzeugen wie key-value-artige Daten. Der Parameter index.mapping.depth.limit begrenzt zusaetzlich, wie tief Objektverschachtelungen ueberhaupt erlaubt sind, unabhaengig von der reinen Feldanzahl.
Bei nested-Feldern kommt eine weitere Dimension hinzu: jedes Element eines Nested-Arrays wird intern als eigenes verstecktes Lucene-Dokument gespeichert, was bei Arrays mit vielen Elementen pro Dokument die Gesamtzahl der Lucene-Dokumente im Index vervielfacht, selbst wenn die Feldanzahl im Mapping ueberschaubar bleibt. Das Setting index.mapping.nested_fields.limit begrenzt die Anzahl unterschiedlicher Nested-Mappings pro Index, waehrend index.mapping.nested_objects.limit die Gesamtzahl der Nested-Objekte pro Dokument deckelt und damit vor unkontrolliertem Wachstum auf Dokumentenebene schuetzt.
7. Weitere Field-Limits pro Anwendungsfall setzen
Neben total_fields.limit bietet Elasticsearch mehrere ergaenzende Limits, die gezielt gegen unterschiedliche Formen von Mapping-Explosion wirken. index.mapping.field_name_length.limit begrenzt die maximale Laenge eines einzelnen Feldnamens und faengt Faelle ab, in denen dynamisch generierte Feldnamen ganze Datenwerte enthalten, etwa vollstaendige UUIDs oder Zeitstempel als Feldname statt als Feldwert. index.mapping.depth.limit begrenzt, wie viele Verschachtelungsebenen ein JSON-Dokument maximal haben darf.
PUT products/_settings
{
"index.mapping.total_fields.limit": 1000,
"index.mapping.depth.limit": 10,
"index.mapping.nested_fields.limit": 50,
"index.mapping.field_name_length.limit": 128
}
Diese Kombination aus mehreren Limits bildet ein mehrschichtiges Sicherheitsnetz: selbst wenn eine einzelne Grenze durch einen unerwarteten Anwendungsfall knapp umgangen wird, faengt eine der anderen Grenzen die zugrunde liegende Mapping-Explosion typischerweise trotzdem ab, bevor sie den Cluster gefaehrdet. Alle diese Limits sollten Teil des Index-Templates sein, damit sie fuer jeden neu erstellten Index automatisch gelten, statt individuell nachgetragen zu werden.
| Setting | Schuetzt vor | Standardwert | Empfehlung |
|---|---|---|---|
| total_fields.limit | Zu viele eindeutige Feldnamen | 1000 | Nicht reflexartig erhoehen |
| depth.limit | Zu tiefe Verschachtelung | 20 | Auf reale Struktur begrenzen |
| nested_fields.limit | Zu viele Nested-Mappings | 50 | Bewusst pro Anwendungsfall setzen |
| field_name_length.limit | Werte statt Namen als Feld | Unbegrenzt | 128 bis 256 Zeichen setzen |
8. Monitoring: die Feldanzahl kontinuierlich beobachten
Reaktives Handeln allein reicht nicht aus, produktive Cluster sollten die Feldanzahl proaktiv ueberwachen, um eine beginnende Mapping-Explosion zu erkennen, bevor Limits ueberschritten werden. Die Field-Usage-Statistics-API liefert Einblick, welche Felder tatsaechlich in Suchanfragen verwendet werden, was hilft, ungenutzte Felder zu identifizieren, die moeglicherweise aus einer vergangenen Mapping-Explosion stammen und bereinigt werden koennten.
Ein einfaches, aber wirksames Monitoring-Skript fragt regelmaessig die Mapping-Groesse jedes Index ab und alarmiert, sobald die Feldanzahl einen definierten Schwellenwert unterhalb des konfigurierten Limits ueberschreitet, etwa 80 Prozent von total_fields.limit. Das gibt Teams genug Vorlaufzeit, um das zugrunde liegende Datenmodell zu korrigieren, bevor Schreiboperationen tatsaechlich fehlschlagen und in Produktion sichtbar werden.
# Count current mapping fields against the configured limit
curl -s "https://es.mironsoft.de:9200/products/_mapping" | \
jq '[.. | objects | select(has("type"))] | length'
curl -s "https://es.mironsoft.de:9200/products/_settings/index.mapping.total_fields.limit" | \
jq '.[].settings.index.mapping.total_fields.limit'
Mironsoft
Elasticsearch-Cluster-Gesundheit, Mapping-Design und Monitoring
Cluster-State, der nicht mehr im Griff ist?
Wir analysieren bestehende Mappings auf Explosionsrisiken, richten Field-Limits und Monitoring ein und sanieren betroffene Indizes mit einer sauberen Migration auf flattened-Felder und strikte Mapping-Kontrolle.
Mapping-Audit
Feldanzahl, Verschachtelungstiefe und Wachstumstrend je Index pruefen
Datenmodell-Redesign
Key-Value-Strukturen auf flattened-Felder und strikte Mappings umstellen
Monitoring-Setup
Fruehwarnung bei wachsender Feldanzahl in Alerting-Pipelines integrieren
9. Sanierung eines bereits betroffenen Index
Ist eine Mapping-Explosion bereits eingetreten, laesst sich das Mapping eines bestehenden Index nicht einfach bereinigen, weil Felder nach dem Anlegen nicht wieder entfernt werden koennen. Der einzige Weg zur Sanierung ist ein Reindexing in einen neuen Index mit korrigiertem, striktem Mapping, bei dem die problematischen key-value-artigen Felder gezielt in ein flattened-Feld ueberfuehrt werden, waehrend echte, stabile Felder ihr explizites Mapping behalten.
Vor diesem Reindexing lohnt sich eine Analyse, welche der explodierten Felder tatsaechlich in Suchanfragen verwendet werden, damit die neue Struktur nicht nur technisch sauber, sondern auch funktional vollstaendig ist. Ein Painless-Script innerhalb der _reindex API kann die Transformation der alten, verstreuten Felder in das neue flattened-Objekt automatisieren, sodass die Migration ohne manuelle Nachbearbeitung jedes einzelnen Dokuments ablaeuft. Nach erfolgreicher Sanierung sollte das neue Index-Template mit strikten Limits verhindern, dass sich dieselbe Mapping-Explosion ein zweites Mal wiederholt.
10. Zusammenfassung
Mapping-Explosion ist ein strukturelles Problem, das aus der Kombination von dynamischem Mapping und key-value-artigen Datenstrukturen entsteht, bei denen jeder neue Schluessel ein permanentes Feld im Mapping erzeugt. Die Folgen reichen von langsamen Cluster-State-Updates bis zu Out-of-Memory-Fehlern auf Master-Knoten. index.mapping.total_fields.limit und die begleitenden Depth- und Nested-Limits wirken als Fruehwarnsystem, waehrend dynamic: strict in Kombination mit dem flattened-Datentyp die strukturelle Loesung fuer variable Attribute darstellt.
Ist eine Mapping-Explosion bereits eingetreten, bleibt nur die Sanierung ueber Reindexing in einen neu strukturierten Index. Wer stattdessen von Anfang an klare Limits im Index-Template verankert und die Feldanzahl kontinuierlich ueberwacht, verhindert, dass ein bequemes, aber ungebremstes dynamisches Mapping zum schleichenden Stabilitaetsrisiko fuer den gesamten Cluster wird.
Mapping-Explosion vermeiden: Das Wichtigste auf einen Blick
total_fields.limit
Deckelt die Feldanzahl pro Index und wirkt als Fruehwarnsystem gegen wachsende Mappings.
dynamic: strict
Lehnt unbekannte Felder komplett ab, statt sie stillschweigend ins Mapping aufzunehmen.
flattened-Datentyp
Buendelt beliebig viele Schluessel-Wert-Paare in einem einzigen Mapping-Feld.
Sanierung
Nur ueber Reindexing in einen neu strukturierten Index moeglich, keine nachtraegliche Feldloeschung.