24 Vorteile und Herausforderungen der Datenverteilung

Sharding klingt in der Theorie elegant: Daten auf viele Server verteilen, unbegrenzt skalieren, alle Probleme lösen. Die Realität ist nuancierter. Sharding bietet echte, messbare Vorteile für Systeme, die ihre Kapazitätsgrenzen erreichen. Aber es bringt auch operative Komplexität, neue Fehlerquellen und Performance-Trade-offs mit sich. Die Entscheidung zu sharden ist keine triviale Checkbox, sondern eine fundamentale Architektur-Wahl mit langfristigen Konsequenzen.

Teams, die erfolgreich sharden, verstehen sowohl die Stärken als auch die Grenzen. Sie wissen, dass Sharding bestimmte Probleme löst, aber andere schafft. Sie planen für die erhöhte Komplexität, investieren in Monitoring und Automatisierung, und akzeptieren, dass manche Operationen langsamer werden. Teams, die schlecht sharden, unterschätzen die Herausforderungen, wählen suboptimale Shard Keys und kämpfen mit operativen Problemen, die schwer zu lösen sind.

24.1 Die Vorteile: Warum Sharding sich lohnt

Die primäre Motivation für Sharding ist Kapazität – Storage, RAM, Throughput. Ein einzelner Server hat physische Grenzen. Selbst die stärksten verfügbaren Server toppen aus bei 1-2 TB RAM, Dutzenden Cores und einigen Dutzend TB Storage. Für viele Anwendungen reicht dies. Aber für wirklich große Systeme – Social Networks, IoT-Plattformen, Analytics-Warehouses – sind diese Grenzen erreichbar.

Horizontale Skalierung von Storage: Ein Sharded Cluster kann praktisch unbegrenzt Storage bereitstellen. Jeder Shard hält einen Teil der Daten. Mit zehn Shards, jeder mit 5 TB nutzbarem Storage, hat das Cluster 50 TB Kapazität. Braucht man mehr, fügt man Shards hinzu. Ein Cluster mit hundert Shards kann Petabytes halten. Dies ist keine theoretische Obergrenze – produktive MongoDB-Deployments mit Hunderten Shards und Petabytes Daten existieren.

Die Alternative wäre vertikale Skalierung: Immer größere Server kaufen. Aber die Kosten explodieren nicht-linear. Ein Server mit doppeltem RAM kostet oft mehr als doppelt so viel. Und irgendwann gibt es einfach keine größeren Server mehr. Horizontale Skalierung durch Sharding ist oft kosteneffizienter und hat keine theoretische Obergrenze.

RAM-Skalierung für Working Sets: Das Working Set – die häufig zugegriffenen Daten – muss idealerweise in RAM passen. Für eine 10-TB-Datenbank, wo 2 TB häufig abgefragt werden, braucht man mindestens 2 TB RAM (plus Overhead) auf einem einzelnen Server. Das ist teuer und an Grenzen. Mit Sharding verteilt sich das Working Set. Zehn Shards mit je 200 GB Working Set benötigen je “nur” 250 GB RAM – deutlich günstiger pro Shard.

Der subtile Vorteil: Locality of Reference verbessert sich oft. Wenn Daten nach Customer gesharded sind, greifen Queries für Customer X nur auf Shard Y zu. Der Cache auf Shard Y optimiert sich für Customer X’s Daten. Bei einem ungesharded System müsste der globale Cache für alle Customers optimieren, was weniger effizient ist.

Throughput-Skalierung: Ein einzelner Server hat CPU- und I/O-Limits. Selbst mit 64 Cores und NVMe-SSDs gibt es Obergrenzen für Operations pro Sekunde. Mit Sharding parallelisieren sich Operationen. Eine Query, die alle Shards betrifft, läuft parallel auf allen. Ein Write-Heavy-Workload verteilt sich auf alle Shards. Das theoretische Maximum-Throughput ist die Summe aller Shards.

In der Praxis ist der Gewinn oft linear oder besser. Ein System, das auf einem Replica Set 10.000 Ops/Sekunde schafft, könnte auf einem 4-Shard-Cluster 40.000 erreichen – wenn die Workload gut verteilt ist und der mongos-Router nicht zum Bottleneck wird. Für Write-Intensive Workloads ist dies transformativ.

Ausfallsicherheit auf Shard-Ebene: Jeder Shard ist ein Replica Set. Fällt ein Shard komplett aus (alle Nodes), bleibt der Rest des Clusters funktional. Queries, die nur andere Shards betreffen, laufen weiter. Ja, ein Teil der Daten ist nicht verfügbar, aber das System ist nicht komplett down. Bei einem ungesharded Replica Set wäre ein Total-Ausfall des gesamten Sets ein kompletter Stillstand.

Dies ist besonders wertvoll für Partial-Outage-Szenarien. Ein Datacenter-Ausfall, der einen Shard komplett killt, beeinträchtigt nur die Daten auf diesem Shard. Für Multi-Tenant-Systeme, wo jeder Tenant auf einem Shard konzentriert ist, bedeutet dies, dass nur ein Bruchteil der Tenants betroffen ist.

graph TB
    subgraph "Ungesharded - Total Ausfall"
        RS[Replica Set<br/>ALLE Daten]
        RS -.x.-> FAIL[X Komplett Down]
    end
    
    subgraph "Sharded - Partial Verfügbarkeit"
        S1[Shard 1<br/>20% Daten<br/>Verfügbar]
        S2[Shard 2<br/>20% Daten<br/>DOWN]
        S3[Shard 3<br/>20% Daten<br/>Verfügbar]
        S4[Shard 4<br/>20% Daten<br/>Verfügbar]
        S5[Shard 5<br/>20% Daten<br/>Verfügbar]
        
        S2 -.x.-> PFAIL[X Ein Shard Down<br/>80% verfügbar]
    end
    
    style FAIL fill:#fce4ec
    style RS fill:#fce4ec
    style S2 fill:#fce4ec
    style S1 fill:#4caf50
    style S3 fill:#4caf50
    style S4 fill:#4caf50
    style S5 fill:#4caf50

24.2 Die Herausforderungen: Was Sharding kostet

Die Vorteile sind real, aber Sharding ist kein kostenloses Lunch. Die erhöhte Komplexität manifestiert sich in mehreren Dimensionen.

Shard-Key-Wahl als permanente Entscheidung: Wir haben dies in vorherigen Kapiteln besprochen, aber es verdient Wiederholung: Die Shard-Key-Wahl ist kritisch und schwer zu ändern. Ein schlechter Shard Key führt zu ungleicher Verteilung, Hotspots und suboptimaler Performance. Resharding ist möglich seit MongoDB 5.0, aber aufwendig bei großen Datasets. Teams verbringen oft Wochen mit Shard-Key-Design, Prototyping und Testing, bevor sie sich committen.

Der psychologische Druck ist real. Bei einem Replica Set kann man Schema und Indizes iterativ verbessern. Bei Sharding fühlt sich die Shard-Key-Entscheidung final an. Dies führt manchmal zu Analysis-Paralysis – Teams sharden nicht, weil sie Angst haben, den falschen Key zu wählen. Die Realität: Perfekt gibt es nicht. Ein “gut genug” Shard Key, der die Hauptprobleme löst, ist besser als gar nicht zu sharden aus Angst vor Fehlern.

Scatter-Gather-Queries und Performance-Degradation: Queries ohne Shard Key müssen an alle Shards gehen. Der mongos sendet die Query parallel an alle, wartet auf Responses, merged die Resultate. Dies ist langsamer als eine Query auf einem einzelnen Shard, aus mehreren Gründen.

Die Latenz ist mindestens die des langsamsten Shards. Wenn neun Shards in 10 ms antworten, aber einer braucht 100 ms (wegen temporärer Last oder langsamer Disk), dauert die gesamte Query 100 ms. Bei mehr Shards steigt die Wahrscheinlichkeit eines langsamen Outliers.

Der Network-Overhead addiert sich. Jeder Shard returned Daten zu mongos, der sie über das Netzwerk empfängt und merged. Bei großen Resultsets kann dies signifikanten Traffic erzeugen. Ein Query, der 10.000 Dokumente returned, könnte bei 10 Shards 100.000 Dokumente netzwerk-intern bewegen (jeder Shard returned 10.000, mongos merged und returned finale 10.000 an Client).

Aggregations-Pipelines können besonders leiden. Manche Stages müssen auf mongos laufen, weil sie globale Daten benötigen. $sort etwa muss alle Daten sehen, um global zu sortieren. Dies bedeutet, alle Shards senden unsortierte Daten zu mongos, der sortiert und returned. Bei Terabytes Daten ist dies ineffizient.

Die Lösung ist, Queries shard-aware zu designen. Apps sollten wissen, welche Queries shard-isoliert sind (enthalten Shard Key) und welche nicht. Performance-kritische Queries sollten shard-isoliert sein. Für Analytics oder Batch-Jobs, die sowieso langsam sind, sind Scatter-Gather-Queries akzeptabel.

Chunk-Migration und Balancing-Overhead: Der Balancer ist essentiell, aber nicht kostenlos. Chunk-Migrationen bewegen Daten über das Netzwerk, konsumieren I/O auf Quell- und Ziel-Shard, und erzeugen temporäre Last. Bei sehr großen Chunks (Gigabytes) können Migrationen Minuten oder Stunden dauern.

Während einer Migration ist Performance oft beeinträchtigt. Der Quell-Shard muss Writes zu migrierenden Daten tracken, um sie nach dem Initial-Copy zu synchronisieren. Der Ziel-Shard schreibt große Mengen neuer Daten. Beide Shards sind gestresster als normal.

Für Produktionssysteme wird Balancing oft auf Low-Traffic-Fenster beschränkt – nachts oder an Wochenenden. Dies verhindert, dass Migrationen Peak-Traffic beeinträchtigen. Aber es bedeutet auch, dass Ungleichgewichte länger bestehen. Ein neuer Shard, der hinzugefügt wird, könnte Tage brauchen, bis er seinen vollen Anteil der Daten hat, wenn Balancing nur nachts läuft.

Operative Komplexität und Monitoring: Ein Sharded Cluster hat mehr bewegliche Teile als ein Replica Set. Config Servers, mongos-Router, mehrere Shard-Replica-Sets – jede Komponente kann ausfallen oder Probleme haben. Das Monitoring muss alle diese Komponenten abdecken.

Typische Monitoring-Metriken für Sharded Clusters:

Das Setup dieses Monitorings ist nicht trivial. MongoDB Ops Manager oder Atlas automatisieren viel davon, aber für Self-Managed-Deployments muss man Prometheus Exporters konfigurieren, Grafana-Dashboards bauen, Alerting-Rules definieren. Dies ist Aufwand, den ein Replica Set nicht erfordert.

Transaktionen über Shards hinweg: Multi-Document-Transaktionen, eingeführt in MongoDB 4.0, funktionierten zunächst nur innerhalb eines einzelnen Replica Sets. MongoDB 4.2 erweiterte dies auf Sharded Clusters, aber mit Caveats. Transaktionen über mehrere Shards sind langsamer als Single-Shard-Transaktionen und haben strengere Limits.

Der Grund: Distributed Transactions erfordern Two-Phase-Commit-ähnliche Koordination. Der mongos koordiniert alle beteiligten Shards, um sicherzustellen, dass entweder alle committen oder alle aborten. Dies bedeutet mehr Netzwerk-Roundtrips und höheres Konflikt-Risiko. Für Anwendungen, die stark auf Transaktionen angewiesen sind, kann Sharding Performance-Probleme schaffen.

Die Best Practice: Daten so designen, dass Transaktionen meist auf einem Shard bleiben. Wenn der Shard Key customerId ist und Transaktionen Customer-spezifisch sind, sind sie Single-Shard. Multi-Shard-Transaktionen sollten die Ausnahme sein, nicht die Regel.

Backup und Disaster Recovery: Backups eines Sharded Clusters sind komplexer. Man muss nicht nur jeden Shard backen, sondern auch die Config Servers – und alles muss zeitlich konsistent sein. Ein Backup, das Shard 1 um 02:00 nimmt und Shard 2 um 03:00, ist inkonsistent, wenn Daten zwischen 02:00 und 03:00 migriert wurden.

MongoDB bietet Tools wie mongodump --oplog für konsistente Backups, aber bei Dutzenden Shards wird die Koordination knifflig. MongoDB Atlas’s Continuous Backups automatisieren dies, aber für Self-Managed-Clusters muss man die Komplexität selbst managen.

Disaster Recovery erfordert Planung. Ein kompletter Cluster-Restore ist aufwendiger als ein Replica-Set-Restore. Man muss Config Servers zuerst restoren, dann Shards, dann das Routing re-establishen. Testing dieser Prozeduren ist kritisch – und oft vernachlässigt.

24.3 Trade-offs akzeptieren: Wann Sharding sich lohnt

Die Entscheidungsmatrix für Sharding ist keine Checkliste, sondern eine Abwägung. Die Vorteile – unbegrenzte Skalierung, höherer Throughput, Partial-Outage-Resilienz – sind signifikant. Die Kosten – operative Komplexität, Query-Performance-Trade-offs, Shard-Key-Commitment – sind real.

Sharding lohnt sich, wenn:

Die Datenbank groß ist oder schnell wächst. Hunderte Gigabytes oder Terabytes, mit Wachstum von Gigabytes oder Terabytes pro Monat. Ein Replica Set wird bald an Grenzen stoßen.

Der Throughput einzelne Server überfordert. Zehntausende Writes pro Sekunde oder hunderttausende Reads, die ein Replica Set nicht mehr effizient bedienen kann.

Vertikale Skalierung zu teuer oder unmöglich wird. Der nächste RAM-Upgrade kostet fünfstellig, oder es gibt einfach keine größeren Server mehr.

Die Workload gut partitionierbar ist. Es gibt einen klaren Shard Key mit guter Cardinality und Distribution. Die meisten Queries sind shard-isolierbar.

Sharding lohnt sich nicht, wenn:

Die Datenbank klein ist. Unter 100 GB, langsames Wachstum. Ein Replica Set ist deutlich simpler.

Die Workload nicht partitionierbar ist. Jede Query braucht globale Sicht auf alle Daten. Sharding macht alles langsamer.

Das Team keine operative Kapazität hat. Sharding erfordert Expertise und Monitoring. Ein unterbesetztes Team kämpft mit der Komplexität.

Die Kosten nicht gerechtfertigt sind. Ein größerer Server ist teurer als mehrere kleinere, aber einfacher zu managen. Manchmal ist “teurer aber einfach” die bessere Wahl.

Die folgende Tabelle fasst die Trade-offs zusammen:

Aspekt Replica Set Sharded Cluster
Maximale Datengröße ~10 TB praktisch Praktisch unbegrenzt
Maximaler Throughput ~50k ops/sec Skaliert linear mit Shards
Query-Performance Exzellent Gut (mit Shard Key), mäßig (ohne)
Transaktions-Performance Exzellent Gut (Single-Shard), mäßig (Multi-Shard)
Operative Komplexität Niedrig Hoch
Monitoring-Aufwand Moderat Hoch
Setup-Zeit Stunden Tage bis Wochen
Kostenpunkt Hardware für 3-5 Nodes Hardware für 10-30+ Nodes
Failure-Modus Total Outage bei kompletten Ausfall Partial Outage möglich
Schema-Flexibilität Hoch Shard Key limitiert

Sharding ist keine Default-Entscheidung, sondern eine bewusste Architektur-Wahl für spezifische Skalierungs-Anforderungen. Für die meisten MongoDB-Deployments ist ein Replica Set ausreichend und deutlich simpler. Aber wenn die Grenzen erreicht sind, ist Sharding die einzige Möglichkeit, weiter zu skalieren. Die Herausforderung ist, den richtigen Zeitpunkt zu erkennen – nicht zu früh (unnötige Komplexität) und nicht zu spät (Notfall-Migration unter Last).

Die erfolgreichsten Sharding-Deployments starten mit gründlicher Planung: Workload-Analyse, Shard-Key-Simulation, Monitoring-Setup, und Team-Training. Sie akzeptieren, dass manche Dinge langsamer werden, optimieren dafür, und genießen die unbegrenzte Skalierbarkeit, die Sharding ermöglicht. Die weniger erfolgreichen sharden ad-hoc, unterschätzen die Komplexität, und kämpfen mit Performance-Problemen, die schwer zu lösen sind. Der Unterschied liegt in der Vorbereitung.