Sharding und Replikation von Datenbanken
Sharding und Replikation von Datenbanken
1) Warum es notwendig ist
Wenn ein vertikales DB-Upgrade an die CPU/IO/RAM-Grenzen stößt oder ein Cluster zu SPOF wird, kommen Replikation (für Lesungen/HA) und Sharding (für die Schreib-/Datenverteilung). Die Ziele sind:- Bandbreite (horizontales Wachstum write QPS).
- Verfügbarkeit (schneller Failover, kein Single Point of Failure).
- Datenlokalisierung (Multi-Region, geringe Latenz).
- Isolierung von lauten Nachbarn (hot tenants/hot keys).
2) Grundbegriffe und Konsistenzmodelle
Primary/Leader ↔ Replica/Follower: Schreiben auf den Führer, Lesen - auf den Repliken.
Synchrone Replikation: Bestätigung der Transaktion nach dem Schreiben auf N Knoten (niedriger RPO, höhere Latenz).
Asynchron: Der Leader erfasst den Commit und sendet das Log später (RPO> 0, niedrige Latenz).
Quorum (Raft/Paxos): Schreiben auf die meisten Knoten; ein Log, ein automatischer Anführer.
Read-after-write: garantiertes Lesen Ihrer Einträge (siehe § 5).
Die CAP im Verkauf lesen wir so: Bei Netzwerkproblemen wählen Sie Konsistenz (CP) oder Verfügbarkeit (AP) für kritische Operationen und kombinieren oft Ebenen auf verschiedenen Pfaden.
3) Replikation: Optionen und Praktiken
3. 1 Physikalisch und logisch
Physisch (WAL/redo/binlog): näher am Blockmagazin, einfach und schnell; beschränkt auf homogene Topologie/Version.
Logisch: DML/DDL-Stream auf Zeilen-/Tabellenebene; ermöglicht partielle Replikate, Migrationen zwischen Versionen, CDC für DWH/Streaming.
3. 2 Einrichtung und Verwaltung
Überwachen Sie die Verzögerung (Zeit/Bytes/LSN).
Begrenzen Sie Hot-Standby-Feedback und lange Anfragen auf Replikate (um VACUUM/Reinigung nicht zu blockieren).
Für MySQL - GTID und Orchestrator; для PostgreSQL — Patroni/replication slots, synchronous_standby_names.
sql
-- на лидере
ALTER SYSTEM SET synchronous_commit = 'on';
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 (standby_a, standby_b)';
SELECT pg_reload_conf();
MySQL GTID (Transaktions-ID):
sql
SET GLOBAL enforce_gtid_consistency = ON;
SET GLOBAL gtid_mode = ON; -- перезапуск
CHANGE MASTER TO MASTER_AUTO_POSITION=1;
3. 3 Topologien
1→N (der Führer → Repliken) + Kaskaden (Repliken verschmelzen weiter).
Multi-primary (aktiv-aktiv) - Vermeiden Sie in OLTP ohne striktes Konfliktmanagement.
Quorum-Cluster (Raft) - CockroachDB/Yugabyte/PG-Raft-Add-Ins.
4) Lesen/Schreiben Split und Routing
Schreiben Sie immer an den Führer; Lesen Sie aus den Repliken, aber berücksichtigen Sie lag.
Read-after-write Strategien:1. Session Stickiness: Nach einer erfolgreichen Aufnahme liest der Client den Leader für 'Δ T'.
2. LSN/GTID-Gate: Der Client meldet „Ich möchte nicht älter werden als LSN = X“, der Router sendet an das Replikat, dessen LSN X ≥.
3. Stale-ok: Ein Teil der Abfragen erlaubt veraltete Daten (Kataloge/Bänder).
Werkzeuge: PgBouncer/Pgpool-II (Postgres), ProxySQL/MaxScale (MySQL), Vitess (Shard Routing).
Beispiel für ein LSN-Gate (Idee): Speichern Sie' pg _ current _ wal _ lsn () 'im HTTP-Header/Cook und fordern Sie vom Router ein Replikat mit' pg _ last _ wal _ replay _ lsn () ≥ LSN'.
5) Sharding-Strategien
5. 1 Auswahl des Schlüssels
Der Schlüssel muss sicherstellen, dass die Anfragen einheitlich und lokal sind:- Hash durch 'tenant _ id '/' user _ id' - gleichmäßig, aber beraubt range-scans.
- Bereich nach Zeit/ID - großartig für Zeitreihe/Archiv, aber Hot-Shard-Risiko.
- Consistent hashing - vereinfacht das Hinzufügen/Entfernen von Shards.
- Verzeichnis/Lookup-Tabelle - flexibel (jeder Algorithmus), aber eine andere Tabelle/Cache.
5. 2 Muster
Shared-nothing: Jeder Shard ist eine separate DB/Cluster, die Anwendung kennt das Routing.
Middleware-Sharding: Vitess (MySQL), Citus (Postgres), Proxy-Level versteckt die Topologie.
Federation: Aufteilung der Datendomänen nach Diensten (Katalog, Zahlungen, auth).
5. 3 Zusammengesetzte Schlüssel
Verwenden Sie den Schlüsselraum:'{tenant}: {entity}: {id} 'und speichern Sie diesen in der App und im Cache. Для Postgres — hash partitioning + LIST/RANGE subpartition.
PostgreSQL-Partitionierung (Fragment):sql
CREATE TABLE orders (
tenant_id int,
id bigint,
created_at timestamptz,
...,
PRIMARY KEY (tenant_id, id)
) PARTITION BY HASH (tenant_id);
CREATE TABLE orders_t0 PARTITION OF orders FOR VALUES WITH (MODULUS 16, REMAINDER 0);
--... t1..t15
6) Generierung von IDs
Vermeiden Sie „heiße“ monotone Autoinkremente auf der Schürze.
Verwenden Sie eine Snowflake-ähnliche 64-Bit-ID (time + region + shard + seq) oder eine ULID/KSUID (Monotonie und Verteilung).
Для Postgres — sequence per shard; für MySQL - auto_increment_increment/offset (verschiedene Offsets auf Shard-Leadern).
7) Online-Weiterleitung und Migrationen
Key Principles: Double Write (Dual-Write), Idempotenz, temporäres Double Routing.
Schritte (zusammengefasst):1. Fügen Sie einen neuen Shard/Cluster hinzu.
2. Aktivieren Sie Dual-Read (Konsistenzprüfung).
3. Aktivieren Sie Dual-Write (in beiden Shards), erfassen Sie Abweichungen.
4. Backfill historischer Daten durchführen (Batches, logische Replikation/CDC).
5. Schalten Sie die „Quelle der Wahrheit“ auf den neuen Schard; belassen Sie die „Schwanz“ -Synchronisation.
6. Schalten Sie den alten aus.
Werkzeuge: Vitess Resharding, Citus move shards, pg_logical/pgoutput, Debezium (CDC), gh-ost/pt-online-schema-change (DDL ohne Sperren).
8) Multi-Region und Geo-Distribution
Leader-Follower pro Region: Lokale Lesungen, Schreiben - via Global Leader (einfaches Modell, aber Cross-Region RTT).
Multi-Leader: Aufnahme in beiden Regionen - Konflikt-Merging erforderlich (Timestamp/Version/CRDT).
True distributed SQL (Raft): CockroachDB/Yugabyte - die Daten werden an die Region „geklebt“, die Abfragen gehen an das lokale Quorum.
- Geld/Aufträge - CP (Quorum/Leader), Verzeichnisse/Bänder - AP (Cache, Eventual).
- Planen Sie immer write fencing (eindeutige Schlüssel/Versionierung) mit einem möglichen Split-Brain.
9) Kohärenz in der Praxis
Read-your-writes: Führer oder Replik, der LSN/GTID „eingeholt“ hat.
Monotonische Lesungen: „nicht älter“ als die zuletzt gelesene LSN.
Write-conflict control: `SELECT... FOR UPDATE', Versionen ('xmin '/' rowversion'), UPSERT mit Versionsprüfung.
Idempotenz: Schlüssel zur Idempotenz bei Zahlungen/Veranstaltungen.
10) Beobachtbarkeit, SLO und Warnungen
Lag-Repliken: Zeit (Sekunden), LSN-Entfernung (Bytes), seconds_behind_master (MySQL).
Erzwungene Rollbacks/Konflikte, Replikationsfehler.
p95/p99 latency по route (read leader vs replica, write).
Throughput: TPS/locks/row-contended tables.
Bloat/VACUUM (PG), InnoDB buffer pool hit ratio (MySQL).
Dashboards: Per-Shard-Last, „heiße“ Shards, Schlüsselverteilung.
11) Backups, PITR und DR
Komplettes Backup + WAL/Binlog für PITR (Point-in-Time Recovery).
In einer anderen Region/Cloud speichern, regelmäßig Restore-Tests durchführen.
Für Shards gibt es einen vereinbarten „Schnitt“ (Time Coordination/LSN) oder eine applikative Idempotenz bei der Rekonstitution.
RPOs/RTOs werden an den Spieltagen vorgeschrieben und getestet.
bash pg_basebackup -D /backups/base -X stream -C -S slot_replica_1 архивация WAL через archive_command или pgBackRest/Barman
12) Sicherheit und Zugang
Segmentierung nach VPC/ACL, mTLS nach Proxy.
Rollen/Zuschüsse nach dem Prinzip der Mindestrechte; einzelne Benutzer pro Shard/Rolle.
DDL/DCL-Audit, Grenzwerte für „schwere“ Anfragen auf Replikaten.
Verschlüsselung bei Rest (KMS) und im Transit (TLS).
„Panik-Button“: global „NUR LESEN“ für die Dauer des Vorfalls/der Untersuchung.
13) Werkzeuge und Ziegel
PostgreSQL: Patroni (HA), PgBouncer (pooling/RO-routing), repmgr, pgBackRest/Barman (бэкап), Citus (шардинг), pglogical/Logical Replication, pgbadger/pg_stat_statements.
MySQL: Orchestrator (Topologien/Auto-Failover), ProxySQL/MaxScale (Routing), Percona XtraBackup (Backup), Group Replication/InnoDB Cluster, Vitess (Sharding/Resharding).
Distributed SQL: CockroachDB, YugabyteDB (Quorum, Embedded Sharding/Geolocation).
CDC: Debezium + Kafka/Pulsar für Ereignisse/ETL.
14) Anti-Muster
Single-primary ohne Auto-Failover und ohne DR-Tests.
„Magische“ read-split ohne Berücksichtigung lag → Phantomfehler/verdächtige bugs.
Sharding „aus Gründen der Sharding“: vorzeitige Komplikation anstelle von vertikalen Skale/Indizes/Cache.
Heißer Bereich (time-range) ohne time-bucket/hash-salt → ein shard schmilzt.
Die globale Transaktion 2PC über Dutzende von Shards im OLTP - hohe p99-Schwänze und häufige Sperren.
Das Fehlen von Dual-Write/Dual-Read bei Migrationen → Verlust/Rassynron.
DDL im Angebot ohne Online-Tools und ohne Kompatibilitätsflaggen.
15) Implementierung Checkliste (0-60 Tage)
0-15 Tage
Definieren Sie DB SLO, RPO/RTO.
Aktivieren Sie Replikation, Lag-Überwachung, grundlegende Backups + PITR.
Geben Sie den Router (PgBouncer/ProxySQL) und die Read-After-Write-Richtlinie ein.
16-30 Tage
Wählen Sie eine Sharding-Strategie, beschreiben Sie die Schlüssel und Schemata.
Vorbereitung der Nachschubwerkzeuge (Vitess/Citus/CDC).
Ein Verzeichnis von Diensten/Tabellen mit dem Vermerk „read-stale-ok“ vs „strict“.
31-60 Tage
Pilot-Shard, Dual-Read und Backfill ausführen.
Spieltag: Führungstreffer, Erholung vom PITR, Umschalten der Region.
Automatisieren Sie Berichte über Hot-Shard-Schlüssel und Unebenheiten.
16) Reifegradkennzahlen
Replica lag p95 <target (z.B. 500 ms) für kritische Lesungen.
Erfolgreiche DR-Tests ≥ 1/Quartal (Restore ≤ RTO, Verlust von RPO- ≤).
Lastverteilung nach Shards: Ungleichgewicht <20% nach QPS/Speicher.
Anteil der Anfragen mit strict-consistency, korrekt geroutet, = 100%.
Zero-Data-Loss bei Vorfällen, die CP-Garantien erfordern (Geld/Aufträge).
Online DDL/Migrationen ohne Ausfallzeiten, mit Kompatibilitätsflags.
17) Beispiele für Rezepte
Hash-Salz für den Zeitbereich (um nicht einen Shard zu erwärmen):sql
-- вычисляйте bucket = hash(user_id) % 16, храните (bucket, created_at)
PARTITION BY LIST (bucket) SUBPARTITION BY RANGE (created_at)
Read-my-writes middleware (Pseudocode):
python lsn = db.leader_query("SELECT pg_current_wal_lsn()")
ctx.sticky_until = now()+5s ctx.min_lsn = lsn в роутере чтений: выбираем реплику с last_lsn >= ctx.min_lsn, иначе лидер
Vitess VSchema (Fragment):
json
{
"tables": {
"orders": { "column_vindexes": [{ "column": "tenant_id", "name": "hash" }] }
}
}
18) Schlussfolgerung
Sharding und Replikation sind nicht nur Technik, sondern auch Prozesse: Konsistenzgerechtes Routing, die Disziplin der Migrationen (Dual-Write/Read, Backfill), regelmäßige DR-Tests und die Beobachtbarkeit von Lag/Hot Shards. Beginnen Sie mit einem einfachen leader→replica + read-after-write und fügen Sie dann Sharding hinzu, wo das Lastprofil es wirklich erfordert. Verwenden Sie vorgefertigte Plattformen (Vitess/Citus/Distributed SQL) und halten Sie geschäftskritische Daten im CP-Modus - damit die Basis kein Engpass mehr ist und zu einem vorhersehbaren, elastischen Fundament der Plattform wird.