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:
| Kural | Değer | Neden |
|---|---|---|
| İdeal shard boyutu | 10-50 GB | Optimal segment merge, recovery süresi |
| Minimum shard boyutu | 1 GB | Altı overhead'e değmez |
| Maksimum shard boyutu | 65 GB | Üstü recovery'yi çok uzatır |
| Node başına max shard | 1000 (varsayılan) | cluster.max_shards_per_node |
| Shard başına max doküman | ~2.1 milyar | Lucene limiti |
| Heap başına shard | ~20 shard/GB heap | Pratik 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 shardOver-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:
| Metrik | 1000 Shard | 10000 Shard |
|---|---|---|
| Cluster state boyutu | ~5 MB | ~50 MB |
| Heap overhead | ~10 GB | ~100 GB |
| Arama latency | Düşük | 3-5x yüksek |
| Master node yükü | Normal | Kritik |
# 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:asc2. 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 CPU | Açıklama |
|---|---|---|
| Hot data node | 16-64 core | Indexing + search |
| Warm data node | 8-16 core | Sadece search |
| Cold/Frozen node | 4-8 core | Minimal arama |
| Master node | 4-8 core | Cluster yönetimi |
| Coordinating node | 8-16 core | Sorgu dağıtımı, aggregation merge |
| Ingest node | 8-16 core | Pipeline 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:
JVM Heap — Elasticsearch'ün kendi iç yapıları (field data, segment metadata, query cache)
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 GBNeden 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_pointersHeap formülü:
Heap = min(
RAM × 0.50,
30.5 GB
)| Toplam RAM | Heap | Page Cache | Not |
|---|---|---|---|
| 16 GB | 8 GB | 8 GB | Küçük cluster |
| 32 GB | 16 GB | 16 GB | Orta cluster |
| 64 GB | 30 GB | 34 GB | Büyük cluster |
| 128 GB | 30 GB | 98 GB | Çok büyük — heap artmaz! |
| 256 GB | 30 GB | 226 GB | Page 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 TBOverhead 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=64mGC 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 → PROBLEMGC 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ırGC Pressure Belirtileri:
| Heap % | Durum | Aksiyon |
|---|---|---|
| < 65% | Sağlıklı | Bir şey yapma |
| 65-75% | İzle | Trend'i takip et |
| 75-85% | Uyarı | Shard sayısını azalt, query optimize et |
| 85-95% | Tehlike | Acil node ekle veya veri sil |
| > 95% | Circuit breaker | ES 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/breaker4. Thread Pool Sizing
Elasticsearch Thread Pool'ları
Elasticsearch, farklı iş tipleri için ayrı thread pool'lar kullanır:
| Thread Pool | Varsayılan | Kullanım |
|---|---|---|
search | CPU core × 3 / 2 + 1, queue: 1000 | Arama sorguları |
write | CPU core, queue: 10000 | Indexing, update, delete, bulk |
get | CPU core, queue: 1000 | Get by ID |
analyze | 1, queue: 16 | _analyze API |
management | 5 (sabit) | Cluster yönetimi |
flush | CPU core / 2 | Translog flush |
force_merge | max(1, core/8) | Segment merge |
snapshot | CPU core / 2 | Snapshot/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 1498234Rejected 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 = 32768Swap — 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=**.mlockallPage 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 diskNode 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 + S3Shard 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 SSDBu 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 node7. 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
| Metrik | Minimum | Önerilen | Maksimum |
|---|---|---|---|
| Shard boyutu | 1 GB | 10-50 GB | 65 GB |
| Node başına shard | - | 200-600 | 1000 |
| Heap | 1 GB | RAM×0.5 | 30.5 GB |
| Heap/Shard | - | 50 MB | - |
| Disk watermark (low) | - | 85% | - |
| Disk watermark (high) | - | 90% | - |
| Flood stage | - | 95% | - |
| vm.max_map_count | 262144 | 262144 | - |
| File descriptors | 65535 | 65535+ | - |
| CPU/node (hot) | 8 core | 16-32 core | 64 core |
| RAM/node (hot) | 32 GB | 64 GB | 256 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) | |
|---|---|---|
| Maliyet | Lineer | Eksponansiyel |
| HA | Daha iyi | Daha kötü |
| Complexity | Daha fazla node yönetimi | Daha basit |
| Sınır | Teorik olarak sınırsız | RAM/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ın10. Yaygın Hatalar ve Anti-Patterns
❌ Yapma
Heap'i 30.5 GB üstüne çıkarma — Compressed oops kapanır, performans DÜŞER
Swap açık bırakma — GC pause'lar dakikalara çıkar
HDD'de hot tier çalıştırma — Merge + search + indexing çöker
Her microservice'e ayrı cluster — Yönetim kabusu, kaynak israfı
Shard sayısını "önceden fazla yapayım" mantığıyla şişirme — Over-sharding overhead'i büyüktür
Default ayarlarla production'a çıkma — vm.max_map_count, file descriptors ayarlanmalı
✅ Yap
Rally ile benchmark yap — Tahmini bırak, ölç
2 yıllık büyümeyi planla — Bugün yetse de yarın yetmez
Monitoring kur — Disk, heap, GC, thread pool rejection izle
ILM kullan — Verinin yaşam döngüsünü otomatikleştir
Tier architecture kullan — Hot/warm/cold ile maliyet optimize et
Dedicated master node kullan — 5+ node'lu cluster'larda zorunlu
Özet
Bu derste öğrendiklerimizi toplayalım:
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.
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.
SSD (tercihen NVMe) zorunlu — hot tier için tartışmasız. HDD sadece warm/cold tier'da tolere edilebilir.
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.
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.
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.
AI Asistan
Sorularını yanıtlamaya hazır