Buyukweb
Veritabanı Sharding ve Horizontal Scaling Stratejileri

Veritabanı Sharding ve Horizontal Scaling Stratejileri

Veritabanı sharding ve yatay ölçekleme. Range-based, hash-based ve directory-based sharding stratejileri, avantajları ve uygulama yöntemleri.

Büyükweb Editör EkibiHosting, Sunucu ve Sistem Yönetimi Editörü13 dakika okuma

Veritabanı Sharding ve Horizontal Scaling Stratejileri

Milyonlarca kullanıcıya ulaştığınızda, tek bir veritabanı sunucusu yeterli olmaz. Horizontal scaling (yatay ölçekleme), veritabanı performansını artırmanın en etkili yoludur.

Vertical vs Horizontal Scaling

Özellik Vertical (Dikey) Horizontal (Yatay)
Yöntem Daha güçlü sunucu Daha fazla sunucu
Maliyet Üstel artar Doğrusal artar
Limit Fiziksel sınır Teorik sınır yok
Karmaşıklık Düşük Yüksek
Downtime Gerekebilir Genellikle yok

Read Replicas (Okuma Replikaları)

En basit yatay ölçekleme:

          WRITE                READ
    ┌─────────────┐    ┌─────────────┐
    │   Master    │───▶│  Replica 1  │
    │  (yazma)    │    │  (okuma)    │
    └─────────────┘    └─────────────┘
                       ┌─────────────┐
                       │  Replica 2  │
                       │  (okuma)    │
                       └─────────────┘
# Python'da okuma/yazma ayrımı
class DatabaseRouter:
    write_db = "mysql://master:3306/db"
    read_dbs = [
        "mysql://replica1:3306/db",
        "mysql://replica2:3306/db",
    ]

    def get_write_connection(self):
        return connect(self.write_db)

    def get_read_connection(self):
        import random
        return connect(random.choice(self.read_dbs))

Sharding (Parçalama)

Sharding, büyük bir veritabanını küçük parçalara (shard) böler. Her shard farklı bir sunucuda bulunur.

Tüm kullanıcılar (100 milyon)
     ┌──────────────┐
     │ User Service │
     └──────────────┘
           │
    ┌──────┼──────┐
    │      │      │
  Shard 1 Shard 2 Shard 3
  (ID     (ID     (ID
   1-33M)  33-66M) 66-100M)

1. Range-Based Sharding

Kullanıcı ID'ye göre:
Shard 1: ID 1 - 10.000.000
Shard 2: ID 10.000.001 - 20.000.000
Shard 3: ID 20.000.001 - ...

Tarih bazlı:
Shard 1: Ocak 2026 verileri
Shard 2: Şubat 2026 verileri
...

Avantajlar:

  • Basit mantık
  • Range sorguları verimli

Dezavantajlar:

  • Hotspot riski (yeni veriler hep son shard'a)
  • Dengesiz dağılım

2. Hash-Based Sharding

def get_shard(user_id, num_shards=4):
    return user_id % num_shards

# user_id=1 → Shard 1
# user_id=2 → Shard 2
# user_id=5 → Shard 1
# user_id=100 → Shard 0

Avantajlar:

  • Dengeli dağılım
  • Hotspot yok

Dezavantajlar:

  • Range sorguları verimsiz
  • Shard sayısı değişince yeniden hash gerekir

3. Consistent Hashing

Sanal node'larla esnek hash dağıtımı:

Hash ring (0-360 derece):
Node A: 0-120
Node B: 120-240
Node C: 240-360

Veri hash'i → Ring üzerinde yerleştir → En yakın node'a ata

Yeni node D eklense:
Node A: 0-90
Node D: 90-120 (yeni)
Node B: 120-240
Node C: 240-360
→ Sadece %25 veri taşınır (tüm veri değil)

4. Directory-Based Sharding

Lookup tablosu ile shard tespiti:

-- Shard lookup tablosu
CREATE TABLE shard_map (
    entity_id BIGINT,
    shard_id  INT
);

-- user_id 42 hangi shard'da?
SELECT shard_id FROM shard_map WHERE entity_id = 42;

Avantajlar:

  • En esnek yaklaşım
  • Veri taşıma kolaylığı

Dezavantajlar:

  • Lookup tablosu bottleneck olabilir
  • Ekstra sorgu

Sharding Shard Key Seçimi

Shard key seçimi kritiktir:

İyi shard key:
✓ Yüksek kardinalite (çok farklı değer)
✓ Dengeli dağılım
✓ Sorgu kalıplarıyla uyumlu

Kötü shard key:
✗ Boole değeri (true/false) — sadece 2 shard
✗ Zaman damgası (tüm yeni veri aynı shard)
✗ Düşük kardinalite alan

Cross-Shard Joins Sorunu

-- Bu sorgu sharding'de sorun:
SELECT u.name, COUNT(o.id)
FROM users u JOIN orders o ON u.id = o.user_id
-- users ve orders farklı shard'lardaysa?

Çözümler:

  1. Denormalizasyon: Gerekli verileri aynı shard'a taşı
  2. Application-level join: Uygulamada birleştir
  3. Global table: Küçük tablolar tüm shard'larda
  4. Colocation: İlişkili verileri aynı shard'a koy

ProxySQL ile MySQL Sharding

apt install proxysql

# ProxySQL query routing
# Okuma → replica'ya
# Yazma → master'a
# Belirli tablolar → belirli shard'lara

Büyük Ölçekli Veritabanı Stratejileri

1. Tek sunucu (< 1TB, < 10K TPS)
   └─ MySQL / PostgreSQL

2. Read Replicas (1-10TB, okuma yoğun)
   └─ Master + 2-3 Replica

3. Vertical Sharding (farklı servisler)
   └─ Kullanıcı DB / Sipariş DB / Ürün DB

4. Horizontal Sharding (> 10TB veya > 100K TPS)
   └─ Vitess (MySQL sharding)
   └─ Citus (PostgreSQL sharding)
   └─ CockroachDB (NewSQL)

5. Polyglot Persistence
   └─ MySQL + Redis + Elasticsearch + Cassandra

Vitess (YouTube'un MySQL Sharding Çözümü)

# Vitess - MySQL için otomatik sharding
# https://vitess.io
# Google'ın YouTube için geliştirdiği çözüm
# Kubernetes native

Citus (PostgreSQL Sharding)

-- Citus extension
CREATE EXTENSION citus;

-- Tabloyu dağıt
SELECT create_distributed_table('siparisler', 'musteri_id');

-- Artık sorgu tüm shard'lara dağıtılır
SELECT COUNT(*) FROM siparisler WHERE durum = 'beklemede';

Büyük ölçekli projeleriniz için [Büyükweb VDS çözümlerimizde](MASK31) özelleştirilmiş veritabanı mimarileri kurabilirsiniz.

Sharding'e Karar Verme — Premature Optimization Riski

Sharding karmaşıklığı 10x artırır. Önce vertical scaling + read replica + caching denemeden başlamayın:

Aşama Veri Strateji
1 < 1 TB, < 10K TPS Tek node, vertical scaling (RAM/CPU artır)
2 1-10 TB, read-heavy Master + 2-3 read replica
3 10-50 TB, mixed Functional sharding (user_db, order_db, product_db)
4 50+ TB, > 50K TPS Horizontal sharding (Vitess/Citus/Cassandra)
5 Distributed transactions, multi-region NewSQL (CockroachDB, YugabyteDB, Spanner)

Soru: Sharding'e gerek var mı? Cache + index + read replica ile çoğu zaman 90% sorun çözülür.

Functional Sharding (Vertical Partitioning)

Sharding'in en kolay ve düşük riskli formu — tablolarınızı konuya göre ayır:

monolith_db (eski)
  ├── users
  ├── orders
  ├── products
  ├── reviews
  └── analytics_events  ← çok büyük

→ Mikroservis split

users_db          : users + sessions
orders_db         : orders + order_items + payments
products_db       : products + categories + inventory
analytics_db      : events (TimescaleDB veya ClickHouse)

Her servis kendi DB'sini sahipler; cross-service join → API call. Distributed transaction yerine eventual consistency + saga pattern.

Horizontal Sharding — Karşılaşılan Zorluklar

Tek shard'a Sığmayan Sorgular:
- "Tüm kullanıcılar arasında en çok satın alanları getir" — tüm shard'larda sorgula + birleştir
- "Yeni kullanıcı kayıt" — distributed transaction (2PC) gerek
- Yabancı anahtar (FK) — cross-shard FK desteklenmez
- Auto-increment ID — her shard'da çakışmaması için global ID generator (Snowflake)
- Şema değişikliği — tüm shard'larda paralel
- Reshard (yeniden dengeleme) — büyük operasyon

Global ID Generator — Snowflake Pattern

Auto-increment çakışmasın diye timestamp + node_id + sequence birleşimi:

64-bit ID
[1 bit unused] [41 bits timestamp] [10 bits node ID] [12 bits sequence]
# Twitter Snowflake basitleştirilmiş
import time
NODE_ID = 1  # her shard'da farklı

def generate_id():
    timestamp = int(time.time() * 1000) - EPOCH
    sequence = next_sequence()  # process-local counter
    return (timestamp << 22) | (NODE_ID << 12) | sequence

Saniyede 4M unique ID üretebilir; Twitter, Discord, Instagram bu pattern'i kullanır.

Tutarlılık (Consistency) Modelleri

Sharded sistemde CAP teoremi devreye girer:

Model Açıklama Kullanım
Strong Consistency Yazma sonrası okuma garantili son hâl Banking, finansal
Eventual Consistency Sonunda tutarlı (saniyeler/dakikalar) Sosyal medya, analitik
Read-your-writes Kullanıcı kendi yazdığını görür E-commerce sepet
Monotonic Reads Okuma her zaman ileri gider Timeline, feed
Causal Consistency İlişkili yazmaların sırası korunur Sohbet, yorumlar

CAP'a göre CP (Cassandra QUORUM, MongoDB writeConcern majority) veya AP (Cassandra ONE) tercihi.

NewSQL — Sharding Karmaşası Olmadan Ölçek

Geleneksel sharding ekstra karmaşık; NewSQL bu işi otomatik yapar:

Sistem Highlight Uyum
CockroachDB PostgreSQL wire protocol, distributed SQL, ACID self-hosted veya Cockroach Cloud
YugabyteDB PostgreSQL + Cassandra API, distributed self-hosted
Vitess MySQL sharding (YouTube/Slack/Square) Kubernetes ortamlarda
Citus PostgreSQL extension, columnar self-hosted veya yönetilen seçenekler
TiDB MySQL uyumlu, HTAP (analitik+OLTP) self-hosted veya TiDB Cloud

Trend 2026: Yeni projeler giderek CockroachDB, TiDB, YugabyteDB ile distributed SQL kullanıyor — manuel sharding'in karmaşası yerine ACID + scale.

Citus Pratik Örneği

PostgreSQL'i sharding'e dönüştüren extension:

-- Coordinator + worker setup (3 worker)
SELECT master_add_node('worker-1', 5432);
SELECT master_add_node('worker-2', 5432);
SELECT master_add_node('worker-3', 5432);

-- Tabloyu dağıt (hash by user_id)
SELECT create_distributed_table('orders', 'user_id');

-- Reference table (her worker'da kopya — küçük tablolar)
SELECT create_reference_table('countries');

-- Sorgular otomatik paralel çalışır
SELECT user_id, COUNT(*) FROM orders WHERE created_at > '2026-01-01' GROUP BY user_id;
-- Coordinator query'i 3 worker'a dağıtır → topla → dön

-- Reshard gerektiğinde
SELECT * FROM citus_rebalance_status();
SELECT citus_rebalance_start();

Vitess — YouTube'un MySQL Sharding'i

# Vitess Kubernetes (vtcontroller, vttablet, vtgate)
# Her shard kendi MySQL master + 2 replica
# vtgate query proxy + routing

# Keyspace + shards
CreateKeyspace customer
ApplyVSchema -- '{"sharded":true, "vindexes":{"hash":{"type":"hash"}}, "tables":{"users":{"column_vindexes":[{"column":"id","name":"hash"}]}}}'

# 4 shard ile başla
ApplyShardingDef customer "-40,40-80,80-c0,c0-"

# Online resharding (downtime'sız 4 → 8 shard)
SplitClone customer/-40

Production'da Slack, Square, Etsy, GitHub kullanıyor.

Cross-Shard Query Stratejileri

# 1. Scatter-Gather — tüm shard'lara paralel
async def find_user_globally(email):
    tasks = [shard.query(f"SELECT * FROM users WHERE email='{email}'")
             for shard in shards]
    results = await asyncio.gather(*tasks)
    return next((r for r in results if r), None)

# 2. Routing key — shard hesapla, tek shard'a git
def find_user(user_id):
    shard = shards[hash(user_id) % len(shards)]
    return shard.query(f"SELECT * FROM users WHERE id={user_id}")

# 3. Secondary index — shard map ekstra tablo
def find_user_by_email(email):
    shard_id = lookup_table.get(email)
    return shards[shard_id].query(f"...")

Sharding ile Kaçınılmaz Sorunlar

Hot Shard

Kullanıcı bazlı sharding'de "süper kullanıcı" (100M post atan etkileyici) tek shard'ı doldurur. Çözüm:

  • Sub-sharding — hot kullanıcının verisini birden fazla shard'a böl
  • Caching — Redis ile read trafik %95+'i sunucudan uzak tut
  • Read replica — hot shard için 5+ replica

Resharding

10 shard → 20 shard geçiş: tüm verinin yarısı taşınmalı. Stratejiler:

  • Online migration — yeni shard'lar dolarken yazma trafiği split
  • Dual write + verify + cutover — güvenli ama karmaşık
  • Consistent hashing — sadece %25 veri taşınır (eklenen node oranında)

Distributed Transaction

Müşteri A → Müşteri B'ye para transferi (farklı shard'larda)

Naive:
1. A.balance -= 100
2. (network) B.balance += 100   ← burada hata olursa para uçar

2PC (Two-Phase Commit): prepare → commit; ama ağ partition'ında DB'ler kilitli kalır.
Saga pattern: kompansating transaction; eventual consistency.
Outbox pattern: write log → background worker → diğer servise gönder.

Caching Layer Sharding'siz Çoğu Sorunu Çözer

Tek MySQL DB
   ↑
Redis cache (95% hit ratio)
   ↑
CDN edge (statik) + Application server cache
   ↑
Client (browser cache)

→ DB'ye giden trafik %5 → tek node yıllarca yeter

Redis Object Cache genel olarak %30-50 sayfa hızı kazandırır + DB yükünü %90 azaltır. Sharding'e gerek kalmadan ölçeklenmenin en etkili yolu.

CQRS — Command Query Responsibility Segregation

Yazma + okuma'yı tamamen ayrı modeller:

Write side: PostgreSQL (normalized, ACID)
   ↓ event stream (Kafka/Debezium)
Read side: Elasticsearch / Redis / read-only DB
   - faster queries
   - denormalized
   - can be eventually consistent

E-ticaret sitelerinde popüler — yazmalar PG, ürün arama ES, sepet Redis.

Polyglot Persistence — Right Tool for the Job

Kullanıcı oturumu  → Redis (TTL'li, hız)
İşlemler            → PostgreSQL (ACID)
Ürün arama          → Elasticsearch (full-text)
Analitik events     → ClickHouse / TimescaleDB (columnar)
Recommendation      → Cassandra (yüksek yazma)
Real-time chat      → MongoDB (JSON-friendly)

Tek DB'ye sığmayan iş yükünü doğru aracın çözmesi → her biri kendi shard stratejisini uygular.

Sharding Hazırlık Checklist

  • Cache layer (Redis/Memcached) %90+ hit ratio mu?
  • Read replica + connection pool var mı?
  • Slow query'ler optimize edildi mi (index, EXPLAIN)?
  • Vertical scaling (sunucu 2x büyütme) yapıldı mı?
  • Functional sharding (servis bazlı DB) düşünüldü mü?
  • Data growth projection — 12 ay sonra ne olacak?
  • Hot key analizi yapıldı mı (user_id distribution)?
  • Application kodunda SHARD_KEY belirlendi mi?
  • Cross-shard transaction senaryoları tanımlı mı?
  • Resharding stratejisi planlı mı?
  • Monitoring (per-shard query rate, lag) hazır mı?
  • Backup ve restore stratejisi shard-aware mi?

Sıkça Sorulan Sorular

Sharding'e ne zaman geçmeliyim?

Tek node + replica + cache ile yetmediğinde. Tipik göstergeler: 1) DB CPU > %70 sürekli 2) Disk > 5 TB 3) Tek tablo > 1 milyar satır 4) Yedek alma >12 saat 5) DDL operasyonları downtime gerektiriyor. Erken sharding = gereksiz karmaşıklık.

Shard sayısını kaç seçeyim?

Genel pratik: iyi başlangıç 32 veya 64 shard (logical) ama az node'da host edilir (örn. 4 node × 16 logical shard). Büyüdükçe logical shard'lar yeni node'lara taşınır → reshard gerekmez. Power-of-2 sayılar consistent hashing için ideal.

Vitess vs Citus farkı?

Vitess = MySQL ekosistem, YouTube/Slack production tested, K8s native. Citus = PostgreSQL extension, daha kolay setup; açık kaynak topluluk tarafından geliştirilir. İkişi de production-grade. Mevcut DB'nize göre seç.

Read replica yetersiz neden?

Yazma yükü yüksekse — replica'lar yine tek master'a yazıyor → master CPU/disk patlatır. Sharding yazma yükünü dağıtır.

Sharding sonrası schema migration nasıl?

Online schema change tool'ları kullan: gh-ost (MySQL), pg_repack (PG), pt-online-schema-change. Tüm shard'larda paralel veya sıralı uygula. CI/CD pipeline'a otomatik shard fan-out gerekir.

"Distributed transaction" gerçekten gerekli mi?

Çoğu zaman HAYIR — eventual consistency + saga pattern + outbox yeterli. Strict ACID sadece finansal sistemlerde gerekli; oradaysa CockroachDB/Spanner gibi global ACID veren sistem kullan.

MongoDB sharding daha mı kolay?

MongoDB native sharding'e sahip — sh.shardCollection() tek komut. Ama trade-off: schema esneklik karşılığında karmaşık aggregation, ACID daha sınırlı. SQL DB'ye alışkın ekipler için Citus/CockroachDB daha doğal.

Sharding ile latency artar mı?

Cross-shard query'lerde EVET — scatter-gather paterni network round-trip ekler. Single-shard query'ler aynı hızda. Doğru shard key seçimi (sorgu kalıplarınızla uyumlu) latency'i düşük tutar.

"Shard rebalance" ne zaman?

Yeni node ekledikten sonra; bir node disk doluysa; hot shard tespit edildiğinde. Manuel veya scheduler ile (örn. Citus citus_rebalance_start()). Production'da rebalance trafik etkisini minimize için off-peak saatlerde.

Backup sharded sistemde nasıl?

Her shard ayrı backup (paralel) + global metadata backup. Snapshot consistency zor — pg_basebackup aynı anda 100 node'da consistent point sağlamaz. Çözüm: per-shard backup + saga timestamps + restore script tüm shard'ları aynı timestamp'e geri sarar.

Büyükweb'de Sharding

Büyükweb VDS ve fiziksel dedicated paketlerinde:

  • Functional sharding: birden fazla VDS, her biri farklı servis DB'si
  • Citus PostgreSQL: 1 coordinator + 3-N worker VDS
  • Vitess MySQL: K8s cluster, çoklu node
  • Read replica: master + 2-3 replica VDS, ayrı IP

Yüksek trafikli e-ticaret/SaaS için mimari danışmanlığı: 0850 302 60 70.

İlgili Rehberler

İlgili Büyükweb Hizmetleri

Veritabanı performansı ve güvenilirliği için Türkiye lokasyonlu sunucu paketlerimiz:

Sorularınız için 0850 302 60 70 numaralı destek hattımıza veya iletişim sayfamıza yazabilirsiniz.

Veritabanı Yönetimi İlgili Hizmetlerimiz

Bu yazıda anlatılan teknik konuyu profesyonel altyapıyla deneyimleyin

Etiketler:

#veritabanı sharding#veritabanı#database#veri yönetimi

Bu yazıyı paylaş