Veritabanı Parçalama ve Çoğaltma
Veritabanı Parçalama ve Çoğaltma
1) Neden ihtiyacınız var
Veritabanının dikey yükseltmesi CPU/IO/RAM'e dayandığında veya bir küme SPOF olduğunda, çoğaltma (okuma/HA için) ve parçalama (yazma/veri dağıtımı için) gelir. Hedefler:- Verim (QPS yatay büyüme yazın).
- Kullanılabilirlik (hızlı yük devretme, tek bir arıza noktası yok).
- Veri lokalizasyonu (çok bölgeli, düşük gecikme süresi).
- Gürültülü komşuların izolasyonu (sıcak kiracılar/sıcak tuşlar).
2) Temel terimler ve tutarlılık modelleri
Birincil/Lider ↔ Çoğaltma/Takipçi: lidere yaz, kopyalarda oku.
Eşzamanlı çoğaltma: N düğümlerine yazdıktan sonra işlem onayı (düşük RPO, daha yüksek gecikme süresi).
Asenkron: leader taahhüt eder ve daha sonra log gönderir (RPO> 0, düşük gecikme).
Quorum (Raft/Paxos): Çoğu düğüme yazma; Tek kütük, otomatik lider.
Yazma sonrası okuma: kayıtlarının garantili okunması (bkz. § 5).
Satışlarda CAP'ı şu şekilde okuyoruz: Ağ sorunları durumunda, kritik işlemler için tutarlılığı (CP) veya kullanılabilirliği (AP) seçersiniz ve genellikle seviyeleri farklı yollarda birleştirirsiniz.
3) Çoğaltma: Seçenekler ve Uygulamalar
3. 1 Fiziksel ve mantıksal
Fiziksel (WAL/redo/binlog): blok günlüğüne daha yakın, basit ve hızlı; Homojen topoloji/versiyon ile sınırlıdır.
Mantıksal: Satır/tablo düzeyinde DML/DDL akışı; Kısmi kopyalara, çapraz sürüm geçişlerine, DWH/akış için CDC'ye izin verir.
3. 2 Kurulum ve yönetim
Monitör gecikmesi (zaman/bayt/LSN).
Kopyalarda hazır bekleme geribildirimini ve uzun istekleri sınırlayın (VAKUM/temizlemeyi engellememek için).
MySQL için - GTID ve Orchestrator; для PostgreSQL - Patroni/çoğaltma yuvaları, 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 (işlem kimliği):
sql
SET GLOBAL enforce_gtid_consistency = ON;
SET GLOBAL gtid_mode = ON; -- перезапуск
CHANGE MASTER TO MASTER_AUTO_POSITION=1;
3. 3 Topolojiler
1- N (leader) + cascades (replica merges further).
Çok birincil (aktif-aktif) - OLTP'de sıkı çatışma yönetimi olmadan kaçının.
Quorum cluster (Raft) - CockroachDB/Yugabyte/PG-Raft eklentileri.
4) Okuma/Yazma Bölme ve Yönlendirme
Her zaman bir lider olarak yazın; İpuçlarından okuyun, ancak gecikmeyi düşünün.
Yazma sonrası okuma stratejileri:1. Oturum yapışkanlığı: Başarılı bir kayıttan sonra, müşteri 'Δ T' sırasında liderden okur.
2. LSN/GTID kapısı: istemci "Eski LSN = X'i almak istemiyorum'diyor, yönlendirici LSN X'i ≥ replikaya gönderiyor.
3. Bayat-ok: bazı sorgular bayat verilere (dizinler/bantlar) izin verir.
Araçlar: PgBouncer/Pgpool-II (Postgres), ProxySQL/MaxScale (MySQL), Vitess (shard routing).
Bir LSN kapısı örneği (fikir): HTTP başlığına/çerezine 'pg _ current _ wal _ lsn ()' kaydedin ve yönlendiricinin 'pg _ last _ wal _ replay _ lsn () ≥ LSN ()'ile çoğaltılmasını isteyin.
5) Sharding stratejileri
5. 1 Anahtar seçimi
Anahtar, taleplerin tekdüzeliğini ve yerelliğini sağlamalıdır:- 'Tenant _ id'/' user _ id'ile karma - eşit olarak, ancak aralık taramalarından mahrum kalır.
- Zaman/ID aralığı - zaman serisi/arşiv için harika, ancak sıcak parça riski.
- Tutarlı karma - parça eklemeyi/çıkarmayı kolaylaştırır.
- Dizin/arama tablosu - esnek (herhangi bir algoritma), ancak başka bir tablo/önbellek.
5. 2 Desenler
Paylaşılan-hiçbir şey: Her parça ayrı bir veritabanı/kümedir, uygulama yönlendirmeyi bilir.
Middleware-sharding: Vitess (MySQL), Citus (Postgres), Proxy seviyesi topolojiyi gizler.
Federasyon: veri alanlarının hizmetlere göre ayrılması (katalog, ödemeler, auth).
5. 3 Kompozit anahtarlar
Anahtar uzayını kullanın: '{tenant}: {entity}: {id}'ve uygulama ve önbellekte saklayın. Для Postgres - karma bölümleme + LIST/RANGE alt bölümleme.
PostgreSQL bölümleme (fragman):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) Kimlik oluşturma
Sharding'de "sıcak" monoton otomatik artışlardan kaçının.
Snowflake benzeri 64 bit ID (zaman + bölge + parça + seq) veya ULID/KSUID (monotonluk ve dağıtım) kullanın.
Для Postgres - parça başına dizi; MySQL için - auto_increment_increment/offset (parça liderlerinde farklı uzaklıklar).
7) Çevrimiçi aşırı paylaşım ve geçişler
Anahtar ilkeler: çift yazma, idempotency, geçici çift yönlendirme.
Adımlar (genelleştirilmiş):1. Yeni bir parça/küme ekleyin.
2. Çift okumayı etkinleştirin (tutarlılık denetimi).
3. Çift yazma (her iki parçada), kayıt tutarsızlıkları içerir.
4. Backfill geçmiş verileri (toplu, mantıksal/CDC replikasyonu).
5. "Gerçeğin kaynağını'yeni bir parçaya geçirin; "Kuyruk" senkronizasyonunu bırakın.
6. Eskisini kapat.
Araçlar: Vitess Resharding, Citus hareket parçaları, pg_logical/pgoutput, Debezium (CDC), gh-ost/pt-online-şema-değişim (kilitsiz DDL).
8) Çok bölgeli ve coğrafi dağıtım
Bölge başına lider-takipçi: yerel okur, yazar - küresel lider aracılığıyla (basit model, ancak bölgeler arası RTT).
Çoklu lider: her iki bölgede kayıt - çatışma-mering (zaman damgası/sürüm/CRDT) gerekir.
Gerçek dağıtılmış SQL (Raft): CockroachDB/Yugabyte - veriler bölgeye "yapıştırılır", sorgular yerel çoğunluğa gider.
- Para/emirler - CP (çekirdek/lider), dizinler/kasetler - AP (önbellek, nihai).
- Her zaman olası bir split-beyin ile yazma eskrim (benzersiz anahtarlar/sürüm oluşturma) planlayın.
9) Uygulamada tutarlılık
Yazdıklarını oku: LSN/GTID ile "yakalanan" lider veya işaret.
Monotonik okur: Son LSN okuduğundan'daha eski değil ".
Yazma-çakışma kontrolü: 'SELECT... UPDATE 'için, sürümler (' xmin'/' rowversion '), sürüm kontrolü ile UPSERT.
Idempotence: Ödemelerde/etkinliklerde idempotence anahtarları.
10) Gözlemlenebilirlik, SLO ve uyarılar
Replica lag: zaman (saniye), LSN mesafesi (bayt), seconds_behind_master (MySQL).
Zorla geri alma/çakışma, çoğaltma hataları.
P95/p99 gecikme по rota (okuma lideri vs çoğaltma, yazma).
Verim: TPS/locks/row-contended tables.
Bloat/VACUUM (PG), InnoDB arabellek havuzu isabet oranı (MySQL).
Panolar: parça başına yük, "sıcak" parçalar, anahtar dağılımı.
11) Yedeklemeler, PITR ve DR
PITR için tam yedekleme + WAL/binlog (zamanında kurtarma).
Başka bir bölgede/bulutta saklayın, testleri düzenli olarak geri yükleyin.
Parçalar için, tutarlı bir "dilim" (zaman koordinasyonu/LSN) veya iyileşme üzerine uygulayıcı idempotans.
RPO'lar/RTO'lar oyun günlerinde yazılır ve test edilir.
bash pg_basebackup -D /backups/base -X stream -C -S slot_replica_1 архивация WAL через archive_command или pgBackRest/Barman
12) Güvenlik ve erişim
VPC/ACL ile segmentasyon, proxy ile mTLS.
Asgari haklar ilkesi üzerine roller/hibeler; Parça/rol başına bireysel kullanıcılar.
Denetim DDL/DCL, kopyalar üzerinde'ağır "istekleri sınırlar.
Dinlenme (KMS) ve geçiş sırasında (TLS) şifreleme.
Panik Butonu: Olay/soruşturma süresince global 'SADECE OKUYUN'.
13) Aletler ve tuğlalar
PostgreSQL: Patroni (HA), PgBouncer (pooling/RO-routing), repmgr, pgBackRest/Barman (бэкап), Citus (шардинг), peglogic/Logical Replication, pgbadger/pg_stat_statements.
MySQL: Orchestrator (topologies/auto-failover), ProxySQL/MaxScale (routing), Percona XtraBackup (backup), Group Replication/InnoDB Cluster, Vitess (sharding/resharding).
Dağıtılmış SQL: CockroachDB, YugabyteDB (quorum, dahili sharding/geolocation).
CDC: Olaylar/ETL için Debezium + Kafka/Pulsar.
14) Anti-desenler
Otomatik yük devretme olmadan ve DR testleri olmadan tek birincil.
Lag hariç "Magic" okuma-bölme - fantom hataları/şüpheli hatalar.
"Sharding uğruna" sharding: Dikey ölçek/indeksler/önbellek yerine erken komplikasyon.
Sıcak aralık (zaman aralığı) zaman-kova/karma-tuz olmadan - bir parça erir.
Küresel işlem, OLTP'deki düzinelerce parçanın üzerine 2PC - yüksek p99 kuyrukları ve sık kilitleri.
Geçişler sırasında çift yazma/çift okuma eksikliği - kayıp/senkronizasyon dışı.
Çevrimiçi araçlar olmadan ve uyumluluk özelliği bayrakları olmadan prod DDL.
15) Uygulama kontrol listesi (0-60 gün)
0-15 gün
DB SLO, RPO/RTO'yu tanımlayın.
Çoğaltma, gecikme izleme, temel yedeklemeler + PITR'yi etkinleştirin.
Yönlendiriciyi (PgBouncer/ProxySQL) ve yazma sonrası okuma politikasını girin.
16-30 gün
Bir sharding stratejisi seçin, anahtarları ve şemaları açıklayın.
Aşırı şarj araçlarını hazırlayın (Vitess/Citus/CDC).
"Read-stale-ok" veya "strict'olarak işaretlenmiş hizmet/tablo dizini.
31-60 gün
Pilot-shard, dual-read ve backfill çalıştırın.
Oyun günü: lider yük devretme, PITR'den kurtarma, bölge değiştirme.
Sıcak parça anahtarını ve eşitsizlik raporlamasını otomatikleştirin.
16) Olgunluk metrikleri
Replica lag p95 <hedef (örn. Kritik okumalar için 500 ms).
Başarılı DR testleri ≥ 1/çeyrek (RTO ≤ geri yükleme, RPO ≤ kaybı).
Parçalara göre yük dağılımı: QPS/depolama ile <%20 dengesizlik.
Katı tutarlılığa sahip isteklerin yüzdesi doğru yönlendirildi = %100.
CP garantisi gerektiren olaylarda sıfır veri kaybı (para/emir).
Uyumluluk bayraklarıyla, kesinti olmadan çevrimiçi DDL/geçiş.
17) Tarif örnekleri
Zaman aralığı için hash-salt (bir parçayı ısıtmamak için):sql
-- вычисляйте bucket = hash(user_id) % 16, храните (bucket, created_at)
PARTITION BY LIST (bucket) SUBPARTITION BY RANGE (created_at)
Benim yazdığım ara katman yazılımını oku (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 (fragman):
json
{
"tables": {
"orders": { "column_vindexes": [{ "column": "tenant_id", "name": "hash" }] }
}
}
18) Sonuç
Parçalama ve çoğaltma sadece bir teknik değil, aynı zamanda süreçlerdir: tutarlılığa duyarlı yönlendirme, geçiş disiplini (çift yazma/okuma, geri doldurma), düzenli DR testleri ve lag/hot shard gözlemlenebilirliği. Basit bir + okumadan sonra yazma lideriyle başlayın - çoğaltma, ardından yük profilinin gerçekten gerektirdiği yere sharding ekleyin. Hazır platformları (Vitess/Citus/Distributed SQL) kullanın ve iş açısından kritik verileri CP modunda tutun - bu şekilde taban bir darboğaz olmaktan çıkacak ve platformun öngörülebilir, elastik bir temeli haline gelecektir.