Elasticsearch Shard-Größenstrategie: Die optimale Balance finden

Planen Sie die Elasticsearch-Shard-Größe durch Abwägen von Shard-Größe, Knotenkapazität, Abfragemustern, Wiederherstellungszeit und Wachstum.

Elasticsearch Shard-Größenstrategie: Die optimale Balance finden

Elasticsearch, eine leistungsstarke verteilte Such- und Analyse-Engine, verdankt einen Großteil seiner Skalierbarkeit und Leistung seiner zugrunde liegenden Architektur, insbesondere dem Konzept der Shards. Shards sind im Wesentlichen unabhängige Lucene-Indizes, die einen Teil Ihrer Daten enthalten. Ihre Größe zu verstehen und zu optimieren ist nicht nur eine bewährte Methode; es ist ein kritischer Faktor, der sich direkt auf die Leistung, Stabilität und Kosteneffizienz Ihres Clusters auswirkt.

Die Elasticsearch-Shard-Größenstrategie ist ein Kapazitätsplanungsproblem, keine einmalige Formel. Sie möchten Shards, die groß genug sind, um Metadaten-Overhead zu vermeiden, klein genug, um schnell wiederhergestellt zu werden, und zahlreich genug, um Indexierungs- und Sucharbeit auf Ihre Datenknoten zu verteilen.

Elasticsearch-Shards verstehen

Bevor wir uns mit der Größenbestimmung befassen, lassen Sie uns kurz wiederholen, was Shards sind und wie sie innerhalb eines Elasticsearch-Clusters funktionieren.

Was ist ein Shard?

In Elasticsearch ist ein Index eine logische Gruppierung von Daten. Um diese Daten zu verteilen und parallele Verarbeitung zu ermöglichen, wird ein Index in einen oder mehrere Shards unterteilt. Jeder Shard ist ein eigenständiger Lucene-Index. Wenn Sie einen Index erstellen, legen Sie die Anzahl der Primär-Shards fest, die er haben wird.

Für hohe Verfügbarkeit und Leseskalierbarkeit ermöglicht Elasticsearch Ihnen auch die Angabe von Replica-Shards. Ein Replica-Shard ist eine exakte Kopie eines Primär-Shards. Wenn der Knoten eines Primär-Shards ausfällt, kann ein Replica hochgestuft werden, um seinen Platz einzunehmen, wodurch die Datenverfügbarkeit sichergestellt und Datenverlust verhindert wird. Replicas bedienen auch Suchanfragen und verteilen die Leselast.

Wie Shards funktionieren

Wenn Sie ein Dokument indizieren, bestimmt Elasticsearch basierend auf einem Routing-Algorithmus (standardmäßig basierend auf der ID des Dokuments), zu welchem Primär-Shard es gehört. Dieses Dokument wird dann auf diesem spezifischen Primär-Shard und seinen entsprechenden Replica-Shards gespeichert. Wenn Sie suchen, wird die Anfrage an alle relevanten Shards gesendet, die ihren Teil der Daten parallel verarbeiten. Die Ergebnisse werden dann aggregiert und an den Client zurückgegeben. Diese parallele Verarbeitung verleiht Elasticsearch seine immense Geschwindigkeit und Skalierbarkeit.

Warum die Shard-Größe wichtig ist

Die optimale Shard-Größe ist ein grundlegendes Element für einen gesunden Elasticsearch-Cluster. Eine falsche Größenbestimmung kann zu einer Vielzahl von Problemen führen, von träger Abfrageleistung über kostspielige Ressourcenverschwendung bis hin zu instabilen Wiederherstellungsszenarien.

Leistung

  • Abfragegeschwindigkeit: Ein gut dimensionierter Shard kann Abfragen effizient verarbeiten. Zu kleine Shards bedeuten mehr Koordinationsaufwand; zu große Shards bedeuten längere Suchzeiten für einzelne Shards.
  • Indexierungsdurchsatz: Ebenso kann die Indexierungsleistung beeinträchtigt werden. Wenn Shards zu klein sind, kann der Overhead der Verwaltung vieler Shards Schreibvorgänge verlangsamen. Wenn Shards zu groß sind, kann die Leistung einzelner Shards zum Engpass werden.

Ressourcennutzung

Jeder Shard verbraucht Ressourcen auf dem Knoten, auf dem er sich befindet, einschließlich CPU, Arbeitsspeicher (JVM-Heap) und Festplatten-I/O. Die richtige Größenbestimmung stellt sicher, dass Ihre Knoten effizient genutzt werden, ohne überlastet oder unterausgelastet zu sein.

Skalierbarkeit

Shards sind die Verteilungseinheiten in Elasticsearch. Um horizontal zu skalieren, fügen Sie weitere Knoten hinzu, und Elasticsearch gleicht die Shards über sie aus. Wenn Shards zu groß sind, dauert der Ausgleich länger und erfordert mehr Netzwerkbandbreite. Wenn Sie zu wenige Shards haben, stoßen Sie möglicherweise früh an eine Skalierungsgrenze, da Sie die Arbeitslast nicht weiter als auf die Anzahl der Primär-Shards verteilen können.

Wiederherstellung & Stabilität

  • Knotenausfälle: Wenn ein Knoten ausfällt, muss Elasticsearch seine Primär-Shards neu zuweisen (durch Hochstufen von Replicas) und verlorene Replicas neu erstellen. Die dafür benötigte Zeit ist direkt proportional zur Größe und Anzahl der beteiligten Shards.
  • Cluster-Wiederherstellung: Große Shards benötigen länger für die Wiederherstellung und Replikation, was das Zeitfenster der Anfälligkeit während Knotenausfällen oder Cluster-Neustarts vergrößert.

Faktoren, die die Shard-Größe beeinflussen

Die Bestimmung der richtigen Shard-Größe ist keine Einheitslösung. Sie hängt von mehreren voneinander abhängigen Faktoren ab, die für Ihren Anwendungsfall und Ihre Infrastruktur spezifisch sind.

  • Datenvolumen & Wachstum: Ihre aktuelle Datengröße und die prognostizierte Wachstumsrate sind grundlegend. Ein statischer 100-GB-Index hat andere Anforderungen als ein rollierender Index, der täglich um 1 TB wächst.
  • Dokumentgröße & Schema-Komplexität: Indizes mit vielen Feldern oder sehr großen Dokumenten könnten von kleineren Shards profitieren, da die Verarbeitung jedes Dokuments mehr Ressourcen erfordert.
  • Abfragemuster:
    • Suche-lastig: Wenn Ihr Cluster hauptsächlich für die Suche verwendet wird, priorisieren Sie möglicherweise eine höhere Anzahl kleinerer Shards, um die Parallelisierung zu maximieren und die Suchzeiten einzelner Shards zu minimieren.
    • Analyse-lastig (Aggregationen): Große Aggregationen könnten mit größeren Shards besser funktionieren, da der Overhead der Kombination von Ergebnissen aus vielen winzigen Shards erheblich werden kann.
  • Indexierungsrate: Hohe Indexierungsraten könnten von mehr Shards profitieren, um die Schreiblast zu verteilen, aber zu viele können Overhead verursachen.
  • Knotenspezifikationen: Die CPU, der RAM (JVM-Heap-Größe) und der Festplattentyp (SSD vs. HDD) Ihrer Datenknoten sind entscheidend. Leistungsstärkere Knoten können mehr Shards oder größere Shards verarbeiten.
  • Cluster-Topologie: Die Gesamtzahl der verfügbaren Datenknoten zur Verteilung der Shards wirkt sich direkt auf die mögliche Anzahl von Shards aus.

Die Kompromisse: Zu viele vs. zu wenige Shards

Die optimale Balance zu finden bedeutet, die Konsequenzen beider Extreme zu verstehen.

Folgen von zu vielen Shards

Obwohl mehr Shards mehr Parallelität zu bieten scheinen, gibt es einen Punkt des abnehmenden Grenznutzens:

  • Höherer Overhead: Jeder Shard verbraucht CPU und Arbeitsspeicher (JVM-Heap) für seine Metadaten, offenen Dateien, Segmentzusammenführungen usw. Zu viele Shards auf einem Knoten führen zu einem höheren Gesamtressourcenverbrauch für die Verwaltung der Shards selbst, sodass weniger für die eigentliche Datenverarbeitung übrig bleibt.
    • Tipp: Ältere Shard-pro-Heap-Regeln waren als grobe Warnungen nützlich, aber moderne Elasticsearch-Versionen haben den Shard-pro-Heap-Overhead reduziert. Dennoch verschwendet ein Cluster mit Tausenden von winzigen Shards Speicher und erschwert die Arbeit des Cluster-Zustands.
  • Langsamere Wiederherstellung: Während Knotenausfällen oder Rebalancing dauert die Verwaltung und Verschiebung vieler kleiner Shards länger und erfordert mehr Netzwerk-I/O als eine geringere Anzahl größerer Shards.
  • Erhöhte Ressourcenkonkurrenz: Wenn viele Shards auf demselben Knoten aktiv Operationen durchführen (z. B. Segmentzusammenführungen, Beantwortung von Abfragen), konkurrieren sie um CPU, Arbeitsspeicher und Festplatten-I/O, was zu einer insgesamt langsameren Leistung führt.
  • "Shard Bloat": Ein Cluster mit vielen kleinen, meist leeren Shards ist ineffizient. Er verbraucht Ressourcen für die Verwaltung ohne proportionale Datennutzen.

Folgen von zu wenigen Shards

Umgekehrt bringt auch die Verwendung zu weniger Shards erhebliche Herausforderungen mit sich:

  • Begrenzte Parallelisierung: Wenn ein Index nur wenige große Shards hat, können Suchabfragen nicht die volle Rechenleistung Ihres Clusters nutzen, da die Arbeitslast nicht auf viele Knoten/Kerne verteilt werden kann.
  • Hot Spots: Ein großer Shard auf einem einzelnen Knoten kann zu einem "Hot Spot" werden, wenn er eine unverhältnismäßige Anzahl von Lese- oder Schreibanfragen erhält, was zu einer Ressourcensättigung auf diesem spezifischen Knoten führt.
  • Schwierigkeiten beim horizontalen Skalieren: Wenn Ihr Index beispielsweise nur 5 Primär-Shards hat, können Sie diesen Index effektiv nur auf maximal 5 Datenknoten verteilen. Das Hinzufügen weiterer Knoten hilft nicht bei der Leistung dieses bestimmten Index, wenn sich alle Shards bereits auf verschiedenen Knoten befinden.
  • Langsameres Rebalancing: Das Verschieben eines einzelnen sehr großen Shards über das Netzwerk während des Rebalancings ist ein zeitaufwändiger und I/O-intensiver Vorgang, der möglicherweise die Cluster-Stabilität beeinträchtigt.
  • Längere Wiederherstellungszeiten: Ein einzelner großer Shard, der wiederhergestellt oder kopiert werden muss, kann die Wiederherstellungszeit des Clusters nach einem Ausfall erheblich verlängern.

Allgemeine Empfehlungen & Best Practices

Obwohl keine einzelne Regel für alle passt, bieten einige allgemein akzeptierte Richtlinien einen guten Ausgangspunkt.

Ziel-Shard-Größe

Die am häufigsten zitierte Empfehlung für eine einzelne Shard-Größe (nach der Indexierung und möglichen Zusammenführungen) liegt zwischen 10 GB und 50 GB. Einige Quellen erweitern dies auf bis zu 100 GB für bestimmte Szenarien (z. B. Zeitreihendaten mit hauptsächlich Anhänge-Schreibvorgängen und weniger komplexen Abfragen). Dieser Bereich bietet im Allgemeinen eine gute Balance zwischen Verwaltbarkeit, Wiederherstellungsgeschwindigkeit und effizienter Ressourcennutzung.

  • Warum dieser Bereich?:
    • Wiederherstellung: Shards in diesem Bereich können sich nach einem Knotenausfall relativ schnell erholen.
    • Leistung: Sie sind groß genug, um den Overhead zu minimieren, aber klein genug, um eine effiziente Verarbeitung und schnelle Zusammenführungen zu ermöglichen.
    • Skalierbarkeit: Ermöglicht eine flexible Verteilung auf Knoten.

Shards pro Knoten

Vermeiden Sie eine übermäßige Anzahl von Shards auf einem einzelnen Knoten. Elasticsearch erzwingt in modernen Versionen Cluster-Shard-Limits, und Ihr praktisches Limit hängt von Heap, Mappings, Abfragevolumen und Festplattengeschwindigkeit ab. Verwenden Sie die Shard-Anzahl als Warnmetrik und bestätigen Sie dann mit JVM-Druck, Cluster-Zustands-Aktualisierungslatenz sowie Such-/Indexierungslatenz.

Hot-Warm-Cold-Architektur & Shard-Größe

In einer Hot-Warm-Cold (HWC)-Architektur kann die Shard-Größe variieren:

  • Hot-Tier: Datenknoten, die aktive Schreibvorgänge empfangen und häufig abgefragt werden. Hier könnten Sie sich für etwas mehr Shards oder kleinere Shards entscheiden, um den Indexierungsdurchsatz und die Abfrageparallelität zu maximieren.
  • Warm/Cold-Tier: Knoten, die ältere, seltener abgerufene Daten enthalten. Diese Shards sind typischerweise größer, da die Indexierung gestoppt ist und Zusammenführungen abgeschlossen sind. Größere Shards (bis zu 100 GB+) können hier akzeptabel sein, um die Gesamtzahl der Shards und den damit verbundenen Overhead zu reduzieren, insbesondere bei kostenoptimiertem Speicher.

Replicas

Verwenden Sie immer Replicas! Ein Minimum von einer Replica pro Primär-Shard (insgesamt 2 Kopien Ihrer Daten) ist entscheidend für hohe Verfügbarkeit. Replicas erhöhen auch die Lesekapazität, indem sie Suchanfragen verteilen. Die optimale Anzahl von Replicas hängt von Ihren Verfügbarkeitsanforderungen und Ihrer Abfragelast ab.

Praktische Strategie zur Bestimmung der Shard-Größe

Hier ist ein schrittweiser Ansatz, um eine anfängliche Shard-Größenstrategie abzuleiten, gefolgt von einem iterativen Verfeinerungsprozess.

Schritt 1: Gesamtdatenvolumen & Wachstum schätzen

Prognostizieren Sie, wie viele Daten Ihr Index (oder Ihre rollierenden täglichen/monatlichen Indizes) während seines Lebenszyklus enthalten wird. Berücksichtigen Sie die durchschnittliche Dokumentgröße.

  • Beispiel: Sie erwarten, 100 GB Daten pro Tag aufzunehmen und diese 30 Tage lang aufzubewahren. Ihre gesamten aktiven Daten werden ungefähr 3 TB betragen (100 GB/Tag * 30 Tage).

Schritt 2: Ziel-Shard-Größe bestimmen

Beginnen Sie mit der allgemeinen Empfehlung von 30 GB-50 GB pro Primär-Shard. Passen Sie basierend auf Ihrem Anwendungsfall an:

  • Kleinere Shards (z. B. 10-20 GB): Wenn Sie einen sehr hohen Abfragedurchsatz, komplexe Aggregationen bei großen Dokumenten oder sehr häufig wechselnde Daten haben.

  • Größere Shards (z. B. 50-100 GB): Wenn Sie hauptsächlich Zeitreihendaten, Anhänge-Indizes oder weniger häufige, einfachere Abfragen haben.

  • Beispiel (Fortsetzung von Schritt 1): Lassen Sie uns eine durchschnittliche Primär-Shard-Größe von 50 GB anstreben.

Schritt 3: Anfängliche Anzahl der Primär-Shards berechnen

Teilen Sie Ihr geschätztes Gesamtdatenvolumen durch Ihre Ziel-Shard-Größe.

Anzahl der Primär-Shards = (Gesamtdatenvolumen) / (Ziel-Shard-Größe)

  • Beispiel: 3000 GB / 50 GB = 60 Primär-Shards.

Schritt 4: Knotenressourcen und Heap-Größe berücksichtigen

Bestimmen Sie, wie viele Primär- und Replica-Shards Ihr Cluster bequem hosten kann, unter Beachtung der Shards-pro-GB-Heap-Regel.

  • Heap pro Knoten: Nehmen wir an, Sie haben Datenknoten mit jeweils 30 GB JVM-Heap.
  • Maximale Shards pro Knoten (ca.): Unter Verwendung der 10-20 Shards pro GB Heap-Regel könnte ein 30-GB-Heap-Knoten 30 * 10 = 300 bis 30 * 20 = 600 Shards hosten.
  • Gesamtzahl der Replicas: Wenn Sie 1 Replica verwenden (sehr empfehlenswert), haben Sie 60 Primär-Shards + 60 Replica-Shards = 120 Shards insgesamt.
  • Anzahl der Datenknoten: Stellen Sie sicher, dass diese Shards verteilt werden können, ohne eine Replica auf demselben Knoten wie ihr Primär-Shard zu platzieren. Verwenden Sie für die Produktionsresilienz genügend Datenknoten und -zonen, sodass ein Knoten- oder Zonenausfall nicht dazu führt, dass Sie nicht zugewiesene Replicas haben.

Beispielszenario

Nehmen wir einen 3-Knoten-Datencluster an, jeder mit 30 GB Heap:

  • Unsere aktuell berechneten Gesamt-Shards: 120 Shards (60 primär + 60 replica)
  • Durchschnittliche Shards pro Knoten: 120 Gesamt-Shards / 3 Knoten = 40 Shards pro Knoten.
  • Die Anzahl ist nur dann angemessen, wenn Heap-Druck, Festplatten-I/O, Indexierungslatenz und Suchlatenz unter Last gesund bleiben.

Schritt 5: Testen und Überwachen

Dies ist der kritischste Schritt. Ihre theoretischen Berechnungen sind nur ein Ausgangspunkt.

  • Lasttests: Simulieren Sie Ihre erwarteten Indexierungs- und Abfragemuster. Beobachten Sie Leistungsmetriken.

  • Überwachungstools: Verwenden Sie die integrierte Überwachung von Kibana, die _cat-APIs von Elasticsearch oder externe Überwachungstools (z. B. Prometheus, Grafana), um Folgendes im Auge zu behalten:

    • _cat/shards: Überprüfen Sie Shard-Größen und -Verteilung.
    • _cluster/stats: Cluster-weite Statistiken, insbesondere zur JVM-Heap-Nutzung.
    • CPU, Arbeitsspeicher und Festplatten-I/O auf einzelnen Knoten.
    • Indexierungs- und Suchlatenzen.
    • Segmentzusammenführungsaktivität.
    # Shard-Zuordnungs- und Größeninformationen abrufen
    GET _cat/shards?v=true&h=index,shard,prirep,state,docs,store,node
    
    # Cluster-Statistiken für Heap-Nutzung und Shard-Anzahl abrufen
    GET _cluster/stats
    

Schritt 6: Iterative Anpassung

Basierend auf Ihrer Überwachung sollten Sie darauf vorbereitet sein, Ihre Shard-Anzahl anzupassen. Dies könnte Folgendes umfassen:

  • Shrink-API: Wenn Sie zu viele Primär-Shards für einen Index haben, der nicht mehr beschrieben wird, können Sie die _shrink-API verwenden, um die Anzahl der Primär-Shards zu reduzieren. Der Index muss schreibgeschützt sein, und die Shard-Platzierung muss die Shrink-Anforderungen erfüllen.
  • Split-API: Wenn die Shards eines Index zu groß werden und die Leistung leidet, kann die _split-API die Anzahl der Primär-Shards erhöhen. Der Index muss schreibgeschützt sein und mit einer kompatiblen Routing-Shard-Anzahl erstellt worden sein.
  • Reindex-API: Für komplexere Änderungen, wie das Ändern des Mappings oder die Änderung der Anzahl der Shards für einen live, aktiv beschriebenen Index, müssen Sie Ihre Daten möglicherweise in einen neuen Index mit einer anderen Shard-Konfiguration neu indizieren.

Häufige Fallstricke und wie man sie vermeidet

  • Blindes Übersharding: Erstellen von 1 Shard pro GB Daten auf kleinen Clustern, was zu übermäßigem Overhead führt. Vermeiden: Beginnen Sie mit vernünftigen Zielen und skalieren Sie die Shards hoch, wenn die Daten wachsen.
  • Untersharding eines Index: Nur 1-3 Shards für einen sehr großen Index zu haben, was die Parallelisierung und Skalierbarkeit einschränkt. Vermeiden: Berechnen Sie basierend auf Datenvolumen und Knotenkapazität.
  • Ignorieren von Wachstumsprognosen: Dimensionierung für aktuelle Daten ohne Berücksichtigung zukünftiger Aufnahme. Vermeiden: Berücksichtigen Sie immer das erwartete Datenwachstum für die Lebensdauer Ihrer Daten.
  • Nicht überwachen: Einrichten und Vergessen. Shard-Größen, Knotenressourcen und Abfrageleistung ändern sich im Laufe der Zeit. Vermeiden: Implementieren Sie eine robuste Überwachung und Warnungen für wichtige Metriken.
  • Blindes Befolgen von Faustregeln: Die 10-GB-50-GB-Regel ist eine Richtlinie, kein strenges Gesetz. Ihre spezifische Arbeitslast kann Abweichungen vorgeben. Vermeiden: Validieren Sie allgemeine Empfehlungen immer mit Ihren tatsächlichen Daten und Nutzungsmustern.

Praktische Erkenntnisse

Wählen Sie eine anfängliche Shard-Anzahl basierend auf dem erwarteten Datenvolumen und einer Ziel-Shard-Größe und beweisen Sie diese dann mit Lasttests. Beobachten Sie die Wiederherstellungszeit, den Heap-Druck, die Festplatten-I/O und die Latenz nach einem Rollover oder Wachstum. Wenn die Zahlen abweichen, verwenden Sie Rollover, Shrink, Split oder Reindexing, bevor das Shard-Layout zu einem Vorfall wird.