Node Tipleri ve Roller — master, data, coordinating
Giriş — Master, Data, Coordinating, Ingest ve ML Node'ları
Bir hastane düşün. Doktorlar, hemşireler, laborantlar, resepsiyonistler ve yöneticiler var. Herkes farklı bir iş yapar. Doktor ameliyat yapar ama randevu almaz. Resepsiyonist hasta kabul eder ama ilaç vermez. Her rolün ayrı bir uzmanlığı var ve bu ayrım hastaneyi verimli çalıştırır. Eğer tek bir kişi hem ameliyat yapıp hem randevu alsaydı, hastane çökerdi.
Elasticsearch cluster'ı aynı mantık. Her node bir "çalışan" ve farklı roller üstlenebilir. Küçük bir cluster'da herkes her işi yapar (geliştirme ortamı). Ama production'da roller ayrılır — master node cluster yönetimini yapar, data node veriyi saklar, coordinating node sorguları yönlendirir. Bu ayrım, cluster'ın ölçeklenebilir ve dayanıklı olmasını sağlar.
1. Node Rolleri Genel Bakış
Elasticsearch 7.9+ ile birlikte node rolleri daha granüler hale geldi:
| Rol | Görev | Kaynak İhtiyacı |
|---|---|---|
| master | Cluster state yönetimi, index oluşturma/silme, shard atama | Düşük CPU, düşük disk, orta RAM |
| data | Veri saklama, CRUD, arama, aggregation | Yüksek disk, yüksek RAM, yüksek CPU |
| data_hot | Aktif yazma/okuma verisi | Hızlı SSD, yüksek CPU |
| data_warm | Az okunan veri | Orta SSD/HDD |
| data_cold | Nadiren okunan veri | Ucuz HDD |
| data_frozen | Çok nadiren okunan arşiv | Shared storage (S3) |
| ingest | Pipeline ile veri dönüşümü | Orta CPU |
| coordinating | Sorgu yönlendirme, sonuç birleştirme | Orta RAM, orta CPU |
| ml | Machine learning job'ları | Yüksek CPU, yüksek RAM |
| remote_cluster_client | Cross-cluster search | Düşük |
| transform | Transform job'ları | Orta CPU |
Varsayılan Roller
Eğer elasticsearch.yml'de hiçbir rol belirtmezseniz, node tüm rolleri alır:
# Varsayılan — tüm roller aktif (dev/test için OK)
# node.roles: [master, data, data_content, data_hot, data_warm, data_cold,
# data_frozen, ingest, ml, remote_cluster_client, transform]2. Master Node — Cluster Beyni
Master Node Ne Yapar?
Cluster state yönetimi (index listesi, mapping, shard atamaları, node bilgileri)
Index oluşturma ve silme
Shard'ları node'lara atama ve yeniden dağıtma
Node ekleme/çıkarma
Cluster ayar değişiklikleri
Master Node Ne YAPMAZ?
Veri saklamaz
Arama yapmaz
Document indexlemez
Konfigürasyon
# elasticsearch.yml — Dedicated master node
node.roles: [master]
# Cluster adı (tüm node'larda aynı olmalı)
cluster.name: production-cluster
# Node adı
node.name: master-1
# Diğer master-eligible node'lar
discovery.seed_hosts: ["master-1:9300", "master-2:9300", "master-3:9300"]
# İlk cluster başlatmada (sadece bir kere)
cluster.initial_master_nodes: ["master-1", "master-2", "master-3"]Master Election — Seçim Süreci
Elasticsearch, master node'u seçmek için quorum-based bir algoritma kullanır. Çoğunluk (majority) gerekir.
Quorum = (master-eligible node sayısı / 2) + 1| Master-Eligible Node Sayısı | Quorum | Tolere Edilen Kayıp |
|---|---|---|
| 1 | 1 | 0 (single point of failure!) |
| 2 | 2 | 0 (split-brain riski!) |
| 3 | 2 | 1 ✅ |
| 5 | 3 | 2 ✅ |
| 7 | 4 | 3 ✅ |
⚠️ Dikkat: Master-eligible node sayısı her zaman tek sayı olmalı (3, 5, 7). Çift sayı split-brain riskini artırır. Production'da minimum 3 dedicated master node kullanın.
Split-Brain Nedir?
İki grup node birbirini göremediğinde, her grup kendi master'ını seçer ve iki bağımsız cluster oluşur. Bu, veri tutarsızlığına yol açar — felakettir.
# Normal durum:
[Master-1] ←→ [Master-2] ←→ [Master-3]
↕ ↕ ↕
[Data-1] [Data-2] [Data-3]
# Network partition (split-brain):
[Master-1] ←→ [Master-2] | [Master-3]
↕ ↕ | ↕
[Data-1] [Data-2] | [Data-3]
# Sol taraf: 2 master-eligible → quorum sağlar → master seçer
# Sağ taraf: 1 master-eligible → quorum sağlayamaz → master seçemez → bekleme3 master node ile: bir tarafta 2, diğer tarafta 1 kalır. 2'li taraf quorum sağlar, 1'li taraf bekler. Split-brain oluşmaz.
Mevcut Master'ı Kontrol Etme
# Şu anki master
GET _cat/master?v
// Çıktı:
// id host ip node
// abc123def456 10.0.1.10 10.0.1.10 master-1
# Master-eligible node'lar
GET _cat/nodes?v&h=name,role,masterMaster Node Donanım Önerisi
Master node çok kaynak tüketmez ama stabil olmalı:
CPU: 2-4 core yeterli
RAM: 4-8GB heap (cluster state büyüklüğüne bağlı)
Disk: SSD, 50-100GB yeterli
Network: Düşük latency, diğer node'lara hızlı erişim
3. Data Node — Veri Deposu
Data Node Ne Yapar?
Document saklama (CRUD)
Arama (query execution)
Aggregation hesaplama
Segment merge
Shard recovery
Konfigürasyon
# elasticsearch.yml — Dedicated data node
node.roles: [data]
# Veya tiered data rolleri
# node.roles: [data_hot] # Hot tier
# node.roles: [data_warm] # Warm tier
# node.roles: [data_cold] # Cold tier
# node.roles: [data_frozen] # Frozen tier
node.name: data-hot-1
cluster.name: production-cluster
discovery.seed_hosts: ["master-1:9300", "master-2:9300", "master-3:9300"]
# Data path
path.data: /var/data/elasticsearchTiered Data Node'lar (Hot-Warm-Cold)
# Hot node — hızlı SSD, aktif veri
# elasticsearch.yml (hot node)
node.roles: [data_hot, data_content]
node.name: data-hot-1
# Warm node — orta hız, eski veri
# elasticsearch.yml (warm node)
node.roles: [data_warm]
node.name: data-warm-1
# Cold node — yavaş disk, arşiv
# elasticsearch.yml (cold node)
node.roles: [data_cold]
node.name: data-cold-1ILM ile birlikte kullanıldığında:
Yeni veriler hot node'lara yazılır
7 gün sonra warm node'lara taşınır
30 gün sonra cold node'lara taşınır
Data Node Donanım Önerisi
| Tier | CPU | RAM | Disk | Disk Tipi |
|---|---|---|---|---|
| Hot | 16-32 core | 64GB (heap: 30GB) | 2-4TB | NVMe SSD |
| Warm | 8-16 core | 64GB (heap: 30GB) | 4-8TB | SATA SSD |
| Cold | 4-8 core | 32GB (heap: 16GB) | 8-16TB | HDD |
💡 İpucu: Data node'larda heap'i 31GB'ı geçmeyin. JVM compressed ordinary object pointers (compressed oops) 32GB altında çalışır. 31GB heap + OS page cache için kalan RAM = optimal performans.
4. Coordinating Node — Trafik Polisi
Coordinating Node Ne Yapar?
Her node aslında coordinating rolüne sahiptir. Ama dedicated coordinating node, sadece sorgu yönlendirme ve sonuç birleştirme yapar:
Client'tan sorguyu alır
İlgili data shard'larına yönlendirir (scatter phase)
Shard'lardan gelen sonuçları birleştirir (gather phase)
Client'a döner
Konfigürasyon
# elasticsearch.yml — Dedicated coordinating node
# Hiçbir rol vermezseniz, sadece coordinating olur
node.roles: []
node.name: coord-1
cluster.name: production-cluster
discovery.seed_hosts: ["master-1:9300", "master-2:9300", "master-3:9300"]Ne Zaman Dedicated Coordinating Node?
Ağır aggregation'lar: Sonuç birleştirme CPU ve RAM yoğun olabilir. Data node'lara bu yükü bindirmemek için ayrı coordinating node kullanın.
Çok fazla concurrent arama: Client load'unu data node'lardan ayırır.
Heterojen client'lar: Bazı client'lar ağır sorgular atar, diğerleri hafif. Coordinating node load balancer görevi görür.
Coordinating Node Donanım Önerisi
CPU: 8-16 core (sonuç birleştirme CPU yoğun)
RAM: 32-64GB (merge işlemleri bellek kullanır)
Disk: Minimal (veri saklamaz)
5. Ingest Node — Veri Dönüştürücü
Ingest Node Ne Yapar?
Document indexlenmeden önce ingest pipeline ile dönüştürme yapar:
Field ekleme/çıkarma
Veri dönüştürme (lowercase, date parse, grok)
Enrichment (harici veriden zenginleştirme)
GeoIP lookup
Konfigürasyon
# elasticsearch.yml — Dedicated ingest node
node.roles: [ingest]
node.name: ingest-1
cluster.name: production-cluster
discovery.seed_hosts: ["master-1:9300", "master-2:9300", "master-3:9300"]Ingest Pipeline Örneği
// Pipeline oluştur
PUT _ingest/pipeline/web-logs
{
"description": "Web log enrichment",
"processors": [
{
"grok": {
"field": "message",
"patterns": [
"%{COMBINEDAPACHELOG}"
]
}
},
{
"date": {
"field": "timestamp",
"formats": ["dd/MMM/yyyy:HH:mm:ss Z"],
"target_field": "@timestamp"
}
},
{
"geoip": {
"field": "clientip",
"target_field": "geo"
}
},
{
"user_agent": {
"field": "agent",
"target_field": "user_agent"
}
},
{
"remove": {
"field": ["message", "timestamp", "agent"]
}
}
]
}
// Pipeline ile document indexle
POST web-logs/_doc?pipeline=web-logs
{
"message": "83.149.9.216 - - [17/May/2024:10:05:03 +0000] \"GET /presentations/logstash.html HTTP/1.1\" 200 7697 \"http://example.com/\" \"Mozilla/5.0\""
}Ne Zaman Dedicated Ingest Node?
Pipeline'lar ağır işlem yapıyorsa (grok, geoip, enrich)
Yüksek yazma throughput'u varsa
Data node'ların CPU'sunu ingest işlemlerinden korumak istiyorsanız
6. ML (Machine Learning) Node
ML Node Ne Yapar?
Elastic'in machine learning özelliklerini çalıştırır:
Anomaly detection
Forecasting
Classification
Regression
Konfigürasyon
# elasticsearch.yml — Dedicated ML node
node.roles: [ml, remote_cluster_client]
node.name: ml-1
cluster.name: production-cluster
discovery.seed_hosts: ["master-1:9300", "master-2:9300", "master-3:9300"]
# ML spesifik ayarlar
xpack.ml.max_machine_memory_percent: 30
xpack.ml.max_open_jobs: 20ML Node Donanım Önerisi
CPU: 16-32 core (model eğitimi CPU yoğun)
RAM: 64-128GB (büyük modeller)
Disk: SSD, model snapshot'ları için
GPU: Elastic 8.x+ NLP modelleri için faydalı
7. Transform Node
Transform Node Ne Yapar?
Sürekli çalışan transform job'larını çalıştırır. Kaynak index'ten veri okur, dönüştürür, hedef index'e yazar.
# elasticsearch.yml — Transform node
node.roles: [transform, remote_cluster_client]
node.name: transform-1// Transform örneği: Saatlik log özeti
PUT _transform/hourly-log-summary
{
"source": {
"index": "logs-*"
},
"dest": {
"index": "log-summary"
},
"pivot": {
"group_by": {
"hour": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "1h"
}
},
"service": {
"terms": {
"field": "service.keyword"
}
}
},
"aggregations": {
"total_requests": { "value_count": { "field": "@timestamp" } },
"error_count": {
"filter": { "term": { "level": "ERROR" } }
},
"avg_response_time": { "avg": { "field": "response_time" } }
}
},
"frequency": "5m",
"sync": {
"time": {
"field": "@timestamp",
"delay": "60s"
}
}
}
// Transform başlat
POST _transform/hourly-log-summary/_start8. Production Cluster Mimarisi
Küçük Production (Minimum)
3x Master/Data Node (herkes her şeyi yapar)
- node.roles: [master, data, ingest]
- 16 core, 64GB RAM, 2TB SSD
Toplam: 3 nodeOrta Production
3x Dedicated Master Node
- node.roles: [master]
- 4 core, 16GB RAM, 100GB SSD
3x Hot Data Node
- node.roles: [data_hot, data_content, ingest]
- 32 core, 64GB RAM, 4TB NVMe SSD
2x Warm Data Node
- node.roles: [data_warm]
- 16 core, 64GB RAM, 8TB SATA SSD
1x Coordinating Node
- node.roles: []
- 16 core, 32GB RAM
Toplam: 9 nodeBüyük Production
3x Dedicated Master Node
- node.roles: [master]
- 8 core, 32GB RAM, 200GB SSD
10x Hot Data Node (2 availability zone, 5+5)
- node.roles: [data_hot, data_content]
- 32 core, 128GB RAM, 4TB NVMe SSD
6x Warm Data Node
- node.roles: [data_warm]
- 16 core, 64GB RAM, 16TB SATA SSD
4x Cold Data Node
- node.roles: [data_cold]
- 8 core, 32GB RAM, 32TB HDD
3x Coordinating Node (load balancer arkasında)
- node.roles: []
- 16 core, 64GB RAM
2x Ingest Node
- node.roles: [ingest]
- 16 core, 32GB RAM
2x ML Node
- node.roles: [ml]
- 32 core, 128GB RAM
Toplam: 30 nodeMimari Diyagram (Metin)
[Load Balancer]
|
+------------+------------+
| | |
[Coord-1] [Coord-2] [Coord-3]
| | |
+-------+-------+----+----+------+------+
| | | | | |
[Master-1] [Master-2] [Master-3] [Ingest-1] [Ingest-2]
+--------+--------+--------+--------+
| | | | |
[Hot-1] [Hot-2] [Hot-3] [Hot-4] [Hot-5]
+--------+--------+--------+
| | | |
[Warm-1] [Warm-2] [Warm-3] [Warm-4]
+--------+--------+
| | |
[Cold-1] [Cold-2] [Cold-3]
+--------+
| |
[ML-1] [ML-2]9. Java ile Node Bilgisi Sorgulama
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.nodes.InfoResponse;
import co.elastic.clients.elasticsearch.nodes.NodeInfo;
import co.elastic.clients.elasticsearch.cat.NodesResponse;
import co.elastic.clients.elasticsearch.cat.NodesRecord;
public class NodeInspector {
private final ElasticsearchClient client;
public NodeInspector(ElasticsearchClient client) {
this.client = client;
}
public void listNodes() throws Exception {
NodesResponse response = client.cat().nodes(n -> n
.headers("name,ip,role,heap.percent,ram.percent,cpu,master")
);
System.out.println("=== Cluster Nodes ===");
for (NodesRecord node : response.valueBody()) {
System.out.printf("%-15s %-15s roles=%-20s heap=%s%% cpu=%s%% master=%s%n",
node.name(), node.ip(), node.role(),
node.heapPercent(), node.cpu(), node.master());
}
}
public void nodeDetails() throws Exception {
InfoResponse info = client.nodes().info();
info.nodes().forEach((nodeId, nodeInfo) -> {
System.out.println("Node: " + nodeInfo.name());
System.out.println(" Roles: " + nodeInfo.roles());
System.out.println(" Version: " + nodeInfo.version());
System.out.println(" OS: " + nodeInfo.os().prettyName());
if (nodeInfo.jvm() != null) {
System.out.println(" JVM: " + nodeInfo.jvm().version());
System.out.println(" Heap Max: " +
nodeInfo.jvm().mem().heapMaxInBytes() / (1024*1024) + "MB");
}
System.out.println();
});
}
}Role-Based Health Check
public void checkRoleDistribution() throws Exception {
InfoResponse info = client.nodes().info();
int masterCount = 0;
int dataCount = 0;
int coordCount = 0;
int ingestCount = 0;
for (var entry : info.nodes().entrySet()) {
NodeInfo node = entry.getValue();
List<String> roles = node.roles().stream()
.map(r -> r.jsonValue())
.collect(Collectors.toList());
if (roles.contains("master")) masterCount++;
if (roles.contains("data") || roles.contains("data_hot")) dataCount++;
if (roles.isEmpty()) coordCount++;
if (roles.contains("ingest")) ingestCount++;
}
System.out.println("Role Distribution:");
System.out.println(" Master-eligible: " + masterCount);
System.out.println(" Data: " + dataCount);
System.out.println(" Coordinating: " + coordCount);
System.out.println(" Ingest: " + ingestCount);
// Uyarılar
if (masterCount < 3) {
System.err.println("⚠️ WARNING: Less than 3 master-eligible nodes!");
}
if (masterCount % 2 == 0) {
System.err.println("⚠️ WARNING: Even number of master-eligible nodes (split-brain risk)!");
}
}10. Best Practices
✅ Yap
| Konu | Öneri |
|---|---|
| Master node | Dedicated, 3 veya 5 adet, tek sayı |
| Data tiering | Hot/warm/cold ayrımı yap, ILM ile otomatize et |
| Coordinating node | Ağır arama yükünde dedicated kullan |
| Heap boyutu | 31GB'ı geçme (compressed oops) |
| Rol ayrımı | Production'da rolleri ayır, dev'de birleştir |
| Availability zone | Master ve data node'ları farklı zone'lara dağıt |
❌ Yapma
| Konu | Neden |
|---|---|
| Tek master node | Single point of failure |
| 2 master node | Split-brain riski (quorum sağlanamaz) |
| Data node'da master rolü (büyük cluster) | Ağır query data node'u yavaşlatır, master election etkilenir |
| Heap > 31GB | Compressed oops kapanır, bellek verimsiz |
| Tüm node'lara tüm roller | Kaynak izolasyonu yok, sorun tespiti zor |
11. Yaygın Hatalar ve Çözümleri
Hata 1: "Master Not Discovered"
# Sorun: Node cluster'a katılamıyor
# "master not discovered yet, this node has not previously joined..."
# Kontrol 1: discovery.seed_hosts doğru mu?
discovery.seed_hosts: ["master-1:9300", "master-2:9300", "master-3:9300"]
# Kontrol 2: cluster.name aynı mı?
cluster.name: production-cluster # Tüm node'larda aynı olmalı!
# Kontrol 3: Network erişimi var mı?
# Tüm node'lar birbirinin 9300 portuna erişebilmeliHata 2: "Node Left Cluster"
# Sorun: Node sık sık cluster'dan düşüyor
# Olası nedenler:
# 1. GC pause — heap yetersiz
# 2. Network timeout
# 3. Disk I/O yavaşlığı
# Kontrol: Discovery timeout ayarları
# elasticsearch.yml
discovery.cluster_formation_warning_timeout: 10s
cluster.fault_detection.leader_check.timeout: 30s
cluster.fault_detection.leader_check.interval: 2s
cluster.fault_detection.leader_check.retry_count: 5Hata 3: "Too Many Master-Eligible Nodes"
# Sorun: Data node'lar da master-eligible → 20 master candidate
# Seçim yavaşlıyor, cluster state replikasyonu ağırlaşıyor
# Çözüm: Data node'lardan master rolünü kaldır
# elasticsearch.yml (data node)
node.roles: [data_hot] # master yok12. Node Attribute ile Shard Yönlendirme
Custom attribute'lar ile shard'ları belirli node'lara yönlendirebilirsiniz:
# elasticsearch.yml
node.attr.zone: az-1
node.attr.rack: rack-a
node.attr.data_tier: hot// Index'i belirli zone'a yönlendir
PUT my-index/_settings
{
"index.routing.allocation.require.zone": "az-1"
}
// Belirli rack'ten kaçın
PUT my-index/_settings
{
"index.routing.allocation.exclude.rack": "rack-c"
}
// Shard allocation awareness (replica'yı farklı zone'a koy)
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.awareness.attributes": "zone",
"cluster.routing.allocation.awareness.force.zone.values": "az-1,az-2"
}
}Özet
Master node cluster'ın beynidir — index oluşturma, shard atama, cluster state yönetimi yapar. Production'da 3 dedicated master node minimum.
Data node veriyi saklar ve sorguları çalıştırır — en fazla kaynak tüketen node tipidir. Hot/warm/cold tiering ile maliyet optimize edilir.
Coordinating node sorguları yönlendiren "trafik polisi" — ağır aggregation ve yüksek concurrent arama senaryolarında dedicated kullanılmalıdır.
Ingest node veriyi indexlenmeden önce dönüştürür — ağır pipeline işlemleri data node'ların CPU'sunu tüketmesin diye ayrılabilir.
Split-brain'i önlemek için master-eligible node sayısı her zaman tek sayı olmalı ve quorum mekanizması anlaşılmalıdır.
Production'da rolleri ayırın — küçük cluster'da herkes her şeyi yapabilir ama büyüdükçe rol ayrımı zorunlu hale gelir.
AI Asistan
Sorularını yanıtlamaya hazır