← Kursa Dön
📄 Text · 35 min

Index Lifecycle Management ve Data Streams

Giriş — Verinin Yaşam Döngüsünü Yönetmek

Bir süpermarket düşün. Rafların önünde taze ürünler duruyor — müşteriler bunlara hızlıca ulaşmalı. Biraz daha eski ürünler arka raflara geçiyor. Son kullanma tarihi yaklaşanlar indirimli sepete konuyor. Tamamen bayatlayanlar çöpe gidiyor. Bu döngüyü elle yönetmeye kalksan, 50 çalışan yetmez. Ama bir sistem kursan — "3 gün → arka raf, 7 gün → indirim, 10 gün → çöp" — süpermarket kendini yönetir.

Elasticsearch'te Index Lifecycle Management (ILM) tam olarak bu. Verinin doğduğu andan silindiği ana kadar otomatik yönetim. Hot tier'da hızla yazılır, warm'a geçer yavaş disklerle okumaya devam eder, cold'da sıkıştırılır, frozen'da searchable snapshot olur, sonunda silinir. Hepsi otomatik — sen sadece policy'yi tanımlarsın, gerisini Elasticsearch halleder.

Bu derste ILM'in her phase'ini, her action'ını, data streams'in iç yapısını, TSDS'yi, downsampling'i ve data tier mimarisini en ince ayrıntısına kadar göreceğiz.


1. ILM — Index Lifecycle Management Temelleri

ILM Neden Var?

Time-series verileri (loglar, metrikler, event'ler) sürekli büyür. Günde 100GB log üreten bir sistemde 1 yılda 36TB veri birikir. Bu verinin hepsini aynı performanslı donanımda tutmak hem gereksiz hem pahalıdır.

ILM'in çözdüğü problem:

  • Eski veriyi ucuz donanıma taşı — SSD → HDD → object storage

  • İndex'leri otomatik yönet — rollover, shrink, merge

  • Disk alanını koru — belirli yaştan sonra otomatik sil

  • Performansı optimize et — sıcak veriye hızlı donanım, soğuk veriye yavaş ama ucuz donanım

ILM'in 5 Phase'i

ILM, bir index'in yaşam döngüsünü 5 aşamada yönetir:

HOT → WARM → COLD → FROZEN → DELETE
 ↑                                ↑
 Veri yazılıyor              Veri siliniyor

Her phase'in geçiş koşulları ve action'ları vardır. Tüm phase'leri kullanmak zorunda değilsiniz — sadece ihtiyacınız olanları tanımlarsınız.

// Minimal ILM policy — sadece hot + delete
PUT _ilm/policy/minimal-policy
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "50gb",
            "max_age": "1d"
          }
        }
      },
      "delete": {
        "min_age": "30d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

min_age Hesaplaması

Kritik detay: min_age her phase için bir önceki phase'e göre değil, index'in oluşturulma tarihine göre hesaplanır. Ama rollover kullandığınızda, rollover zamanına göre hesaplanır.

// Bu policy'de:
// - Index oluşturuldu (t=0)
// - Hot phase: hemen başlar
// - Rollover: 1 gün sonra veya 50GB olunca
// - Warm: rollover'dan 2 gün sonra
// - Cold: rollover'dan 7 gün sonra  
// - Delete: rollover'dan 30 gün sonra
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "50gb",
            "max_age": "1d"
          }
        }
      },
      "warm": {
        "min_age": "2d",
        "actions": {}
      },
      "cold": {
        "min_age": "7d",
        "actions": {}
      },
      "delete": {
        "min_age": "30d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

⚠️ Dikkat: Rollover kullanılmadığında min_age, index creation date'e göre hesaplanır. Rollover kullanıldığında ise rollover time'a göre hesaplanır. Bu fark çok kişiyi yanıltır.


2. Phase'ler ve Action'lar — Detaylı İnceleme

2.1 HOT Phase

Hot phase, verinin aktif olarak yazıldığı aşamadır. En hızlı donanımda (NVMe SSD, yüksek CPU) çalışır.

Kullanılabilir Action'lar:

ActionAçıklama
rolloverBelirli koşullar sağlanınca yeni index oluştur
set_priorityIndex recovery önceliğini ayarla
unfollowCCR takibini durdur
readonlyIndex'i salt okunur yap
downsampleTime-series verisini özetle (8.5+)
forcemergeSegment sayısını azalt
shrinkShard sayısını azalt
searchable_snapshotSearchable snapshot'a dönüştür

Rollover — Hot Phase'in Kalbi:

Rollover, bir index belirli koşulları sağladığında otomatik olarak yeni bir index oluşturur ve yazma işlemlerini yeni index'e yönlendirir.

PUT _ilm/policy/logs-policy
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "50gb",
            "max_age": "1d",
            "max_docs": 100000000,
            "max_primary_shard_docs": 200000000
          },
          "set_priority": {
            "priority": 100
          }
        }
      }
    }
  }
}

Rollover koşulları (herhangi biri sağlanırsa rollover tetiklenir):

ParametreAçıklamaÖnerilen
max_primary_shard_sizePrimary shard boyutu50gb
max_ageIndex yaşı1d - 7d
max_docsToplam doküman sayısıUse case'e göre
max_primary_shard_docsPrimary shard başına doküman200M
max_sizeToplam index boyutu (primary + replica)Nadiren kullanılır
min_ageMinimum yaş (rollover'ı engellemek için)Nadiren kullanılır
min_docsMinimum doküman (rollover'ı engellemek için)Nadiren kullanılır
min_primary_shard_sizeMinimum primary shard boyutuNadiren kullanılır
min_primary_shard_docsMin primary shard doküman sayısıNadiren kullanılır
min_sizeMinimum toplam boyutNadiren kullanılır

2.2 WARM Phase

Warm phase, artık yazma yapılmayan ama hâlâ sorgulanan verilerin tutulduğu aşamadır. Daha yavaş ama ucuz donanım kullanılır (SATA SSD veya HDD).

Kullanılabilir Action'lar:

"warm": {
  "min_age": "2d",
  "actions": {
    "shrink": {
      "number_of_shards": 1
    },
    "forcemerge": {
      "max_num_segments": 1
    },
    "allocate": {
      "number_of_replicas": 1,
      "require": {
        "data": "warm"
      }
    },
    "set_priority": {
      "priority": 50
    },
    "readonly": {}
  }
}

Shrink Action — Shard Sayısını Azaltma:

Hot phase'de 5 primary shard ile oluşturulmuş bir index, warm'a geçerken 1 shard'a shrink edilebilir. Bu, kaynak tüketimini dramatik şekilde azaltır.

Shrink kuralları:

  • Hedef shard sayısı, kaynak shard sayısının tam böleni olmalı (5 → 1 veya 5 uygun, 5 → 3 uygun değil)

  • Tüm shard'lar tek bir node'a taşınır, shrink edilir, sonra dağıtılır

  • Index otomatik olarak read-only yapılır

// Shrink ile beraber max_primary_shard_size kullanımı
"shrink": {
  "max_primary_shard_size": "50gb"
}
// Bu durumda ES, toplam veriyi 50GB'lık shard'lara sığacak
// minimum shard sayısına shrink eder

Forcemerge Action — Segment Birleştirme:

Lucene segment'leri birleştirerek arama performansını artırır ve disk alanı kazandırır. Deleted document'lar fiziksel olarak temizlenir.

"forcemerge": {
  "max_num_segments": 1,
  "index_codec": "best_compression"
}

index_codec: best_compression (DEFLATE) kullanmak, varsayılan LZ4'e göre %30-40 daha iyi sıkıştırma sağlar — ama okuma biraz yavaşlar.

2.3 COLD Phase

Cold phase, nadiren sorgulanan veriler için. Minimal kaynak tüketimi hedeflenir.

"cold": {
  "min_age": "30d",
  "actions": {
    "allocate": {
      "number_of_replicas": 0,
      "require": {
        "data": "cold"
      }
    },
    "set_priority": {
      "priority": 0
    },
    "searchable_snapshot": {
      "snapshot_repository": "my-s3-repo",
      "force_merge_index": true
    },
    "readonly": {}
  }
}

Searchable Snapshot (Cold Tier) — Partially Mounted:

Cold tier'da searchable snapshot kullanıldığında, index "partially mounted" olarak çalışır:

  • Veri snapshot repository'de (S3, GCS, Azure Blob) tutulur

  • Sadece sorgulanan kısımlar cache'e çekilir

  • Lokal disk kullanımı minimum — sadece cache

  • İlk sorgu yavaş, cache'lenince hızlanır

// Snapshot repository oluştur (önceden gerekli)
PUT _snapshot/my-s3-repo
{
  "type": "s3",
  "settings": {
    "bucket": "my-elastic-snapshots",
    "region": "eu-west-1",
    "base_path": "cold-tier"
  }
}

2.4 FROZEN Phase

Frozen phase, çok nadiren erişilen arşiv verileri için. Elasticsearch 7.12+ ile geldi.

"frozen": {
  "min_age": "90d",
  "actions": {
    "searchable_snapshot": {
      "snapshot_repository": "my-s3-repo",
      "force_merge_index": true
    }
  }
}

Fully Mounted vs Partially Mounted:

ÖzellikPartially (Cold)Fully (Frozen)
Lokal cacheShard-level cacheMinimal, on-demand
Disk kullanımı~%10-20 orijinal~%1-5 orijinal
Sorgu hızıOrtaYavaş
İlk sorguYavaşÇok yavaş
MaliyetDüşükÇok düşük
RAM kullanımıAzMinimal

💡 İpucu: Frozen tier, "hiç silemeyeceğimiz ama yılda 2-3 kez bakacağımız" veriler için idealdir. Compliance (GDPR, KVKK), yasal zorunluluk verileri buraya koyun.

2.5 DELETE Phase

En basit phase — index'i siler ve biter.

"delete": {
  "min_age": "365d",
  "actions": {
    "wait_for_snapshot": {
      "policy": "daily-snapshots"
    },
    "delete": {
      "delete_searchable_snapshot": true
    }
  }
}

wait_for_snapshot action'ı, silmeden önce bir SLM snapshot'ının alınmasını garanti eder. Production'da kesinlikle kullanın — silinen veri geri gelmez.


3. Tam ILM Policy Örnekleri

3.1 Log Verisi için Kapsamlı ILM Policy

PUT _ilm/policy/production-logs-policy
{
  "policy": {
    "_meta": {
      "description": "Production log verileri için ILM policy",
      "managed_by": "devops-team",
      "version": 3
    },
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "50gb",
            "max_age": "1d"
          },
          "set_priority": {
            "priority": 100
          }
        }
      },
      "warm": {
        "min_age": "2d",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          },
          "forcemerge": {
            "max_num_segments": 1,
            "index_codec": "best_compression"
          },
          "allocate": {
            "number_of_replicas": 1
          },
          "set_priority": {
            "priority": 50
          }
        }
      },
      "cold": {
        "min_age": "14d",
        "actions": {
          "searchable_snapshot": {
            "snapshot_repository": "s3-cold-repo",
            "force_merge_index": true
          },
          "set_priority": {
            "priority": 0
          }
        }
      },
      "frozen": {
        "min_age": "90d",
        "actions": {
          "searchable_snapshot": {
            "snapshot_repository": "s3-frozen-repo"
          }
        }
      },
      "delete": {
        "min_age": "365d",
        "actions": {
          "wait_for_snapshot": {
            "policy": "nightly-backup"
          },
          "delete": {
            "delete_searchable_snapshot": true
          }
        }
      }
    }
  }
}

3.2 Metrik Verisi için ILM Policy (Downsampling ile)

PUT _ilm/policy/metrics-policy
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "25gb",
            "max_age": "1d"
          }
        }
      },
      "warm": {
        "min_age": "3d",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          },
          "forcemerge": {
            "max_num_segments": 1
          },
          "downsample": {
            "fixed_interval": "5m"
          }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "downsample": {
            "fixed_interval": "1h"
          },
          "allocate": {
            "number_of_replicas": 0
          }
        }
      },
      "delete": {
        "min_age": "180d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

ILM Policy'yi Index'e Bağlama

// Index template ile bağlama (önerilen yol)
PUT _index_template/logs-template
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1,
      "index.lifecycle.name": "production-logs-policy",
      "index.lifecycle.rollover_alias": "logs"
    }
  },
  "priority": 200
}

// Mevcut index'e ILM policy bağlama
PUT logs-2024.01/_settings
{
  "index.lifecycle.name": "production-logs-policy"
}

ILM Durumunu İzleme

# Index'in hangi ILM phase'inde olduğunu gör
GET logs-2024.01/_ilm/explain

# Tüm index'lerin ILM durumu
GET */_ilm/explain?only_managed=true&only_errors=true

# ILM policy detayı
GET _ilm/policy/production-logs-policy

# ILM'i manuel tetikleme (test için)
POST _ilm/move/logs-2024.01
{
  "current_step": {
    "phase": "hot",
    "action": "complete",
    "name": "complete"
  },
  "next_step": {
    "phase": "warm",
    "action": "shrink",
    "name": "shrink"
  }
}

4. Data Streams — Zaman Serisi Verisi için Modern Yaklaşım

Data Stream Nedir?

Data stream, zaman serisi verilerini (loglar, metrikler, event'ler) yönetmek için özel bir yapıdır. Arka planda birden fazla "backing index" kullanır, ama dışarıdan tek bir isimle erişirsiniz.

Geleneksel yaklaşımda log indexleme:

logs-2024.01.01
logs-2024.01.02
logs-2024.01.03
...

Her gün yeni index oluştur, alias yönet, rollover elle yap... Karmaşık.

Data stream ile:

logs  ← Tek isim, arkada otomatik yönetilen index'ler
  ├── .ds-logs-2024.01.01-000001  (backing index)
  ├── .ds-logs-2024.01.02-000002  (backing index)
  └── .ds-logs-2024.01.03-000003  (backing index - write index)

Data Stream'in Anatomisi

                    Data Stream: "logs"
                         │
                         ▼
┌─────────────────────────────────────────────┐
│                 Backing Indices              │
│                                             │
│  .ds-logs-000001  (read-only, eski)         │
│  .ds-logs-000002  (read-only, orta)         │
│  .ds-logs-000003  (write index, aktif) ◄──  │
│                                    yazma    │
└─────────────────────────────────────────────┘
  • Write index: En son oluşturulan backing index. Tüm yazma işlemleri buraya gider.

  • Backing indices: Önceki index'ler. Salt okunur.

  • Rollover: ILM policy tetiklediğinde yeni write index oluşturulur.

Data Stream Oluşturma

Data stream oluşturmak için önce bir index template gerekir:

// 1. Component template (opsiyonel ama önerilen)
PUT _component_template/logs-mappings
{
  "template": {
    "mappings": {
      "properties": {
        "@timestamp": {
          "type": "date"
        },
        "message": {
          "type": "text"
        },
        "level": {
          "type": "keyword"
        },
        "service": {
          "type": "keyword"
        },
        "host": {
          "type": "object",
          "properties": {
            "name": { "type": "keyword" },
            "ip": { "type": "ip" }
          }
        }
      }
    }
  }
}

PUT _component_template/logs-settings
{
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1,
      "index.lifecycle.name": "production-logs-policy"
    }
  }
}

// 2. Index template (data_stream aktif)
PUT _index_template/logs-template
{
  "index_patterns": ["logs-*"],
  "data_stream": {},
  "composed_of": ["logs-mappings", "logs-settings"],
  "priority": 500
}

// 3. İlk dokümanı yazarak data stream'i oluştur
POST logs-nginx/_doc
{
  "@timestamp": "2024-01-15T10:30:00Z",
  "message": "GET /api/users 200 15ms",
  "level": "info",
  "service": "nginx"
}

⚠️ Dikkat: Data stream'lerde @timestamp alanı zorunludur. Bu alan olmadan doküman indexlenemez. Ayrıca data stream'e doğrudan PUT ile doküman yazamazsınız — sadece POST (veya _bulk API) kullanılır.

Data Stream API'leri

# Tüm data stream'leri listele
GET _data_stream

# Belirli bir data stream'in detayı
GET _data_stream/logs-nginx

# Çıktı:
# {
#   "data_streams": [{
#     "name": "logs-nginx",
#     "timestamp_field": { "name": "@timestamp" },
#     "indices": [
#       { "index_name": ".ds-logs-nginx-2024.01.15-000001" },
#       { "index_name": ".ds-logs-nginx-2024.01.16-000002" }
#     ],
#     "generation": 2,
#     "status": "GREEN",
#     "template": "logs-template",
#     "ilm_policy": "production-logs-policy",
#     "next_generation_managed_by": "Index Lifecycle Management"
#   }]
# }

# Data stream istatistikleri
GET _data_stream/logs-nginx/_stats

# Manuel rollover
POST logs-nginx/_rollover

# Data stream silme
DELETE _data_stream/logs-nginx

Data Stream'de Güncelleme ve Silme

Data stream'ler append-only (sadece ekleme) tasarımındadır. Ama bazen güncelleme veya silme gerekebilir:

// Update by query
POST logs-nginx/_update_by_query
{
  "query": {
    "term": {
      "level": "debug"
    }
  },
  "script": {
    "source": "ctx._source.level = 'trace'"
  }
}

// Delete by query
POST logs-nginx/_delete_by_query
{
  "query": {
    "range": {
      "@timestamp": {
        "lt": "2024-01-01T00:00:00Z"
      }
    }
  }
}

// Tek doküman silme — backing index adını bilmelisiniz
DELETE .ds-logs-nginx-2024.01.15-000001/_doc/abc123

5. TSDS — Time Series Data Stream

TSDS Nedir?

TSDS (Time Series Data Stream), Elasticsearch 8.5+ ile gelen ve metrik verileri için optimize edilmiş özel bir data stream türüdür. Normal data stream'den farkı:

  • Daha iyi sıkıştırma — Aynı veri %60-80 daha az yer kaplar

  • Dimension routing — Aynı time series'in verileri aynı shard'a yönlendirilir

  • Downsampling desteği — Otomatik özetleme

  • _tsid — Her zaman serisini benzersiz tanımlayan otomatik alan

TSDS Nasıl Çalışır?

TSDS'de her zaman serisi, "dimensions" (boyutlar) ile tanımlanır. Örneğin bir CPU metriği:

Dimensions: { host: "server-1", cpu: "0" }
  → timestamp: 10:00, usage: 45.2
  → timestamp: 10:01, usage: 47.8
  → timestamp: 10:02, usage: 43.1

Dimensions: { host: "server-1", cpu: "1" }
  → timestamp: 10:00, usage: 62.5
  → timestamp: 10:01, usage: 58.3
// TSDS oluşturma
PUT _component_template/metrics-mappings
{
  "template": {
    "mappings": {
      "properties": {
        "@timestamp": {
          "type": "date"
        },
        "host": {
          "type": "keyword",
          "time_series_dimension": true
        },
        "cpu_id": {
          "type": "keyword",
          "time_series_dimension": true
        },
        "cpu_usage": {
          "type": "double",
          "time_series_metric": "gauge"
        },
        "requests_total": {
          "type": "long",
          "time_series_metric": "counter"
        }
      }
    }
  }
}

PUT _index_template/metrics-template
{
  "index_patterns": ["metrics-*"],
  "data_stream": {},
  "composed_of": ["metrics-mappings"],
  "template": {
    "settings": {
      "index.mode": "time_series",
      "index.routing_path": ["host", "cpu_id"],
      "index.look_ahead_time": "30m",
      "index.lifecycle.name": "metrics-policy"
    }
  },
  "priority": 500
}

Metrik Tipleri

TSDS'de her metrik alanı bir tip belirtmelidir:

TipAçıklamaDownsampling Davranışı
gaugeAnlık değer (CPU %, sıcaklık)min, max, sum, value_count hesaplanır
counterMonoton artan sayaç (request sayısı)Son değer korunur
positionCoğrafi konumSon konum korunur

_tsid — Time Series ID

TSDS otomatik olarak her benzersiz dimension kombinasyonu için bir _tsid üretir:

// Bu doküman yazıldığında:
POST metrics-cpu/_doc
{
  "@timestamp": "2024-01-15T10:00:00Z",
  "host": "server-1",
  "cpu_id": "0",
  "cpu_usage": 45.2
}

// ES otomatik olarak _tsid üretir:
// _tsid: hash(host=server-1, cpu_id=0)
// Aynı dimension'larla gelen tüm veriler aynı shard'a yönlendirilir

6. Downsampling — Zaman Serisi Özetleme

Downsampling Nedir?

Downsampling, yüksek çözünürlüklü zaman serisi verilerini daha düşük çözünürlüğe özetler. 10 saniyelik metrik verilerini 1 saatlik özete dönüştürmek gibi.

1 yıllık, 10 saniyelik metrik verisi:

  • Ham: 3.153.600 data point / dimension

  • 5 dakikaya downsample: 105.120 data point (30x küçülme)

  • 1 saate downsample: 8.760 data point (360x küçülme)

Downsampling Nasıl Çalışır?

// Manuel downsampling (TSDS gerektirir)
POST metrics-cpu/_downsample/metrics-cpu-1h
{
  "fixed_interval": "1h"
}

// ILM ile otomatik downsampling
PUT _ilm/policy/metrics-tiered-policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_age": "1d",
            "max_primary_shard_size": "25gb"
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "downsample": {
            "fixed_interval": "5m"
          },
          "forcemerge": {
            "max_num_segments": 1
          }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "downsample": {
            "fixed_interval": "1h"
          }
        }
      },
      "delete": {
        "min_age": "365d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

Downsampled veriye sorgu atarken, Elasticsearch otomatik olarak doğru çözünürlüğü seçer. Yani date_histogram ile interval: 1h sorgularsanız, 1 saatlik downsample'dan okur — orijinal veriye dokunmaz.

💡 İpucu: Downsampling TSDS gerektirir ve sadece time_series_metric olarak işaretlenmiş alanlara uygulanır. Gauge metrikler için min/max/sum/count hesaplanır; counter metrikler için son değer korunur.


7. Data Tiers — Donanım Katmanları

Tier Mimarisi

Data tier'lar, farklı performans ve maliyet özelliklerine sahip node gruplarıdır:

┌─────────────────────────────────────────────────────┐
│  CONTENT TIER                                       │
│  Zaman bazlı olmayan veriler (ürün kataloğu, vb.)   │
│  NVMe SSD, yüksek CPU                              │
├─────────────────────────────────────────────────────┤
│  HOT TIER                                           │
│  Aktif yazma + okuma, en yeni veriler               │
│  NVMe SSD, yüksek CPU, bol RAM                     │
├─────────────────────────────────────────────────────┤
│  WARM TIER                                          │
│  Salt okunur, sık sorgulanan                        │
│  SATA SSD veya hızlı HDD, orta CPU                 │
├─────────────────────────────────────────────────────┤
│  COLD TIER                                          │
│  Nadiren sorgulanan, searchable snapshot            │
│  HDD + object storage cache, düşük CPU              │
├─────────────────────────────────────────────────────┤
│  FROZEN TIER                                        │
│  Arşiv, çok nadiren erişilen                        │
│  Minimal lokal disk, object storage, minimal CPU    │
└─────────────────────────────────────────────────────┘

Node'lara Tier Rolü Atama

# elasticsearch.yml — Hot node
node.roles: [ data_hot, ingest ]

# elasticsearch.yml — Warm node
node.roles: [ data_warm ]

# elasticsearch.yml — Cold node
node.roles: [ data_cold ]

# elasticsearch.yml — Frozen node
node.roles: [ data_frozen ]

# elasticsearch.yml — Content node (non-time-series data)
node.roles: [ data_content ]

# elasticsearch.yml — Birden fazla rol
node.roles: [ data_hot, data_content, ingest ]

Tier Preference (Tercih Sırası)

Elasticsearch, index'leri tier'lara yerleştirirken bir tercih sırası izler. Eğer hedef tier mevcut değilse, bir sonraki tier'a düşer:

Hot index  → hot → content → (allocation hatası)
Warm index → warm → hot → content → (allocation hatası)
Cold index → cold → warm → hot → content → (allocation hatası)
Frozen index → frozen → cold → warm → hot → content → (allocation hatası)

Bu davranışı _tier_preference ile kontrol edebilirsiniz:

// Index'in tier preference'ını değiştir
PUT my-index/_settings
{
  "index.routing.allocation.include._tier_preference": "data_warm,data_hot"
}

// Tier preference'ı gör
GET my-index/_settings?filter_path=*.settings.index.routing.allocation.include._tier_preference

Donanım Önerileri (Tier Bazında)

TierCPURAMDiskRAM:Disk
HotYüksek (16-64 core)64-128 GBNVMe SSD, 4-8 TB1:30
WarmOrta (8-16 core)32-64 GBSATA SSD / HDD, 8-16 TB1:100
ColdDüşük (4-8 core)16-32 GBHDD + S3 cache, 16-32 TB1:500
FrozenMinimal (2-4 core)8-16 GBMinimal SSD (cache), S31:∞
ContentUse case'e göre32-64 GBNVMe SSD, 2-4 TB1:30

8. Yaygın Hatalar ve Best Practices

❌ Yapma

  1. Her phase'i kullanma zorunluluğu yok — Sadece hot + delete bile yeterli olabilir

  2. Çok agresif rollovermax_age: 1h gibi ayarlar binlerce micro-index oluşturur

  3. Downsampling'i TSDS olmadan kullanma — Çalışmaz

  4. Data stream'e PUT ile yazma — Sadece POST ve _bulk desteklenir

  5. `@timestamp` alanını unutma — Data stream'de zorunlu

✅ Yap

  1. Component template kullan — Mapping ve settings'i ayrı tut, yeniden kullanılabilir yap

  2. `_meta` alanı ekle — Policy'nin amacını, versiyonunu, sahibini belirt

  3. `wait_for_snapshot` kullan — Delete phase'den önce snapshot alındığından emin ol

  4. `set_priority` kullan — Hot: 100, warm: 50, cold: 0 — recovery sıralaması önemli

  5. Test ortamında poll_interval'ı kıs — 10m beklemek yerine 30s yap


Özet

Bu derste öğrendiklerimizi toplayalım:

  1. ILM, index'lerin yaşam döngüsünü 5 phase'de yönetir: Hot → Warm → Cold → Frozen → Delete. Her phase'in özel action'ları var — rollover, shrink, forcemerge, searchable_snapshot, downsample, delete.

  2. Data Streams, zaman serisi verileri için modern çözüm. Backing index'ler otomatik yönetilir, rollover otomatik olur, @timestamp zorunludur.

  3. TSDS (Time Series Data Stream), metrik verileri için optimize edilmiş data stream. Dimensions + metrics modeli, _tsid ile otomatik routing, %60-80 daha iyi sıkıştırma sağlar.

  4. Downsampling, yüksek çözünürlüklü metrikleri özetler. 10 saniyelik veriyi 1 saatlik özete dönüştürerek 360x disk tasarrufu sağlanır.

  5. Data Tiers (hot/warm/cold/frozen/content), farklı performans-maliyet dengesinde donanım katmanlarıdır. Node'lara node.roles ile tier atanır.

  6. Production'da ILM + Data Stream birlikte kullanın. Component template → Index template → Data stream → ILM policy zinciri, modern Elasticsearch'ün temel veri yönetim mimarisidir.