Shards ve Replicas — Dağıtık Mimari
Dağıtık Mimari Temelleri
Bir pizza düşün. Tek başına koca bir pizza yiyemezsin — dilimlere ayırırsın. Her dilimi farklı bir tabağa koyabilirsin. Arkadaşların da yardım edebilir — her biri bir dilimi alır, paralel olarak yersiniz. İşte shard, Elasticsearch'teki pizza dilimi. Veriyi parçalara ayırarak birden fazla makineye yayar ve paralel işleme sağlar.
Peki ya bir dilim yere düşerse? İşte replica bu durumda devreye girer — her dilimin bir kopyası başka bir tabakta duruyor. Orijinal kaybolursa kopya orada.
Bu ders, Elasticsearch'ün dağıtık doğasını anlaman için kritik. Production'da doğru shard stratejisi belirlemek, performans ve maliyeti doğrudan etkiler.
Shard Nedir?
Shard, bir index'in fiziksel parçasıdır. Her shard kendi başına çalışabilen bir Lucene instance'ıdır. Lucene, tüm arama işlemlerini gerçekleştiren alt motordur — Elasticsearch onu orkestra eder.
Index: "products" (tüm ürün verileri — 10.000 doküman)
├── Shard 0 (Doküman 1-3333) → Node 1'de
├── Shard 1 (Doküman 3334-6666) → Node 2'de
└── Shard 2 (Doküman 6667-10000) → Node 3'teBir index oluşturduğunda shard sayısını belirtirsin:
PUT /products
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}Neden Shard'lara Bölüyoruz?
1. Paralel İşleme (Concurrency)
3 shard'lı bir index'e arama sorgusu gönderdiğinde, 3 shard aynı anda paralel çalışır. Tek shard'da 300ms sürecek sorgu, 3 shard'da ~100ms sürer.
2. Yatay Ölçekleme (Horizontal Scaling)
Tek makinenin diski 500GB. 1TB verin varsa ne yaparsın? 2 makineye yayarsın. 5TB olursa 10 makineye. Shard'lar bunu mümkün kılar.
3. Veri Dağıtımı (Distribution)
Shard'lar cluster'daki node'lara otomatik dağıtılır. Yeni node eklediğinde Elasticsearch shard'ları otomatik yeniden dengeler (rebalance).
Primary Shard ve Replica Shard
İki tür shard var:
Primary Shard: Orijinal veri parçası. Yazma işlemleri (index, update, delete) önce primary shard'a gider.
Replica Shard: Primary shard'ın birebir kopyası. İki amaca hizmet eder:
Yüksek erişilebilirlik (HA): Primary çökerse replica devralır
Okuma performansı: Arama sorguları replica'lardan da cevaplanabilir
Index: "products" (3 primary, 1 replica)
Node 1: [P0] [R1] [R2]
Node 2: [R0] [P1] [R2']
Node 3: [R0'] [R1'] [P2]
P = Primary Shard
R = Replica Shard⚠️ Kritik Kural: Primary shard ile onun replica'sı asla aynı node'da bulunmaz. Çünkü node çökerse ikisi de kaybolurdu — replica'nın tüm amacı boşa giderdi.
Toplam Shard Sayısı Hesabı
Toplam shard = primary_shards × (1 + number_of_replicas)
Örnek: 3 primary, 1 replica
Toplam = 3 × (1 + 1) = 6 shard
Örnek: 5 primary, 2 replica
Toplam = 5 × (1 + 2) = 15 shardShard Dağılımını Görme
// Tüm shard'ları listele
GET /_cat/shards?v
// Belirli bir index'in shard'ları
GET /_cat/shards/products?v
// Yanıt:
// index shard prirep state docs store node
// products 0 p STARTED 3333 15mb node-1
// products 0 r STARTED 3333 15mb node-2
// products 1 p STARTED 3333 15mb node-2
// products 1 r STARTED 3333 15mb node-3
// products 2 p STARTED 3334 15mb node-3
// products 2 r STARTED 3334 15mb node-1
// prirep: p = primary, r = replica
// state: STARTED = aktif, UNASSIGNED = atanamamış, RELOCATING = taşınıyor
// Shard allocation açıklaması (sorun varsa)
GET /_cluster/allocation/explain
// Her node'daki shard dağılımı
GET /_cat/allocation?vShard Sayısını Belirlemek
Bu Elasticsearch'teki en kritik tasarım kararlarından biri. Yanlış shard sayısı ya performans sorunlarına ya da gereksiz kaynak israfına yol açar.
Shard Başına Önerilen Boyut
Elastic'in resmi önerisi:
Her shard: 10GB ile 50GB arası
Hedef: ~30GB per shard (ideal nokta)
Minimum: 1GB'dan küçük shard'lardan kaçın| Toplam Veri | Önerilen Primary Shard | Mantık |
|---|---|---|
| 1 GB | 1 shard | Gereksiz overhead'den kaçın |
| 10 GB | 1 shard | Hâlâ tek shard yeterli |
| 50 GB | 2 shard | ~25GB per shard |
| 100 GB | 3-5 shard | ~20-33GB per shard |
| 500 GB | 10-20 shard | ~25-50GB per shard |
| 1 TB | 20-40 shard | ~25-50GB per shard |
| 10 TB | 200-400 shard | Genelde çoklu index ile dağıtılır |
Çok Az Shard — Sorunlar
Index: "big-data" (1 shard, 500GB)
└── Shard 0 (500GB) → Tek node'da
Sorunlar:
❌ Paralel işleme yok — tüm sorgular tek shard'a gider
❌ Node'un diski dolabilir — ölçekleyemezsin
❌ Recovery çok uzun sürer — node çökerse 500GB kopyalanması gerekir
❌ Rebalance yapılamaz — veriyi bölemezsin
❌ Hot spot — tek node aşırı yüklenirÇok Fazla Shard — Sorunlar
Index: "small-data" (100 shard, 100MB toplam)
├── Shard 0 (1MB)
├── Shard 1 (1MB)
├── ...
└── Shard 99 (1MB)
Sorunlar:
❌ Her shard ~50MB memory overhead (Lucene segments, file handles, buffers)
❌ 100 shard × 50MB = 5GB sadece overhead — verin sadece 100MB!
❌ Koordinasyon maliyeti — her sorgu 100 shard'a fan-out yapar
❌ Master node'da cluster state şişmesi
❌ Merge overhead — her shard'da ayrı segment yönetimiShard Sayısı Hesaplama Formülü
Primary shard sayısı = Toplam veri boyutu / Hedef shard boyutu
Örnek:
- Beklenen veri: 150 GB
- Hedef shard boyutu: 30 GB
- Primary shard sayısı: 150 / 30 = 5
Toplam shard (replica dahil):
5 primary × (1 + 1 replica) = 10 shard
Minimum node sayısı: 2 (replica kuralı gereği)Bir Diğer Kural: Node Başına Shard
Genel kural: Node başına 20 shard per GB heap
Örnek:
- Heap: 4GB
- Maksimum shard/node: 4 × 20 = 80 shard
- Ama genellikle node başına 200-400 shard üst sınır önerilirZaman Bazlı Index'lerde Shard Stratejisi
Log verisi gibi sürekli büyüyen veriler için:
// Günlük index — her gün yeni index oluşur
// app-logs-2025.01.15 → 1 shard (günlük ~5GB veri)
// app-logs-2025.01.16 → 1 shard
// app-logs-2025.01.17 → 1 shard
// ...
PUT /_index_template/logs-template
{
"index_patterns": ["app-logs-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
}
// 1 yıllık veri = 365 index × 1 primary × 2 (1 replica) = 730 shard
// Bu yönetilebilir bir sayıZaman bazlı index'lerde her index küçük olduğu için shard sayısı az tutulur. Ölçekleme, index sayısıyla sağlanır. Eski veriyi silmek de kolay — sadece eski index'i sil.
Replica Detaylı
Replica, primary shard'ın birebir kopyasıdır. Ama basit bir kopyadan çok daha fazlası.
Replica'nın İki Temel Görevi
1. Yüksek Erişilebilirlik (High Availability)
Bir node çöktüğünde veri kaybı olmaz:
Senaryo: Node 2 çöktü
ÖNCE:
Node 1: [P0] [R1]
Node 2: [P1] [R0] ← ÇÖKTÜ!
Node 3: [P2] [R1']
SONRA (otomatik recovery):
1. Elasticsearch R0'ı bulur (Node 1 veya Node 3'te olabilir)
2. R0, P1'e promote edilir (primary olur)
3. Yeni replica'lar oluşturulur (kalan node'lara dağıtılır)
Node 1: [P0] [R1] [P1*] ← R0 artık yeni P1
Node 3: [P2] [R1'] [R0*] ← Yeni R0 oluşturuldu
Veri kaybı: SIFIR ✅
Servis kesintisi: Birkaç saniye (shard relocation süresi)2. Okuma Performansı
Arama sorguları hem primary hem replica shard'lardan cevaplanabilir:
1 primary + 1 replica = 2× okuma kapasitesi
1 primary + 2 replica = 3× okuma kapasitesi
Arama sorgusu geldi → Koordinator node seçer:
Shard 0 → Node 1 (primary) VEYA Node 2 (replica) — en az meşgul olanı
Shard 1 → Node 2 (primary) VEYA Node 3 (replica) — en az meşgul olanı
Shard 2 → Node 3 (primary) VEYA Node 1 (replica) — en az meşgul olanı
Elasticsearch, Adaptive Replica Selection ile en hızlı yanıt verecek shard'ı seçer.Yazma İşleminde Replica'nın Rolü
Client: "Bu dokümanı index'le"
↓
1. Koordinator → Routing → Primary Shard (Node 2)
2. Primary Shard yazar → Başarılı
3. Primary → Tüm replica'lara paralel gönderir
4. Replica'lar yazar → Başarılı
5. Primary → Client'a "201 Created" döner
wait_for_active_shards parametresi bu davranışı kontrol eder:
- "all": Tüm replica'lar yazana kadar bekle (en güvenli, en yavaş)
- "1": Sadece primary yazınca dön (hızlı ama veri kaybı riski)
- varsayılan: "1" (sadece primary)// Tüm replica'ların yazmasını bekle
PUT /products/_doc/1?wait_for_active_shards=all
{
"name": "Laptop",
"price": 15000
}
// Minimum 2 shard'ın aktif olmasını bekle
PUT /products/_doc/2?wait_for_active_shards=2
{
"name": "Mouse",
"price": 300
}Replica Ayarları
// Index oluşturulurken
PUT /products
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1 // Her primary'nin 1 kopyası
}
}
// Replica sayısı sonradan değiştirilebilir!
PUT /products/_settings
{
"number_of_replicas": 2 // Artık her primary'nin 2 kopyası var
}
// Replica'yı kapat (development ortamı veya yazma performansı için)
PUT /products/_settings
{
"number_of_replicas": 0
}💡 İpucu: Primary shard sayısı index oluşturulduktan sonra değiştirilemez (split/shrink API hariç). Replica sayısı ise istediğin zaman değiştirilebilir. Bu fark çok önemli.
Cluster Durumu ve Replica İlişkisi
GET /_cluster/health
// Yanıt:
{
"status": "green", // veya "yellow" veya "red"
"number_of_nodes": 3,
"active_primary_shards": 3,
"active_shards": 6,
"unassigned_shards": 0
}| Status | Anlam | Ne Yapmalı? |
|---|---|---|
| 🟢 green | Tüm primary + replica atanmış | Her şey yolunda |
| 🟡 yellow | Tüm primary atanmış, bazı replica atanamadı | Replica sorunu — ama veri erişilebilir |
| 🔴 red | Bazı primary shard'lar atanamadı | ACİL — veri erişilemez olabilir |
Tek node cluster neden "yellow"?
Ayar: 1 primary, 1 replica
Node sayısı: 1
Primary shard → Node 1'e atandı ✅
Replica shard → Nereye atanacak? Node 1'e atanamaz (aynı node kuralı) → ATANAMADI ⚠️
Sonuç: Cluster status = YELLOWTek node'da çalışıyorsan replica'yı 0 yap:
PUT /my-index/_settings
{
"number_of_replicas": 0
}
// Artık cluster status = GREEN ✅Routing — Document Hangi Shard'a Gider?
Bir document index'lendiğinde hangi shard'a yazılacağı routing formülü ile belirlenir:
shard_number = hash(_routing) % number_of_primary_shardsVarsayılan _routing değeri document'ın _id'sidir:
Document ID: "abc123"
hash("abc123") = 587234891
587234891 % 3 = 1
→ Bu document Shard 1'e yazılırBu formül deterministik — aynı ID her zaman aynı shard'a gider. Bu yüzden GET /products/_doc/abc123 dediğinde Elasticsearch hangi shard'a bakacağını bilir — tüm shard'ları taramaz.
Custom Routing
Belirli bir kritere göre ilişkili document'ları aynı shard'a yönlendirebilirsin:
// Aynı müşterinin tüm siparişleri aynı shard'da
PUT /orders/_doc/order-1?routing=customer-42
{
"customer_id": "customer-42",
"product": "Laptop",
"amount": 75000
}
PUT /orders/_doc/order-2?routing=customer-42
{
"customer_id": "customer-42",
"product": "Mouse",
"amount": 300
}
// Arama yaparken de routing belirt — sadece 1 shard taranır
GET /orders/_search?routing=customer-42
{
"query": {
"term": { "customer_id": "customer-42" }
}
}
// 100 shard yerine 1 shard tarandi → ~100x daha hızlı!⚠️ Dikkat: Custom routing ile bazı shard'lar diğerlerinden çok daha fazla veri barındırabilir (hot shard / data skew). Routing key'i dengeli dağılımlı olmalı.
Neden Primary Shard Sayısı Değiştirilemez?
Routing formülünü hatırla:
shard = hash(id) % number_of_primary_shardsShard sayısı 3'ten 5'e değişirse:
hash("abc123") % 3 = 1 (Shard 1'deydi)
hash("abc123") % 5 = 3 (Artık Shard 3'e bakıyor — ama veri Shard 1'de!)
→ Document bulunamaz!Bu yüzden shard sayısı değiştiğinde tüm verinin yeniden dağıtılması gerekir — yani reindex.
Arama İşleminin Shard'larla Çalışması
Bir arama sorgusunun perde arkasında ne olduğunu adım adım görelim:
Phase 1: Query (Sorgu Fazı)
Client → GET /products/_search { "query": { "match": { "name": "laptop" } }, "size": 10 }
1. Client → Koordinator Node'a sorgu gönderir
2. Koordinator, sorguyu TÜM ilgili shard'lara (primary veya replica) yönlendirir
- Shard 0 (Node 1) → Local arama başlat
- Shard 1 (Node 2) → Local arama başlat
- Shard 2 (Node 3) → Local arama başlat
3. Her shard kendi local top-10 sonucunu döndürür (sadece _id ve _score)
4. Koordinator, 3 × 10 = 30 sonucu birleştirir, global top-10'u belirlerPhase 2: Fetch (Getirme Fazı)
5. Koordinator, seçilen 10 document'ın _source verisini ilgili shard'lardan ister
- Shard 0'dan 3 doküman
- Shard 1'den 4 doküman
- Shard 2'den 3 doküman
6. Shard'lar _source verilerini gönderir
7. Koordinator, nihai sonucu sıralı şekilde client'a döndürür// Bu sorgu:
GET /products/_search
{
"query": { "match": { "name": "laptop" } },
"size": 10,
"from": 0
}
// Aslında her shard'da "from + size" kadar sonuç hesaplanır:
// Her shard → top (0 + 10) = 10 sonuç döner
// Koordinator → 30 sonucu birleştirir → en iyi 10'u seçer
// Deep pagination sorunu:
GET /products/_search
{
"query": { "match_all": {} },
"size": 10,
"from": 10000
}
// Her shard → top 10010 sonuç hesaplar!
// Koordinator → 30030 sonucu birleştirir!
// Bu yüzden from + size > 10000 performans sorunları yaratır.
// Çözüm: search_after veya scroll API (Bölüm 6'da)Node Tipleri ve Shard İlişkisi
┌──────────────────────────────────────────────────────────────┐
│ CLUSTER │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Master Node │ │ Data Node 1 │ │ Data Node 2 │ │
│ │ (Yönetici) │ │ (İşçi) │ │ (İşçi) │ │
│ │ │ │ [P0][R1][R2] │ │ [R0][P1][P2] │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ↕ ↕ ↕ │
│ Cluster state Veri saklama Veri saklama │
│ Index yönetimi Arama Arama │
│ Shard allocation Indexleme Indexleme │
└──────────────────────────────────────────────────────────────┘| Node Tipi | Rol | Shard Saklar mı? |
|---|---|---|
| Master | Cluster yönetimi, shard allocation kararları | Genelde hayır (dedicated master) |
| Data | Veri saklama, arama, indexleme | Evet — asıl iş burada |
| Coordinating | Sorguları yönlendirme, sonuç birleştirme | Hayır |
| Ingest | Veri dönüşüm pipeline'ları | Hayır |
| ML | Machine Learning işleri | Hayır |
Küçük cluster'larda (2-3 node) her node tüm rolleri üstlenir. Büyük cluster'larda roller ayrılır — dedicated master, dedicated data node'lar.
Index Lifecycle Management (ILM) — Kısa Tanıtım
Zaman bazlı verilerde shard yönetimini otomatikleştirmek için ILM kullanılır:
// ILM Policy oluştur
PUT /_ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_primary_shard_size": "30gb",
"max_age": "7d"
}
}
},
"warm": {
"min_age": "30d",
"actions": {
"shrink": {
"number_of_shards": 1
},
"forcemerge": {
"max_num_segments": 1
}
}
},
"cold": {
"min_age": "90d",
"actions": {
"readonly": {}
}
},
"delete": {
"min_age": "365d",
"actions": {
"delete": {}
}
}
}
}
}
// Policy'yi index template'e bağla
PUT /_index_template/logs-template
{
"index_patterns": ["app-logs-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "logs-policy"
}
}
}Yaşam döngüsü:
Hot (0-7 gün): Yüksek performanslı SSD, aktif yazma, tam replica
Warm (7-90 gün): Okuma ağırlıklı, shrink + forcemerge ile optimize
Cold (90-365 gün): Düşük kaynak, sadece nadir sorgular
Delete (365+ gün): Otomatik silme — disk alanı geri kazanılırSplit ve Shrink API
Shard sayısını doğrudan değiştirmek mümkün değil ama bu API'lerle dolaylı olarak yapılabilir:
Shrink — Shard Sayısını Azalt
// 1. Tüm shard'ları tek node'a taşı ve readonly yap
PUT /products/_settings
{
"settings": {
"index.routing.allocation.require._name": "node-1",
"index.blocks.write": true
}
}
// 2. Shard sayısını azalt (bölünebilir olmalı: 6→3, 6→2, 6→1)
POST /products/_shrink/products-shrunk
{
"settings": {
"index.number_of_shards": 1,
"index.number_of_replicas": 1,
"index.routing.allocation.require._name": null,
"index.blocks.write": null
}
}
// 3. Alias'ı güncelle
POST /_aliases
{
"actions": [
{ "remove": { "index": "products", "alias": "products-alias" } },
{ "add": { "index": "products-shrunk", "alias": "products-alias" } }
]
}Split — Shard Sayısını Artır
// 1. readonly yap
PUT /products/_settings
{
"settings": {
"index.blocks.write": true
}
}
// 2. Shard sayısını artır (çarpanı olmalı: 1→2, 1→3, 2→4, 2→6)
POST /products/_split/products-split
{
"settings": {
"index.number_of_shards": 6,
"index.blocks.write": null
}
}⚠️ Her iki operasyon da yeni bir index oluşturur. Bu yüzden alias kullanmak çok önemli.
Java ile Shard Bilgisi Sorgulama
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.cluster.HealthResponse;
import co.elastic.clients.elasticsearch.cat.ShardsResponse;
import co.elastic.clients.elasticsearch.cat.shards.ShardsRecord;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
class Main {
public static void main(String[] args) throws Exception {
RestClient restClient = RestClient.builder(
new HttpHost("localhost", 9200)
).build();
ElasticsearchClient client = new ElasticsearchClient(
new RestClientTransport(restClient, new JacksonJsonpMapper())
);
// Cluster health kontrolü
HealthResponse health = client.cluster().health();
System.out.println("Status: " + health.status());
System.out.println("Nodes: " + health.numberOfNodes());
System.out.println("Data nodes: " + health.numberOfDataNodes());
System.out.println("Active primary shards: " + health.activePrimaryShards());
System.out.println("Active shards (total): " + health.activeShards());
System.out.println("Relocating shards: " + health.relocatingShards());
System.out.println("Initializing shards: " + health.initializingShards());
System.out.println("Unassigned shards: " + health.unassignedShards());
// Shard listesi
ShardsResponse shards = client.cat().shards();
for (ShardsRecord record : shards.valueBody()) {
System.out.printf("Index: %-15s | Shard: %s | Type: %s | State: %-10s | Docs: %s | Size: %s | Node: %s%n",
record.index(), record.shard(), record.prirep(),
record.state(), record.docs(), record.store(), record.node()
);
}
// Index ayarlarını kontrol et (shard/replica sayısı)
var settings = client.indices().getSettings(g -> g.index("products"));
var indexSettings = settings.get("products").settings().index();
System.out.println("Number of shards: " + indexSettings.numberOfShards());
System.out.println("Number of replicas: " + indexSettings.numberOfReplicas());
restClient.close();
}
}Gerçek Dünya Senaryosu: E-Ticaret Shard Planlaması
Bir e-ticaret platformu planlıyorsun:
Ürünler: 5 milyon ürün × ortalama 2KB = ~10GB
→ 1 primary shard yeterli
→ 1 replica (HA için)
Siparişler: Günlük 50.000 sipariş × 1KB = ~50MB/gün = ~18GB/yıl
→ Aylık index: orders-2025.01, orders-2025.02...
→ Her index 1 shard (aylık ~1.5GB)
→ 1 replica
Arama logları: Günlük 10 milyon arama × 500B = ~5GB/gün
→ Günlük index: search-logs-2025.01.15
→ Her index 1 shard (günlük ~5GB)
→ 0 replica (kaybedilse de önemli değil)
→ ILM: 30 gün sonra sil
Uygulama logları: Günlük 50 milyon log × 200B = ~10GB/gün
→ Günlük index
→ Her index 1 shard
→ 1 replica
→ ILM: 90 gün warm, 365 gün sonra sil// E-ticaret ürün index'i
PUT /products
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
// Sipariş index template
PUT /_index_template/orders-template
{
"index_patterns": ["orders-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
}
// Arama log template
PUT /_index_template/search-logs-template
{
"index_patterns": ["search-logs-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index.lifecycle.name": "search-logs-policy"
}
}
}Best Practices
✅ Shard başına 10-50GB hedefle — Çok küçük shard overhead yaratır, çok büyük shard esneklik kaybettirir
✅ Tek node'da replica 0 yap — Yoksa cluster hep yellow kalır ve gereksiz uyarı üretir
✅ Production'da minimum 3 node — High availability ve proper replica dağılımı için
✅ Zaman bazlı veriler için daily/weekly/monthly index — Eski veriyi temizlemek kolay
✅ ILM kullan — Hot-warm-cold-delete lifecycle'ı otomatikleştir
✅ Shard sayısını veri boyutuna göre belirle — 1GB veri için 10 shard oluşturma
✅ Cluster health'i izle — green kalmasını sağla, yellow ve red'i ciddiye al
✅ Alias kullan — Shard değişikliği (shrink/split) gerektiğinde zero-downtime geçiş
Yaygın Hatalar
❌ "Her index'e 5 shard veriyorum"
Elasticsearch 6.x'in varsayılanı 5 shard idi. 7.x'te 1'e düşürüldü — çoğu index için 1 yeterli. Ama insanlar hâlâ eski alışkanlıkla 5 yazıyor.
❌ "Tek node'da replica 1 kullanıyorum"
Replica aynı node'a atanamaz. Tek node'da replica 0 yap.
❌ "Shard sayısını sonra ayarlarım"
Primary shard sayısı değiştirilemez. İlk günden doğru planlama yap. Split/Shrink API var ama overhead'li ve yeni index oluşturur.
❌ "Binlerce küçük index oluşturuyorum"
Her index en az 1 shard. 10.000 index × 1 shard × 1 replica = 20.000 shard. Bu master node'u ezer. Data streams veya index consolidation düşün.
❌ "Cluster red oldu, panik!"
Red status acil ama panik yapmak yerine sistematik debug:
// 1. Hangi index'ler red?
GET /_cat/indices?health=red&v
// 2. Hangi shard'lar atanamıyor?
GET /_cat/shards?h=index,shard,prirep,state,unassigned.reason&s=state:desc
// 3. Neden atanamıyor?
GET /_cluster/allocation/explainÖzet
Shard, index'in fiziksel parçasıdır — her shard bağımsız bir Lucene instance'ı
Primary shard orijinal veri, replica shard kopyasıdır — farklı node'larda bulunur
Primary shard sayısı index oluşturulurken belirlenir ve değiştirilemez (split/shrink hariç)
Replica sayısı istediğin zaman değiştirilebilir
Cluster durumu: green (tümü atanmış), yellow (replica eksik), red (primary eksik)
Shard başına 10-50GB hedefle — çok az veya çok fazla shard performansı bozar
Document routing formülü:
hash(_id) % number_of_shards— bu yüzden shard sayısı sabitArama iki fazda çalışır: Query (her shard local top-N) + Fetch (seçilen sonuçların _source'ları)
ILM ile hot-warm-cold-delete lifecycle'ı otomatikleştir
Bir sonraki derste Inverted Index konusunu işleyeceğiz — Elasticsearch'ün milisaniyede milyonlarca kayıt arayabilmesinin sırrını öğreneceğiz!
AI Asistan
Sorularını yanıtlamaya hazır