← Kursa Dön
📄 Text · 35 min

Capacity Planning — Shard Sizing ve Node Dimensioning

Giriş — Doğru Boyutlandırma Sanatı

Bir restoran açıyorsun. Kaç masa koyacağını planlaman lazım. 10 masa koyarsan, cuma akşamları kapıda kuyruk oluşur — müşteri kaybedersin. 100 masa koyarsan, hafta içi bomboş bir salon kirası ödersin — para kaybedersin. Asıl zor olan şu: müşteri sayısı yıldan yıla artıyor, mutfağın kapasitesi sabit, ve bazen bir anda herkes aynı anda sipariş veriyor.

Elasticsearch capacity planning tam olarak bu. Çok az node koyarsan performans çöker, çok fazla koyarsan bütçe çöker. Doğru "Goldilocks" noktasını bulmak — ne çok sıcak ne çok soğuk — hem bilim hem deneyim gerektiriyor.

Bu derste gerçek rakamlarla, gerçek formüllerle capacity planning yapacağız. "100GB/gün log üreten sistem için kaç node lazım?" sorusuna somut cevap vereceğiz.


1. Shard Sizing — Temelin Temeli

Shard Boyutu Altın Kuralları

Elasticsearch'ün performansının büyük kısmı doğru shard boyutlandırmasına bağlıdır:

KuralDeğerNeden
İdeal shard boyutu10-50 GBOptimal segment merge, recovery süresi
Minimum shard boyutu1 GBAltı overhead'e değmez
Maksimum shard boyutu65 GBÜstü recovery'yi çok uzatır
Node başına max shard1000 (varsayılan)cluster.max_shards_per_node
Shard başına max doküman~2.1 milyarLucene limiti
Heap başına shard~20 shard/GB heapPratik kural

Shard Sayısı Hesaplama Formülü

Primary Shard Sayısı = Toplam Veri (GB) / Hedef Shard Boyutu (GB)
Toplam Shard Sayısı = Primary Shard Sayısı × (1 + Replica Sayısı)

Örnek: 500GB log verisi

Primary shard = 500 / 25 = 20 shard
Replica = 1
Toplam shard = 20 × 2 = 40 shard

Over-Sharding Tehlikesi

Her shard'ın overhead'i vardır:

  • Heap: ~10-50 MB/shard (segment metadata, field data)

  • Thread: Her arama isteği her shard'da bir thread kullanır

  • File handles: Her segment birkaç file descriptor tutar

  • Cluster state: Her shard cluster state'e ~3-5 KB ekler

1000 shard ile 10.000 shard arasındaki fark:

Metrik1000 Shard10000 Shard
Cluster state boyutu~5 MB~50 MB
Heap overhead~10 GB~100 GB
Arama latencyDüşük3-5x yüksek
Master node yüküNormalKritik
# Cluster-wide shard sayısını kontrol et
GET _cluster/health?filter_path=active_primary_shards,active_shards,relocating_shards

# Node başına shard dağılımı
GET _cat/allocation?v&h=node,shards,disk.indices,disk.used,disk.avail,disk.percent

# Shard sayısını sınırla
PUT _cluster/settings
{
  "persistent": {
    "cluster.max_shards_per_node": 1000
  }
}

Shard Boyutu İzleme

# En büyük shard'ları bul
GET _cat/shards?v&h=index,shard,prirep,store,docs,node&s=store:desc&bytes=gb

# Index bazında toplam boyut
GET _cat/indices?v&h=index,pri,rep,docs.count,store.size,pri.store.size&s=store.size:desc&bytes=gb

# Micro-shard'ları tespit et (1GB'dan küçük)
GET _cat/shards?v&h=index,shard,store&bytes=mb&s=store:asc

2. Node Dimensioning — CPU, RAM, Disk

CPU Sizing

Elasticsearch CPU'yu şu işler için kullanır:

  • Arama sorguları (scoring, aggregation)

  • Indexing (analiz, segment write)

  • Merge operations (segment merge)

  • Cluster coordination

CPU Kuralları:

Node TipiÖnerilen CPUAçıklama
Hot data node16-64 coreIndexing + search
Warm data node8-16 coreSadece search
Cold/Frozen node4-8 coreMinimal arama
Master node4-8 coreCluster yönetimi
Coordinating node8-16 coreSorgu dağıtımı, aggregation merge
Ingest node8-16 corePipeline processing

Hyperthreading hakkında: Elasticsearch genellikle fiziksel core'lardan fayda görür. Hyperthreading (SMT) %10-20 arası iyileşme sağlar, %100 değil. 16 fiziksel core > 8 core + HT.

RAM Sizing — %50 Kuralı

Elasticsearch node'unda RAM iki ana amaca hizmet eder:

  1. JVM Heap — Elasticsearch'ün kendi iç yapıları (field data, segment metadata, query cache)

  2. OS Page Cache — Lucene segment dosyalarını cache'lemek

Altın Kural: RAM'in %50'si heap, %50'si OS page cache.

Toplam RAM: 64 GB
├── JVM Heap: 32 GB (ama max 30.5 GB — compressed oops!)
└── OS Page Cache: 32 GB

Neden page cache bu kadar önemli?

Lucene, disk'teki segment dosyalarını okurken OS'un page cache'ini kullanır. Yeterli page cache varsa, "disk okuma" aslında RAM'den okumadır — SSD hızından bile 100x daha hızlı.

# Node'un memory kullanımını kontrol et
GET _nodes/stats/os?filter_path=nodes.*.os.mem

# Page cache etkinliğini izle (Linux)
# OS seviyesinde:
# $ vmstat 1
# $ free -h
# $ cat /proc/meminfo | grep -E "Cached|Buffers|MemFree"

Heap Sizing — Compressed Oops Sınırı

JVM heap sizing, Elasticsearch'ün en kritik konfigürasyon parametresidir.

Hard Rule: Heap asla 30.5 GB'ı geçmemeli.

Neden? Java'nın "Compressed Ordinary Object Pointers" (compressed oops) mekanizması, heap 32 GB altındayken pointer'ları 32-bit olarak saklar. 32 GB üstünde 64-bit pointer'lara geçer — bu da aynı veri için %30-50 daha fazla heap tüketimi demektir.

                     Heap Kullanımı
          ┌─────────────────────────────────┐
   Etkili │                    *            │
   Heap   │               *                │
   Boyutu │          *                      │
          │     *                           │
          │  *                              │
          │*                                │
          └───────────┬─────────────────────┘
                   30.5 GB
                   ↑ Bu noktadan sonra
                   compressed oops kapanır,
                   etkili heap AZALIR!

31 GB heap ≈ 28 GB etkili heap (compressed oops kapalı) 30 GB heap ≈ 30 GB etkili heap (compressed oops açık)

# elasticsearch.yml veya jvm.options ile ayarlama:
# jvm.options dosyasında:
-Xms30g
-Xmx30g

# veya environment variable ile:
# ES_JAVA_OPTS="-Xms30g -Xmx30g"

# Compressed oops durumunu kontrol et:
GET _nodes/jvm?filter_path=nodes.*.jvm.using_compressed_ordinary_object_pointers

Heap formülü:

Heap = min(
  RAM × 0.50,
  30.5 GB
)
Toplam RAMHeapPage CacheNot
16 GB8 GB8 GBKüçük cluster
32 GB16 GB16 GBOrta cluster
64 GB30 GB34 GBBüyük cluster
128 GB30 GB98 GBÇok büyük — heap artmaz!
256 GB30 GB226 GBPage cache cenneti

⚠️ Dikkat: 128 GB+ RAM'li node'larda heap hâlâ 30 GB kalır. Fazla RAM page cache'e gider — bu mükemmeldir. Lucene segment okuma hızı dramatik artar.

Disk Sizing

Disk formülü:

Gerekli Disk = Ham Veri × (1 + Replica) × 1.15 (overhead) × 1.15 (güvenlik marjı)

Örnek: 1 TB ham veri, 1 replica
= 1000 GB × 2 × 1.15 × 1.15
= 2645 GB ≈ 2.6 TB

Overhead faktörleri:

  • Segment merge: Geçici olarak 2x alan kullanabilir

  • Translog: Her shard'da ~512 MB

  • OS + ES runtime: ~5-10 GB

  • Disk watermark: %85'ten sonra shard allocation durur

// Disk watermark ayarları
PUT _cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.disk.watermark.low": "85%",
    "cluster.routing.allocation.disk.watermark.high": "90%",
    "cluster.routing.allocation.disk.watermark.flood_stage": "95%"
  }
}

Low watermark (85%): Yeni shard'lar bu node'a atanmaz. High watermark (90%): Shard'lar bu node'dan taşınmaya başlar. Flood stage (95%): Tüm index'ler read-only yapılır — ACİL DURUM.

SSD Zorunluluğu

Elasticsearch production ortamında SSD (ideali NVMe SSD) zorunludur. HDD ile çalışmayı denemeyin bile — warm/cold tier hariç.

                   IOPS Karşılaştırma
HDD (7200 RPM):    ~100-200 IOPS
SATA SSD:          ~10.000-50.000 IOPS
NVMe SSD:          ~100.000-500.000 IOPS

Elasticsearch'ün ihtiyacı:
- Indexing:   2.000-20.000 IOPS
- Search:     5.000-50.000 IOPS
- Merge:      10.000-100.000 IOPS (burst)

HDD ile ne olur?

  • Merge işlemleri saatlerce sürer

  • Arama latency 100ms'den 10s'ye çıkar

  • Indexing throughput %90 düşer

  • Cluster sürekli "yellow" kalır (recovery yavaş)

💡 İpucu: Warm tier için SATA SSD hâlâ iyi bir seçenek. Cold/Frozen tier için HDD + object storage (S3) makul. Ama hot tier'da NVMe SSD kullanın — %50'den fazla performans farkı yaratır.


3. JVM ve GC Tuning

G1GC — Varsayılan Garbage Collector

Elasticsearch 7.x'ten itibaren varsayılan GC, G1GC'dir (Garbage-First Garbage Collector). Önceki CMS (Concurrent Mark Sweep) artık deprecated.

G1GC Avantajları:

  • Daha öngörülebilir pause time'lar

  • Büyük heap'lerde daha iyi performans

  • Otomatik region boyutlandırma

  • Concurrent marking

# jvm.options — G1GC ayarları (varsayılan, genellikle değiştirmeyin)
-XX:+UseG1GC

# G1GC tuning (ileri seviye, dikkatli!)
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=16m
-XX:InitiatingHeapOccupancyPercent=45

# GC logları (debug için)
-Xlog:gc*,gc+age=trace,safepoint:file=/var/log/elasticsearch/gc.log:utctime,pid,tags:filecount=32,filesize=64m

GC Monitoring

# Node GC istatistikleri
GET _nodes/stats/jvm?filter_path=nodes.*.jvm.gc

# Çıktı yorumlama:
# {
#   "collectors": {
#     "young": {
#       "collection_count": 12500,
#       "collection_time_in_millis": 85000
#     },
#     "old": {
#       "collection_count": 3,
#       "collection_time_in_millis": 1200
#     }
#   }
# }

# Young GC: Sık ama kısa (~5-10ms) — normal
# Old GC: Nadir ama uzun (~200-500ms) — izle
# Old GC > 1 saniye veya çok sık → PROBLEM

GC Pressure İzleme

# Heap kullanım yüzdesi
GET _nodes/stats/jvm?filter_path=nodes.*.jvm.mem.heap_used_percent

# Heap %85 üstünde kalıyorsa → tehlike
# Heap %75 üstünde sürekli → shard sayısını azalt veya heap artır

GC Pressure Belirtileri:

Heap %DurumAksiyon
< 65%SağlıklıBir şey yapma
65-75%İzleTrend'i takip et
75-85%UyarıShard sayısını azalt, query optimize et
85-95%TehlikeAcil node ekle veya veri sil
> 95%Circuit breakerES sorguları reddeder

Circuit Breaker Ayarları

Circuit breaker'lar, OOM'u (Out of Memory) önleyen güvenlik mekanizmalarıdır:

// Circuit breaker ayarları
PUT _cluster/settings
{
  "persistent": {
    "indices.breaker.total.limit": "95%",
    "indices.breaker.fielddata.limit": "40%",
    "indices.breaker.request.limit": "60%",
    "network.breaker.inflight_requests.limit": "100%"
  }
}

// Circuit breaker durumunu kontrol et
GET _nodes/stats/breaker

4. Thread Pool Sizing

Elasticsearch Thread Pool'ları

Elasticsearch, farklı iş tipleri için ayrı thread pool'lar kullanır:

Thread PoolVarsayılanKullanım
searchCPU core × 3 / 2 + 1, queue: 1000Arama sorguları
writeCPU core, queue: 10000Indexing, update, delete, bulk
getCPU core, queue: 1000Get by ID
analyze1, queue: 16_analyze API
management5 (sabit)Cluster yönetimi
flushCPU core / 2Translog flush
force_mergemax(1, core/8)Segment merge
snapshotCPU core / 2Snapshot/restore
# Thread pool durumunu kontrol et
GET _cat/thread_pool?v&h=node_name,name,active,queue,rejected,completed&s=rejected:desc

# Belirli thread pool detayı
GET _nodes/thread_pool/search,write

# Çıktı:
# node_name  name    active queue rejected completed
# node-1     write   12     0     0        1523456
# node-1     search  8      3     15       8745623
# node-2     write   10     125   3        1498234

Rejected count > 0 ise:

  • search rejected: Arama yükü çok fazla. Node ekle veya sorguları optimize et.

  • write rejected: Indexing yükü çok fazla. Bulk size'ı azalt, node ekle.

// Thread pool ayarlarını değiştirme (dikkatli!)
// elasticsearch.yml'de:
// thread_pool:
//   search:
//     size: 25
//     queue_size: 2000
//   write:
//     size: 16
//     queue_size: 20000

⚠️ Dikkat: Thread pool size'ı artırmak genellikle sorunu çözmez, sadece erteler. Asıl çözüm daha fazla node eklemek veya yükü azaltmaktır. Thread'leri artırmak CPU context switching'i artırır ve genel performansı düşürebilir.


5. Memory Pressure ve OS Tuning

Linux Kernel Ayarları

# /etc/sysctl.conf — Production ayarları

# Virtual memory
vm.max_map_count = 262144          # ES zorunlu kılar
vm.swappiness = 1                   # Swap'ı neredeyse kapat

# File descriptors (ulimit)
# /etc/security/limits.conf
# elasticsearch  -  nofile  65535
# elasticsearch  -  nproc   4096

# Transparent Huge Pages — KAPAT
echo never > /sys/kernel/mm/transparent_hugepage/enabled

# Network tuning
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 32768

Swap — Kapatın

Elasticsearch ile swap kullanmak kesinlikle önerilmez. Swap aktifse, GC milyonlarca objeyi taramaya çalışırken swap'a düşen page'leri bekler — bir GC pause 200ms'den 5 dakikaya çıkabilir.

# Swap'ı kapat (geçici)
sudo swapoff -a

# Kalıcı olarak kapat (/etc/fstab'dan swap satırını kaldır)

# Alternatif: bootstrap.memory_lock
# elasticsearch.yml:
bootstrap.memory_lock: true

# ES'in memory lock yapabildiğini doğrula
GET _nodes?filter_path=**.mlockall

Page Cache Optimizasyonu

# Page cache durumunu izle (Linux)
$ cat /proc/meminfo | grep -E "MemTotal|MemFree|Cached|Buffers"
MemTotal:       65879412 kB
MemFree:         2145824 kB
Buffers:          325612 kB
Cached:         31245678 kB    ← Bu değer yüksek olmalı

# ES data dizinindeki dosyaların cache durumu
$ vmtouch /var/lib/elasticsearch/data/

6. Real-World Sizing Örnekleri

Senaryo 1: Log Analytics — 100 GB/gün

Gereksinimler:

  • Günlük 100 GB ham log verisi

  • 30 gün hot retention

  • 90 gün warm retention

  • 365 gün cold retention (searchable snapshot)

  • Ortalama sorgu: 10 req/s, p99 < 500ms

  • Peak indexing: 50.000 event/s

Hesaplama:

Hot Tier Verisi:
= 100 GB/gün × 30 gün = 3 TB ham veri
= 3 TB × 1.15 (overhead) = 3.45 TB
= 3.45 TB × 2 (1 replica) = 6.9 TB

Warm Tier Verisi:
= 100 GB/gün × 60 gün (30-90 gün arası)
= 6 TB × 1.15 × 1.5 (shrink + forcemerge ile %50 küçülme → tekrar büyür replica ile)
≈ 5.2 TB (1 replica, sıkıştırılmış)

Cold Tier Verisi:
= 100 GB/gün × 275 gün (90-365 gün arası)
= 27.5 TB → S3'te, lokal sadece cache ≈ 1 TB lokal disk

Node Planı:

HOT TIER: 3 node
  - Her node: 64 GB RAM, 16 core CPU, 2.5 TB NVMe SSD
  - Heap: 30 GB
  - Disk: 6.9 TB / 3 node ≈ 2.3 TB/node

WARM TIER: 2 node
  - Her node: 32 GB RAM, 8 core CPU, 3 TB SATA SSD
  - Heap: 16 GB
  - Disk: 5.2 TB / 2 node ≈ 2.6 TB/node

COLD TIER: 1 node
  - 16 GB RAM, 4 core CPU, 1 TB SSD (cache), S3 backend
  - Heap: 8 GB

MASTER: 3 dedicated master node (HA için)
  - Her node: 8 GB RAM, 4 core CPU, 50 GB SSD
  - Heap: 4 GB

COORDINATING: 2 node (optional, load balancer arkasında)
  - Her node: 16 GB RAM, 8 core CPU
  - Heap: 8 GB

TOPLAM: 11 node
  Hot: 3 × 64 GB = 192 GB RAM
  Warm: 2 × 32 GB = 64 GB RAM
  Cold: 1 × 16 GB = 16 GB RAM
  Master: 3 × 8 GB = 24 GB RAM
  Coordinating: 2 × 16 GB = 32 GB RAM
  ─────────────────────────────
  Toplam: 328 GB RAM, ~7.5 TB SSD + S3

Shard Planı:

Günlük index: 100 GB / gün
Hedef shard boyutu: 25 GB
Primary shard/index: 4
Replica: 1
Toplam shard/index: 8

30 günlük hot: 30 × 8 = 240 shard (hot tier'da)
60 günlük warm: 60 × 2 = 120 shard (shrink sonrası: 1 pri + 1 rep)
Toplam: ~360 aktif shard

Node başına: ~360 / (3+2) = ~72 shard/node ✅ (limit: 1000)

Senaryo 2: E-Commerce — 10 Milyon Ürün

Gereksinimler:

  • 10 milyon ürün dokümanı (ortalama 2 KB/doküman = 20 GB)

  • Full-text search + faceted search

  • Autocomplete (suggest)

  • Sorgu: 500 req/s, p99 < 100ms

  • Günlük güncelleme: %5 ürün değişir (500K update/gün)

  • HA: Hiçbir node düşünce servis kesintisi olmamalı

Hesaplama:

Toplam Veri:
= 10M × 2 KB = 20 GB ham
= 20 GB × 1.15 (overhead) = 23 GB
= 23 GB × 2 (1 replica) = 46 GB

Shard planı:
= 20 GB / 20 GB (hedef) = 1 primary shard yeterli!
Ama HA ve paralel arama için: 3 primary, 1 replica = 6 shard

Autocomplete index: ~5 GB ek (completion suggester verileri)

Node Planı:

DATA NODE: 3 node (minimum HA için)
  - Her node: 32 GB RAM, 8 core CPU, 500 GB NVMe SSD
  - Heap: 16 GB
  - Disk: 46 GB / 3 ≈ 16 GB/node (disk bol, RAM önemli)

MASTER: Aynı 3 node master rolü de alabilir
  (küçük cluster'da ayrı master gereksiz)

TOPLAM: 3 node
  3 × 32 GB = 96 GB RAM, 1.5 TB SSD

Bu senaryo neden bu kadar küçük? Çünkü 20 GB veri az. E-commerce'de asıl zorluk:

  • Yüksek sorgu throughput (500 req/s) → Yeterli CPU ve page cache

  • Düşük latency (p99 < 100ms) → SSD zorunlu, tüm veri page cache'te olmalı

  • HA → 3 node, 1 replica

💡 İpucu: 20 GB veri + 16 GB heap = tüm veri page cache'te. Bu durumda aramalar bellekten yapılır, disk'e hiç gidilmez. Bu yüzden response time 5-10ms civarında olacaktır.

Senaryo 3: Metrik/Monitoring — 500 GB/gün

Gereksinimler:

  • 500 GB/gün metrik verisi (system metrics, APM, custom metrics)

  • 7 gün hot, 30 gün warm, 90 gün cold (downsample)

  • Peak: 200.000 event/s indexing

  • Dashboard sorguları: 50 req/s, p95 < 2s

HOT TIER:
= 500 GB × 7 = 3.5 TB × 1.15 × 2 (replica) = 8 TB
= 5-6 node, 64 GB RAM, 32 core CPU, 2 TB NVMe SSD

WARM TIER:
= 500 GB × 23 gün × %40 (forcemerge+shrink kazancı) × 1 replica
≈ 6.9 TB
= 3 node, 32 GB RAM, 8 core CPU, 3 TB SATA SSD

COLD TIER (downsampled):
= Downsample sonrası veri %10-20'ye düşer
= 500 GB × 60 gün × %15 = 4.5 TB → S3'te
= 1 node, 16 GB RAM, 1 TB SSD cache

MASTER: 3 dedicated master
  8 GB RAM, 4 core

TOPLAM: 12-15 node

7. Capacity Planning Checklist

Başlamadan Önce Cevaplamanız Gereken Sorular

□ Günlük/aylık veri hacmi nedir? (GB/gün)
□ Veri retention süresi nedir? (gün/ay/yıl)
□ Ortalama doküman boyutu nedir? (KB)
□ Peak indexing rate nedir? (event/saniye)
□ Sorgu tipi nedir? (full-text, term, aggregation)
□ Sorgu throughput ihtiyacı nedir? (req/s)
□ Latency SLA'nız nedir? (p50, p95, p99)
□ HA gereksinimi var mı? (kaç node düşebilir?)
□ Büyüme oranı nedir? (yılda %kaç artış)
□ Bütçe kısıtı var mı?

Hızlı Referans Tablosu

MetrikMinimumÖnerilenMaksimum
Shard boyutu1 GB10-50 GB65 GB
Node başına shard-200-6001000
Heap1 GBRAM×0.530.5 GB
Heap/Shard-50 MB-
Disk watermark (low)-85%-
Disk watermark (high)-90%-
Flood stage-95%-
vm.max_map_count262144262144-
File descriptors6553565535+-
CPU/node (hot)8 core16-32 core64 core
RAM/node (hot)32 GB64 GB256 GB

Boyutlandırma Formülleri Özet

# 1. Toplam disk
Disk = Günlük_Veri × Retention_Gün × (1 + Replica) × 1.3

# 2. Hot node sayısı
Hot_Node = Toplam_Hot_Disk / Node_Disk_Kapasitesi
         (minimum 3 — HA için)

# 3. Heap
Heap = min(RAM × 0.5, 30.5 GB)

# 4. Shard sayısı
Shard = Toplam_Veri / 25 GB  (primary)
Toplam_Shard = Shard × (1 + Replica)

# 5. Node başına shard kontrolü
Shard_Per_Node = Toplam_Shard / Node_Sayısı
                → 600'den az olmalı (ideal < 300)

# 6. Heap/shard kontrolü
Heap_Per_Shard = Heap (MB) / Node_Shard_Sayısı
               → 50 MB'dan fazla olmalı

8. Büyüme Planlaması

Kapasite Büyüme Stratejisi

Yıl 1: 100 GB/gün  → 3 hot node
Yıl 2: 150 GB/gün  → 4 hot node (+1)
Yıl 3: 225 GB/gün  → 5-6 hot node (+2)

%50/yıl büyüme kuralı: Çoğu şirkette log hacmi yılda %30-50 artar. Planlama yaparken 2 yıllık büyümeyi hesaba katın.

Horizontal vs Vertical Scaling

Horizontal (Node Ekle)Vertical (Node Büyüt)
MaliyetLineerEksponansiyel
HADaha iyiDaha kötü
ComplexityDaha fazla node yönetimiDaha basit
SınırTeorik olarak sınırsızRAM/CPU limiti
Tavsiye✅ Tercih edinİlk başta, küçük cluster'da

Ne zaman vertical? 3 node'dan az cluster'larda, önce node'ları büyütmek mantıklı. 3+ node'dan sonra horizontal scaling tercih edin.

Monitoring ile Proaktif Scaling

// Watcher ile kapasite uyarısı
PUT _watcher/watch/disk-space-alert
{
  "trigger": {
    "schedule": { "interval": "1h" }
  },
  "input": {
    "http": {
      "request": {
        "host": "localhost",
        "port": 9200,
        "path": "/_cat/allocation",
        "params": { "format": "json" }
      }
    }
  },
  "condition": {
    "script": {
      "source": "return ctx.payload.body.any(node -> node['disk.percent'] != null && Integer.parseInt(node['disk.percent']) > 80)"
    }
  },
  "actions": {
    "notify": {
      "logging": {
        "text": "UYARI: Disk kullanımı %80 üstünde!"
      }
    }
  }
}

9. Benchmark ve Test

Elasticsearch Rally — Resmi Benchmark Aracı

Rally, Elasticsearch'ün resmi benchmark aracıdır. Gerçek workload'larla cluster'ınızı test eder.

# Rally kurulumu
pip install esrally

# Varsayılan benchmark çalıştır (geonames dataset)
esrally race --track=geonames --target-hosts=localhost:9200

# Özel track ile test
esrally race --track=http_logs --target-hosts=node1:9200,node2:9200

# Sadece indexing testi
esrally race --track=geonames --target-hosts=localhost:9200 --include-tasks="index"

# Sadece search testi  
esrally race --track=geonames --target-hosts=localhost:9200 --include-tasks="default"

Rally Çıktısı Yorumlama:

|   Metric                   |   Value |   Unit |
|:---------------------------|--------:|-------:|
| Indexing throughput         |   28534 | docs/s |
| Total indexing time         |      42 |    min |
| Merge time                  |      12 |    min |
| Query latency (p50)         |     8.2 |     ms |
| Query latency (p99)         |    45.3 |     ms |
| Error rate                  |       0 |      % |

Kendi Benchmark'ınızı Yapın

// 1. Test verisini bulk ile yükleyin
// 2. Farklı shard sayılarıyla aynı veriyi index'leyin
// 3. Aynı sorguları çalıştırıp karşılaştırın

// Arama benchmark (basit)
GET my-test-index/_search
{
  "profile": true,
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "elasticsearch" } }
      ],
      "filter": [
        { "range": { "date": { "gte": "2024-01-01" } } }
      ]
    }
  }
}

// Profile çıktısındaki "time_in_nanos" değerlerini karşılaştırın

10. Yaygın Hatalar ve Anti-Patterns

❌ Yapma

  1. Heap'i 30.5 GB üstüne çıkarma — Compressed oops kapanır, performans DÜŞER

  2. Swap açık bırakma — GC pause'lar dakikalara çıkar

  3. HDD'de hot tier çalıştırma — Merge + search + indexing çöker

  4. Her microservice'e ayrı cluster — Yönetim kabusu, kaynak israfı

  5. Shard sayısını "önceden fazla yapayım" mantığıyla şişirme — Over-sharding overhead'i büyüktür

  6. Default ayarlarla production'a çıkma — vm.max_map_count, file descriptors ayarlanmalı

✅ Yap

  1. Rally ile benchmark yap — Tahmini bırak, ölç

  2. 2 yıllık büyümeyi planla — Bugün yetse de yarın yetmez

  3. Monitoring kur — Disk, heap, GC, thread pool rejection izle

  4. ILM kullan — Verinin yaşam döngüsünü otomatikleştir

  5. Tier architecture kullan — Hot/warm/cold ile maliyet optimize et

  6. Dedicated master node kullan — 5+ node'lu cluster'larda zorunlu


Özet

Bu derste öğrendiklerimizi toplayalım:

  1. Shard boyutu 10-50 GB arasında olmalı. Over-sharding heap tüketir, under-sharding recovery'yi uzatır. Her shard ~50 MB heap overhead'i taşır.

  2. Heap asla 30.5 GB'ı geçmemeli — compressed oops sınırı. RAM'in %50'si heap, %50'si OS page cache. 128 GB RAM'li node'da bile heap 30 GB kalır.

  3. SSD (tercihen NVMe) zorunlu — hot tier için tartışmasız. HDD sadece warm/cold tier'da tolere edilebilir.

  4. Gerçek boyutlandırma somut rakamlarla yapılır: 100 GB/gün log = 3 hot node (64 GB RAM), 2 warm node, 1 cold node, 3 master node ≈ toplam 11 node.

  5. Büyüme planı yapın — %30-50/yıl büyüme normaldir. Horizontal scaling tercih edin, 3+ node'dan sonra node eklemek node büyütmekten daha etkilidir.

  6. Rally ile benchmark yapın, monitoring kurun, ILM ile veri yaşam döngüsünü otomatikleştirin. Capacity planning tek seferlik değil, sürekli bir süreçtir.