← Kursa Dön
📄 Text · 25 min

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:

RolGörevKaynak İhtiyacı
masterCluster state yönetimi, index oluşturma/silme, shard atamaDüşük CPU, düşük disk, orta RAM
dataVeri saklama, CRUD, arama, aggregationYüksek disk, yüksek RAM, yüksek CPU
data_hotAktif yazma/okuma verisiHızlı SSD, yüksek CPU
data_warmAz okunan veriOrta SSD/HDD
data_coldNadiren okunan veriUcuz HDD
data_frozenÇok nadiren okunan arşivShared storage (S3)
ingestPipeline ile veri dönüşümüOrta CPU
coordinatingSorgu yönlendirme, sonuç birleştirmeOrta RAM, orta CPU
mlMachine learning job'larıYüksek CPU, yüksek RAM
remote_cluster_clientCross-cluster searchDüşük
transformTransform 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ıQuorumTolere Edilen Kayıp
110 (single point of failure!)
220 (split-brain riski!)
321 ✅
532 ✅
743 ✅

⚠️ 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 → bekleme

3 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,master

Master 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/elasticsearch

Tiered 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-1

ILM 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

TierCPURAMDiskDisk Tipi
Hot16-32 core64GB (heap: 30GB)2-4TBNVMe SSD
Warm8-16 core64GB (heap: 30GB)4-8TBSATA SSD
Cold4-8 core32GB (heap: 16GB)8-16TBHDD

💡 İ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:

  1. Client'tan sorguyu alır

  2. İlgili data shard'larına yönlendirir (scatter phase)

  3. Shard'lardan gelen sonuçları birleştirir (gather phase)

  4. 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: 20

ML 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/_start

8. 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 node

Orta 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 node

Bü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 node

Mimari 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 nodeDedicated, 3 veya 5 adet, tek sayı
Data tieringHot/warm/cold ayrımı yap, ILM ile otomatize et
Coordinating nodeAğır arama yükünde dedicated kullan
Heap boyutu31GB'ı geçme (compressed oops)
Rol ayrımıProduction'da rolleri ayır, dev'de birleştir
Availability zoneMaster ve data node'ları farklı zone'lara dağıt

❌ Yapma

KonuNeden
Tek master nodeSingle point of failure
2 master nodeSplit-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 > 31GBCompressed oops kapanır, bellek verimsiz
Tüm node'lara tüm rollerKaynak 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şebilmeli

Hata 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: 5

Hata 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 yok

12. 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

  1. Master node cluster'ın beynidir — index oluşturma, shard atama, cluster state yönetimi yapar. Production'da 3 dedicated master node minimum.

  2. 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.

  3. Coordinating node sorguları yönlendiren "trafik polisi" — ağır aggregation ve yüksek concurrent arama senaryolarında dedicated kullanılmalıdır.

  4. 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.

  5. Split-brain'i önlemek için master-eligible node sayısı her zaman tek sayı olmalı ve quorum mekanizması anlaşılmalıdır.

  6. 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.