Shading i replikacja bazy danych
Shading i replikacja bazy danych
1) Dlaczego go potrzebujesz
Gdy pionowa aktualizacja bazy danych przerywa się na procesor/IO/RAM lub jeden klaster staje się SPOF, następuje replikacja (dla odczytu/HA) i shading (dla zapisu/dystrybucji danych). Cele:- Przepustowość (zapisz wzrost poziomy QPS).
- Dostępność (szybka awaria, brak jednego punktu awarii).
- Lokalizacja danych (wielobranżowe, niskie opóźnienia).
- Izolacja hałaśliwych sąsiadów (gorący lokatorzy/gorące klucze).
2) Podstawowe terminy i modele spójności
Pierwszorzędne/Liderka/Naśladowca: napisz na liderze, przeczytaj na replikach.
Replikacja synchroniczna: potwierdzenie transakcji po zapisaniu na węzłach N (niski RPO, wyższy opóźnienie).
Asynchroniczny: lider zobowiązuje się i wysyła dziennik później (RPO> 0, niskie opóźnienie).
Kworum (tratwa/Paxos): pisanie do większości węzłów; jeden dziennik, automatyczny lider.
Odczyt po zapisie: gwarantowana lektura jego zapisów (patrz § 5).
Czytamy WPR w sprzedaży w ten sposób: w przypadku problemów sieciowych wybierasz spójność (CP) lub dostępność (AP) dla operacji krytycznych, często łącząc poziomy na różnych ścieżkach.
3) Replikacja: Opcje i praktyki
3. 1 Fizyczne i logiczne
Fizyczne (WAL/redo/binlog): bliżej dziennika bloku, proste i szybkie; ograniczona do jednorodnej topologii/wersji.
Logiczne: strumień DML/DDL na poziomie wiersza/tabeli; umożliwia częściowe repliki, migracje przekrojowe, CDC dla DWH/streaming.
3. 2 Konfiguracja i zarządzanie
Monitor lag (czas/bajty/LSN).
Ograniczyć hot-standby feedback i długie żądania na replikach (aby nie blokować VACUUM/czyszczenie).
dla MySQL - GTID i Orchestrator; мла PostgreSQL - Patroni/replikacja slotów, 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 (identyfikator transakcji):
sql
SET GLOBAL enforce_gtid_consistency = ON;
SET GLOBAL gtid_mode = ON; -- перезапуск
CHANGE MASTER TO MASTER_AUTO_POSITION=1;
3. 3 Topologie
1 → N (leader → replika) + kaskady (replika łączy się dalej).
Multi-primary (active-active) - unikaj w OLTP bez ścisłego zarządzania konfliktami.
Klaster kworum (tratwa) - dodatki CockroachDB/Yugabyte/PG-Raft.
4) Przeczytaj/napisz split i routing
Zawsze pisać jako lider; czytać z wskazówek, ale rozważyć opóźnienie.
Strategie odczytu po zapisie:1. Lepkość sesji: Po udanym nagraniu klient odczytuje od lidera podczas 'T'.
2. Brama LSN/GTID: klient mówi „Nie chcę starzeć się LSN = X”, router wysyła do repliki, której LSN ≥ X.
3. Stale-ok: niektóre zapytania pozwalają na ciągłe dane (katalogi/taśmy).
Narzędzia: PgBouncer/Pgpool-II (Postgres), ProxySQL/MaxScale (MySQL), Vitess (shard routing).
Przykład bramy LSN (idea): zapisz 'pg _ current _ wal _ lsn ()' do nagłówka/pliku cookie HTTP i wymagaj od routera repliki z 'pg _ last _ wal _ replay _ lsn () ≥ LSN'.
5) Strategie odławiania
5. 1 Wybór klucza
Klucz zapewnia jednolitość i lokalizację wniosków:- Hash przez 'lokator _ id'/' user _ id' - równomiernie, ale pozbawia skanowanie zakresu.
- Zakres w czasie/ID - świetne dla serii czasowych/archiwum, ale ryzyko hot-shard.
- Konsekwentne hashing - ułatwia dodawanie/usuwanie odłamków.
- Tabela katalogów/wyszukiwarek - elastyczna (dowolny algorytm), ale inna tabela/pamięć podręczna.
5. 2 Wzory
Shared-nothing: każdy odłamek jest oddzielną bazą danych/klastrem, aplikacja zna routing.
Middleware-shading: Vitess (MySQL), Citus (Postgres), Proxy-level ukrywa topologię.
Federacja: oddzielenie domen danych według usług (katalog, płatności, auth).
5. 3 klucze kompozytowe
Użyj miejsca kluczowego: '{lokator}: {podmiot}: {id}' i zapisz go w aplikacji i pamięci podręcznej. Дла Postgres - podział hash + LIST/RANGE subpartition.
PogreSQL podziału (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) Generowanie identyfikatorów
Unikać „gorących” monotonnych automatycznych przyrostów na odcieniach.
Użyj 64-bitowego identyfikatora płatków śniegu (czas + region + odłamek + seq) lub ULID/KSUID (monotonia i dystrybucja).
Дла Postgres - kolejność na odłamek; dla MySQL - auto_increment_increment/offset (różne offsety na liderach odłamków).
7) Oversharing online i migracje
Kluczowe zasady: podwójne pisanie, idempotencja, tymczasowy podwójny przebieg.
Kroki (uogólnione):1. Dodaj nowy odłamek/klaster.
2. Włącz podwójny odczyt (kontrola spójności).
3. Zawierać podwójne zapisu (w obu odłamkach), rekordowe rozbieżności.
4. Zasilanie danych historycznych (partie, replikacja logiczna/CDC).
5. Przełącz „źródło prawdy” na nowy odłamek; pozostawić synchronizację ogona.
6. Wyłącz starą.
Narzędzia: Vitess Resharding, Citus move shards, pg_logical/pgoutput, Debezium (CDC), gh-ost/pt-online-schema-change (DDL bez zamków).
8) Wielobranżowy i georozdzielczy
Leader-follower per region: local reads, write - poprzez globalnego lidera (prosty model, ale cross-region RTT).
Multi-leader: nagrywanie w obu regionach - potrzebujesz conflict-mering (timestamp/version/CRDT).
True distributed SQL (tratwa): CockroachDB/Yugabyte - dane są „przyklejane” do regionu, zapytania idą do lokalnego kworum.
- Pieniądze/zamówienia - CP (quorum/leader), katalogi/taśmy - AP (cache, eventual).
- Zawsze planuj pisać ogrodzenia (unikalne klucze/wersioning) z możliwym podziałem mózgu.
9) Spójność w praktyce
Czytaj-swoje-pisma: lider lub sygnał, który „złapał” z LSN/GTID.
Monotoniczny brzmi: „nie starszy” niż ostatni LSN czytać.
Kontrola konfliktu pisemnego: 'SELECT... DLA AKTUALIZACJI ', wersje (' xmin '/' rowversion '), UPSERT z kontrolą wersji.
Idempotencja: klucze idempotencji w płatnościach/zdarzeniach.
10) Obserwowalność, SLO i wpisy
Opóźnienie repliki: czas (sekundy), odległość LSN (bajty), seconds_behind_master (MySQL).
Wymuszone wałki/konflikty, błędy replikacji.
p95/p99 latencja (czytaj leader vs replika, napisz).
Przepustowość: TPS/locks/row-contested tables.
Wzdęcia/VACUUM (PG), współczynnik trafienia w basenie buforowym InnoDB (MySQL).
Deski rozdzielcze: obciążenie na odłamek, „gorące” odłamki, rozkład kluczy.
11) Kopie zapasowe, PITR i DR
Pełna kopia zapasowa + WAL/binlog dla PITR (odzyskiwanie w czasie).
Przechowywać w innym regionie/chmurze, regularnie przywracać testy.
W przypadku odłamków - spójne „kawałek” (koordynacja czasu/LSN) lub zastosowanie idempotencji w odzyskiwaniu.
RPO/RTO są pisane i testowane w dni gry.
bash pg_basebackup -D /backups/base -X stream -C -S slot_replica_1 архивация WAL через archive_command или pgBackRest/Barman
12) Bezpieczeństwo i dostęp
Segmentacja przez VPC/ACL, mTLS przez proxy.
Role/dotacje dotyczące zasady praw minimalnych; indywidualnych użytkowników na odłamek/rolę.
Audyt DDL/DCL, ograniczenia dotyczące „ciężkich” wniosków na replikach.
Szyfrowanie w stanie spoczynku (KMS) i tranzytu (TLS).
Przycisk paniki: Globalny „TYLKO DO ODCZYTU” na czas trwania incydentu/dochodzenia.
13) Narzędzia i cegły
PostgreSQL: Patroni (HA), PgBouncer (pooling/RO-routing), repmgr, pgBackRest/Barman (кака,), Citus (бардиН,), pglogiczne/logiczne replikacje, pgbadger/pg_stat_statements.
MySQL: Orchestrator (topologies/auto-failover), ProxySQL/MaxScale (routing), Percona XtraBackup (Backup), Replikacja grupy/Klaster InnoDB, Vitess (shading/reshitting).
Rozproszony SQL: CockroachDB, Yugab, DB (kworum, wbudowane odłamki/geolokalizacja).
CDC: Debezium + Kafka/Pulsar dla wydarzeń/ETL.
14) Anty-wzory
Pojedynczy podstawowy bez automatycznego awarii i bez badań DR.
„Magic” read-split z wyłączeniem lag → błędy fantomowe/podejrzane błędy.
Shading „dla dobra shading”: przedwczesne komplikacje zamiast pionowej skali/indeksów/pamięci podręcznej.
Gorący zakres (zakres czasowy) bez czasu-wiadro/hash-sól → jeden odłamek topi się.
Globalna transakcja 2PC na szczycie dziesiątek odłamków w OLTP - wysokie ogony p99 i częste zamki.
Brak podwójnego zapisu/podwójnego odczytu podczas migracji → utrata/brak synchronizacji.
DDL w prod bez narzędzi online i bez flag funkcji kompatybilności.
15) Lista kontrolna realizacji (0-60 dni)
0-15 dni
Zdefiniuj DB SLO, RPO/RTO.
Włącz replikację, monitorowanie opóźnień, podstawowe kopie zapasowe + PITR.
Wprowadź router (PgBouncer/ProxySQL) i politykę odczytu po zapisie.
16-30 dni
Wybierz strategię shading, opisać klucze i schematy.
Przygotuj narzędzia do nadmiernego ładowania (Vitess/Citus/CDC).
Katalog usług/tabel oznaczonych „read-stale-ok” vs „strict”.
31-60 dni
Uruchom pilot-shard, podwójny odczyt i zasypkę.
Gra-day: awaria lidera, odzyskiwanie z PITR, przełącznik regionalny.
Automatyzacja klucza strzału i raportowania nierówności.
16) Wskaźniki zapadalności
Replika lag p95 <cel (np. 500 ms) dla odczytów krytycznych.
Udane badania DR ≥ 1/kwartał (przywrócenie ≤ RTO, utrata RPO ≤).
Rozkład obciążenia przez odłamki: nierównowaga <20% przez QPS/storage.
Odsetek wniosków o ścisłej konsystencji prawidłowo przeniesiony = 100%.
Zero-data-loss w incydentach wymagających gwarancji CP (pieniądze/zlecenia).
Online DDL/migracja bez przestojów, z flagami kompatybilności.
17) Przykłady przepisów
Hash-sól dla zakresu czasowego (aby nie podgrzewać jednego odłamka):sql
-- вычисляйте bucket = hash(user_id) % 16, храните (bucket, created_at)
PARTITION BY LIST (bucket) SUBPARTITION BY RANGE (created_at)
Czytaj-my-writes middleware (pseudokoda):
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) Wniosek
Shading i replikacja to nie tylko technika, ale także procesy: routing świadomy spójności, dyscyplina migracyjna (podwójne pisanie/czytanie, zasypywanie), regularne testy DR oraz obserwowalność opóźnień/strzałów. Zacznij od prostego + read-after-write lidera → repliki, a następnie dodaj shading gdzie profil obciążenia naprawdę wymaga. Użyj gotowych platform (Vitess/Citus/Distributed SQL) i utrzymaj dane krytyczne dla biznesu w trybie CP - dzięki temu baza przestanie być wąskim gardłem i stanie się przewidywalnym, elastycznym fundamentem platformy.