Horizontale Partitionierung, die spaeter nicht zum Problem wird
Sharding verteilt eine grosse Tabelle auf mehrere unabhaengige Datenbank-Instanzen, wenn eine einzelne Instanz an ihre Kapazitaetsgrenze stoesst. Die Wahl des Shard-Keys entscheidet dabei ueber die gesamte Lebensdauer der Architektur, denn ein falsch gewaehlter Shard-Key laesst sich nur mit erheblichem Migrationsaufwand nachtraeglich korrigieren.
Inhaltsverzeichnis
- 1. Was Sharding wirklich loest
- 2. Die Wahl des Shard-Keys entscheidet alles
- 3. Hash-Sharding vs. Range-Sharding
- 4. Hotspots erkennen und vermeiden
- 5. Cross-Shard-Queries und ihre Kosten
- 6. Resharding: Shards spaeter neu aufteilen
- 7. Shard-Routing in der Anwendungsschicht
- 8. Alternativen zu manuellem Sharding
- 9. Sharding-Strategien im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Was Sharding wirklich loest
Sharding teilt eine grosse Tabelle horizontal auf mehrere unabhaengige Datenbank-Instanzen auf, sogenannte Shards, wobei jeder Shard nur einen Teil der Zeilen enthaelt. Anders als vertikale Partitionierung, die Spalten aufteilt, oder Replikation, die die gesamte Tabelle kopiert, reduziert Sharding die Datenmenge pro Instanz tatsaechlich. Das ist relevant, sobald eine einzelne Datenbank-Instanz an ihre Grenzen stoesst, sei es bei Speicherplatz, Schreibdurchsatz oder Indexgroesse, die nicht mehr in den Arbeitsspeicher passt.
Der entscheidende Unterschied zu einfacher Skalierung durch groessere Hardware: Sharding skaliert horizontal, also durch das Hinzufuegen weiterer Instanzen, statt vertikal durch staerkere Einzelhardware. Dieser Ansatz hat kein prinzipielles Limit, bringt aber erhebliche Komplexitaet mit sich, die sorgfaeltig gegen den tatsaechlichen Bedarf abgewogen werden muss. Die folgenden Abschnitte zeigen, wie ein Shard-Key gewaehlt wird, welche Sharding-Strategien existieren und wie Cross-Shard-Queries und Resharding in der Praxis funktionieren.
2. Die Wahl des Shard-Keys entscheidet alles
Der Shard-Key ist die Spalte oder Spaltenkombination, anhand derer entschieden wird, auf welchem Shard eine Zeile landet. Diese Entscheidung ist bei Sharding die wichtigste ueberhaupt, weil sie sich nachtraeglich nur mit einer aufwendigen Datenmigration aendern laesst. Ein guter Shard-Key verteilt Daten gleichmaessig ueber alle Shards, wird bei den meisten Queries mitgegeben (um Cross-Shard-Abfragen zu vermeiden) und aendert sich nach dem Anlegen einer Zeile nie mehr.
Ein haeufiger Fehler ist die Wahl eines Shard-Keys, der spaeter aendert, etwa der Status eines Kundenkontos. Aendert sich der Wert des Shard-Keys, muss die gesamte Zeile physisch auf einen anderen Shard verschoben werden, ein teurer und fehleranfaelliger Vorgang. Fuer Multi-Tenant-SaaS-Anwendungen ist eine Tenant-ID oder Kunden-ID meist der natuerliche Shard-Key, weil praktisch alle Queries ohnehin nach Tenant gefiltert werden und der Wert stabil bleibt.
-- Good shard key: stable, present in most queries, evenly distributed
CREATE TABLE orders (
order_id BIGINT NOT NULL,
tenant_id INT NOT NULL, -- shard key: stable, never changes after creation
customer_id INT NOT NULL,
total_amount NUMERIC(10,2),
created_at TIMESTAMP NOT NULL,
PRIMARY KEY (tenant_id, order_id)
);
-- Every query should include the shard key to stay single-shard
SELECT * FROM orders
WHERE tenant_id = 4821 AND created_at > '2026-07-01';
-- Anti-pattern: querying without the shard key requires
-- fanning out to every shard (avoid in hot paths)
SELECT * FROM orders WHERE customer_id = 998877;
3. Hash-Sharding vs. Range-Sharding
Hash-Sharding wendet eine Hash-Funktion auf den Shard-Key an und bestimmt darueber den Ziel-Shard, meist ueber einen Modulo auf die Anzahl der Shards. Dieses Sharding-Verfahren verteilt Daten sehr gleichmaessig, weil eine gute Hash-Funktion Werte praktisch zufaellig streut. Der Nachteil: Range-Abfragen ueber den Shard-Key (etwa "alle Bestellungen von Kunde 100 bis 200") sind nicht mehr moeglich, weil benachbarte Werte auf komplett unterschiedlichen Shards landen koennen.
Range-Sharding teilt den Shard-Key-Wertebereich in zusammenhaengende Intervalle auf, etwa Kunden-IDs 1 bis 1.000.000 auf Shard 1, 1.000.001 bis 2.000.000 auf Shard 2. Dieses Sharding-Verfahren erlaubt effiziente Range-Queries, hat aber ein Risiko: Ungleichmaessige Datenverteilung, wenn bestimmte Wertebereiche deutlich mehr Aktivitaet haben als andere, etwa bei zeitbasierten Shard-Keys, bei denen der aktuellste Bereich immer die meiste Schreiblast traegt.
-- Hash-based shard assignment (application layer, pseudocode as SQL comment)
-- shard_id = hash(tenant_id) % number_of_shards
-- Range-based sharding: explicit shard map table
CREATE TABLE shard_map (
range_start BIGINT NOT NULL,
range_end BIGINT NOT NULL,
shard_id SMALLINT NOT NULL
);
INSERT INTO shard_map (range_start, range_end, shard_id) VALUES
(1, 1000000, 1),
(1000001, 2000000, 2),
(2000001, 3000000, 3);
-- Lookup which shard a given tenant_id belongs to
SELECT shard_id FROM shard_map
WHERE 1542871 BETWEEN range_start AND range_end;
4. Hotspots erkennen und vermeiden
Ein Hotspot entsteht, wenn ein einzelner Shard deutlich mehr Last traegt als die anderen, meist weil der Shard-Key ungleich verteilt ist. Ein klassisches Beispiel: Ein monoton steigender Bestellwert als Shard-Key konzentriert alle neuen Schreiboperationen auf dem zuletzt angelegten Shard, waehrend aeltere Shards praktisch nur noch Leseoperationen sehen. Dieses Muster untergraebt den gesamten Zweck von Sharding, weil die Schreiblast eben nicht gleichmaessig verteilt wird.
Erkennen laesst sich ein Hotspot ueber Monitoring der Anfragen pro Shard, meist durch Aggregation von Datenbank-Metriken pro Instanz. Ein gutes Fruehwarnsignal ist eine deutlich hoehere CPU- oder I/O-Auslastung eines einzelnen Shards im Vergleich zum Durchschnitt aller Shards. Vermeiden laesst sich das Problem meist durch einen zusammengesetzten Shard-Key, der einen zeitbasierten Anteil mit einem gleichverteilten Anteil kombiniert, etwa Tenant-ID plus Zeitstempel statt reinem Zeitstempel.
5. Cross-Shard-Queries und ihre Kosten
Eine Query, die den Shard-Key nicht in der WHERE-Klausel enthaelt, muss auf alle Shards ausgestreut werden (Scatter-Gather), und die Ergebnisse muessen anschliessend in der Anwendungsschicht zusammengefuehrt werden. Diese Cross-Shard-Queries sind bei Sharding deutlich teurer als Single-Shard-Queries, weil sie die Latenz des langsamsten Shards erben und zusaetzliche Netzwerk-Roundtrips erzeugen.
Aggregationen ueber alle Shards (etwa eine globale Summe) sind ein besonders teurer Fall von Cross-Shard-Queries, weil jeder Shard eine Teilsumme berechnen muss und die Anwendung diese Teilsummen anschliessend zusammenfuehrt. Fuer haeufig benoetigte Cross-Shard-Aggregationen lohnt sich ein separates Analytics-System (etwa ein Data Warehouse), das Daten aus allen Shards periodisch zusammenfuehrt, statt Cross-Shard-Queries im Live-Betrieb zu wiederholen.
-- Cross-shard aggregation: each shard computes a partial sum,
-- application layer combines the results
-- Shard 1
SELECT tenant_id, SUM(total_amount) AS partial_sum
FROM orders WHERE created_at > '2026-07-01'
GROUP BY tenant_id;
-- Shard 2 (same query, different shard connection)
SELECT tenant_id, SUM(total_amount) AS partial_sum
FROM orders WHERE created_at > '2026-07-01'
GROUP BY tenant_id;
-- Application layer merges partial sums per tenant_id
-- total = shard1.partial_sum + shard2.partial_sum + ...
6. Resharding: Shards spaeter neu aufteilen
Resharding wird noetig, wenn ein einzelner Shard trotz sorgfaeltiger Shard-Key-Wahl zu gross wird oder ungleichmaessig belastet ist. Der Prozess besteht darin, einen bestehenden Shard in zwei oder mehr neue Shards aufzuteilen und die betroffenen Daten zu migrieren, waehrend das System im Idealfall weiterlaeuft. Ohne sorgfaeltige Planung ist Resharding bei Sharding-Architekturen der aufwendigste und riskanteste Wartungsvorgang ueberhaupt.
Eine bewaehrte Strategie ist konsistentes Hashing, das beim Hinzufuegen neuer Shards nur einen Bruchteil der bestehenden Daten neu verteilen muss, statt alle Daten komplett neu zu hashen. Ein weiterer bewaehrter Ansatz: von Anfang an mehr logische Shards anlegen, als physische Instanzen vorhanden sind (etwa 1024 logische Shards auf 4 physischen Instanzen verteilt), sodass Resharding nur die Zuordnung logischer zu physischen Shards aendert, ohne einzelne Zeilen neu zu verteilen.
-- Logical shard mapping: 1024 logical shards spread over 4 physical instances
CREATE TABLE logical_shard_map (
logical_shard_id SMALLINT PRIMARY KEY,
physical_instance VARCHAR(50) NOT NULL
);
-- shard_id for a given key is always: hash(shard_key) % 1024
-- resharding only updates this mapping table, not the data rows themselves
UPDATE logical_shard_map
SET physical_instance = 'shard-db-05'
WHERE logical_shard_id IN (768, 769, 770, 771);
7. Shard-Routing in der Anwendungsschicht
Die Anwendungsschicht muss bei jeder Query wissen, welcher Shard fuer den jeweiligen Shard-Key zustaendig ist. Diese Routing-Logik gehoert in eine zentrale, gut getestete Bibliothek, statt in jeder einzelnen Codestelle dupliziert zu werden. Ein zentraler Shard-Router reduziert das Risiko, dass ein Entwickler versehentlich auf den falschen Shard zugreift oder eine Query ohne Shard-Key schreibt, die unnoetig auf alle Shards ausgestreut wird.
Manche Datenbanksysteme bieten native Sharding-Unterstuetzung mit transparentem Routing (etwa Vitess fuer MySQL oder Citus fuer PostgreSQL), sodass Anwendungscode sich nicht um die Shard-Zuordnung kuemmern muss. Diese Loesungen reduzieren den Implementierungsaufwand erheblich, bringen aber eigene operative Komplexitaet mit, etwa beim Betrieb des Routing-Layers selbst.
-- Citus (PostgreSQL extension): distribute a table transparently by shard key
SELECT create_distributed_table('orders', 'tenant_id');
-- Queries look identical to a single-instance table,
-- Citus routes them to the correct physical shard automatically
SELECT tenant_id, SUM(total_amount)
FROM orders
WHERE tenant_id = 4821
GROUP BY tenant_id;
8. Alternativen zu manuellem Sharding
Bevor man Sharding einfuehrt, lohnt sich die Pruefung einfacherer Alternativen. Vertikale Skalierung, also groessere Hardware fuer eine einzelne Instanz, loest viele Kapazitaetsprobleme deutlich einfacher, solange die Grenzen der verfuegbaren Hardware noch nicht erreicht sind. Read-Replicas loesen Leselast-Probleme, ohne die Komplexitaet von Sharding einzufuehren, solange das eigentliche Problem Leselast und nicht Schreiblast oder Speicherplatz ist.
Auch Archivierung alter Daten in separate, seltener abgefragte Tabellen reduziert die effektive Groesse der Haupttabelle, ohne Sharding einzufuehren. Erst wenn diese einfacheren Massnahmen nicht mehr ausreichen und die Schreiblast oder Datenmenge die Kapazitaet einer einzelnen Instanz strukturell uebersteigt, ist Sharding die richtige Wahl, denn die zusaetzliche Komplexitaet rechtfertigt sich nur bei echtem Bedarf.
9. Sharding-Strategien im Vergleich
Die folgende Tabelle vergleicht die gaengigen Sharding-Ansaetze anhand ihrer wichtigsten Eigenschaften.
| Ansatz | Verteilung | Range-Queries | Resharding-Aufwand |
|---|---|---|---|
| Hash-Sharding | Sehr gleichmaessig | Nicht moeglich | Hoch ohne Consistent Hashing |
| Range-Sharding | Hotspot-Risiko | Effizient | Mittel |
| Consistent Hashing | Sehr gleichmaessig | Nicht moeglich | Niedrig |
| Native Loesung (Vitess, Citus) | Konfigurierbar | Teilweise | Vom System uebernommen |
Fuer die meisten Anwendungen ist eine Kombination aus zusammengesetztem Shard-Key und Consistent Hashing der pragmatischste Weg, um gleichmaessige Verteilung mit vertretbarem Resharding-Aufwand zu kombinieren. Native Sharding-Loesungen lohnen sich, sobald der Betriebsaufwand einer selbstgebauten Loesung die Lernkurve eines etablierten Systems uebersteigt.
Mironsoft
Data Engineering, Skalierungs-Architektur und Sharding-Strategie
Grosse Tabellen an ihrer Kapazitaetsgrenze?
Wir bewerten, ob Sharding wirklich noetig ist, waehlen den richtigen Shard-Key und planen Resharding-Faehigkeit von Anfang an mit ein, statt spaeter teuer nachzubessern.
Shard-Key-Analyse
Datenzugriffsmuster analysieren und den passenden Shard-Key ableiten
Hotspot-Vermeidung
Zusammengesetzte Shard-Keys und Monitoring gegen ungleiche Lastverteilung
Resharding-Planung
Consistent Hashing und logische Shards fuer risikoarmes Wachstum
10. Zusammenfassung
Sharding verteilt eine grosse Tabelle horizontal auf mehrere unabhaengige Instanzen und loest damit Kapazitaetsgrenzen, die vertikale Skalierung nicht mehr bewaeltigt. Die Wahl des Shard-Keys ist die wichtigste Entscheidung der gesamten Architektur, weil sie sich nachtraeglich nur mit erheblichem Migrationsaufwand aendern laesst. Hash-Sharding verteilt gleichmaessig, verliert aber Range-Query-Faehigkeit, Range-Sharding erhaelt Range-Queries, riskiert aber Hotspots.
Cross-Shard-Queries sind bei Sharding strukturell teuer und sollten auf Ausnahmen beschraenkt bleiben, waehrend haeufige Aggregationen ueber alle Shards besser in ein separates Analytics-System ausgelagert werden. Resharding-Faehigkeit sollte von Anfang an mitgeplant werden, etwa durch Consistent Hashing oder mehr logische als physische Shards, um spaeteres Wachstum ohne kompletten Neuaufbau zu ermoeglichen.
Sharding-Strategien fuer grosse Tabellen — Das Wichtigste auf einen Blick
Shard-Key
Stabil, in den meisten Queries vorhanden, gleichmaessig verteilt. Die wichtigste Design-Entscheidung.
Hash vs. Range
Hash verteilt gleichmaessig ohne Range-Queries, Range erhaelt Range-Queries mit Hotspot-Risiko.
Cross-Shard-Queries
Teuer, sollten auf Ausnahmen beschraenkt bleiben, Aggregationen in separates Analytics-System auslagern.
Resharding
Consistent Hashing oder mehr logische als physische Shards fuer risikoarmes spaeteres Wachstum.