Kasım 7 2025

Elasticsearch ILM ile Disk Tasarrufu: Hot-Warm-Cold-Delete Yapılandırması

DevOps dünyasının en acı verici maliyet kalemlerinden biri, her gün çığ gibi büyüyen log verileridir. Elasticsearch üzerinde koşan log kümelerinin kontrolsüz büyümesi, disk doluluk alarmları ve şişen bulut faturalarıyla sonuçlanır. İşte tam bu noktada, akıllı bir elasticsearch ilm (Index Lifecycle Management) stratejisi kurmak, disk ve donanım maliyetlerinizi kalıcı olarak optimize etmenin en efektif yoludur. Sadece eski verileri silmek bir çözüm değildir; verinin yaşlandıkça daha ucuz kaynaklara taşınması, sıkıştırılması ve segmentlerinin birleştirilmesi gerekir. Bu rehberde, production ortamında doğrudan uygulayabileceğiniz, shrink ve force-merge adımlarıyla desteklenmiş agresif bir hot-warm-cold-delete mimarisini nasıl kuracağınızı inceleyeceğiz.

1. Altyapının Hazırlanması: Node Rollerinin Dağıtımı

ILM mekanizmasının veriyi doğru katmanlar arasında taşıyabilmesi için öncelikle Elasticsearch cluster üyelerinin rollerini net bir şekilde tanımlamalıyız. Eski node.attr.box_type yaklaşımı yerine, modern Elasticsearch mimarisinde (7.x/8.x) yerleşik veri rollerini kullanıyoruz. Node’larınızın elasticsearch.yml dosyalarında şu tanımlamaların yapıldığından emin olun:

Hot Node Konfigürasyonu (Yüksek IOPS NVMe Diskler)

node.roles: [ master, data_hot, ingest ]

Warm Node Konfigürasyonu (Orta Segment SSD / Standart Diskler)

node.roles: [ data_warm ]

Cold Node Konfigürasyonu (Ucuz, Yüksek Kapasiteli HDD / Object Storage)

node.roles: [ data_cold ]

Neden böyle? Yazma (ingest) yükü her zaman CPU ve I/O canavarıdır. Hot node’ları pahalı ve hızlı disklerde tutarken, artık arama sıklığı düşmüş eski verileri barındıran warm ve cold node’larda daha ucuz depolama birimleri kullanarak maliyetleri ciddi oranda dengeliyoruz.

2. Agresif Bir ILM Policy Tanımlama

Şimdi disk tasarrufunu asıl optimize edecek olan ILM policy yapısını kuralım. Senaryomuzda:

  • Hot Fazı: Veri yazılır. Primary shard boyutu 50 GB’a ulaştığında veya 7 gün geçtiğinde rollover tetiklenir.
  • Warm Fazı: Rollover olan veri warm node’lara taşınır. Shard sayısı 1’e düşürülür (shrink) ve segment birleştirmesi (force-merge) yapılarak diskte maksimum sıkıştırma sağlanır.
  • Cold Fazı: Veri cold node’lara taşınır, replica sayısı 0 veya 1’e çekilerek alan kazanılır.
  • Delete Fazı: 90 günün ardından veri cluster’dan tamamen silinir.

Bu akışı tetikleyecek API çağrısını aşağıdaki gibi cluster’a uygulayalım:

curl -X PUT "localhost:9200/_ilm/policy/log_maliyeti_opt_policy" -H 'Content-Type: application/json' -d'
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "50gb",
            "max_age": "7d"
          },
          "set_priority": {
            "priority": 100
          }
        }
      },
      "warm": {
        "min_age": "0ms",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          },
          "forcemerge": {
            "max_num_segments": 1
          },
          "allocate": {
            "number_of_replicas": 1
          },
          "set_priority": {
            "priority": 50
          }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "allocate": {
            "number_of_replicas": 0
          },
          "set_priority": {
            "priority": 0
          }
        }
      },
      "delete": {
        "min_age": "90d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}'

3. Neden Shrink ve Force Merge?

Burada “Neden böyle yaptık?” sorusunu yanıtlayalım. Birçok DevOps mühendisi sadece rollover ve delete adımlarını kullanır. Ancak asıl disk tasarrufu warm fazındaki iki kritik adımda gizlidir:

  1. Shrink: Hot fazda yazma performansını optimize etmek için muhtemelen 5 primary shard kullandınız. Veri salt okunur (read-only) olduğunda, bu kadar çok shard’a ihtiyacınız kalmaz. Shard sayısını 1’e düşürerek hem Elasticsearch JVM Heap bellek tüketimini azaltırız hem de metadata overhead’ini sıfırlarız.
  2. Force Merge (max_num_segments: 1): Elasticsearch arkada verileri sürekli segmentler halinde yazar. Silinen veya güncellenen dökümanlar fiziksel olarak hemen silinmez, sadece silindi olarak işaretlenir. Force merge operasyonu ile tüm segmentleri tek bir segmente indirgeriz. Bu işlem, silinmiş tüm verileri diskten fiziksel olarak kazır ve sıkıştırma algoritmasının (LZ4/DEFLATE) maksimum verimle çalışmasını sağlayarak ortalama %20 ila %40 arasında anlık disk tasarrufu sağlar.

4. Index Template ve Bootstrap Oluşturma

ILM politikasının otomatik olarak yeni index’lere uygulanabilmesi için bir index template tanımlamamız gerekiyor. Burada önemli olan nokta, verilerin yazılacağı ilk “bootstrap” index’ini elle oluşturup alias’ı bağlamaktır.

Index Template Tanımlanması

curl -X PUT "localhost:9200/_index_template/log_template" -H 'Content-Type: application/json' -d'
{
  "index_patterns": ["app-logs-*"],
  "template": {
    "settings": {
      "index.lifecycle.name": "log_maliyeti_opt_policy",
      "index.lifecycle.rollover_alias": "app-logs",
      "index.number_of_shards": 3,
      "index.number_of_replicas": 1,
      "index.routing.allocation.include._tier_preference": "data_hot"
    }
  }
}'

Burada index.routing.allocation.include._tier_preference: "data_hot" satırı çok kritiktir. Yeni oluşturulan tüm index’lerin öncelikli olarak hot node’lara yazılmasını garanti altına alır.

İlk Bootstrap Index’inin Tetiklenmesi

Rollover mekanizmasının çalışabilmesi için alias’ın işaret ettiği fiziksel bir index’in bulunması şarttır. İlk index’i write_index olarak tanımlayarak döngüyü başlatıyoruz:

curl -X PUT "localhost:9200/%3Capp-logs-%7Bnow%2Fd%7D-000001%3E" -H 'Content-Type: application/json' -d'
{
  "aliases": {
    "app-logs": {
      "is_write_index": true
    }
  }
}'

Artık uygulamanız logları doğrudan app-logs alias’ına yazabilir. Elasticsearch, arka planda ILM kurallarını işleterek index boyutlarını izleyecek ve eşikler aşıldığında rollover yaparak süreci warm katmanına devredecektir.

5. SRE Gözünden Production Sorunları ve Çözümler

Production ortamlarında bu yapıyı koştururken karşınıza çıkabilecek bazı tipik tıkanma noktaları ve bunları aşma yöntemleri şunlardır:

Shrink Operasyonunun Askıda Kalması

Bir index’in shrink edilebilmesi için, o index’e ait tüm primary shard kopyalarının cluster içinde tek bir node üzerine toplanması gerekir. Eğer cluster’ınızda disk doluluğu nedeniyle allocation engelleri varsa, shrink işlemi AWAITING_REALLOCATION durumunda takılır.

Çözüm: Warm node’larınızda tek bir node’un index’in tamamını (örneğin 150 GB) tek başına barındırabilecek kadar boş disk alanına sahip olduğundan emin olun. Gerekirse geçici olarak disk limit sınırlarını (watermark) esnetin:

curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
  "transient": {
    "cluster.routing.allocation.disk.watermark.low": "90%",
    "cluster.routing.allocation.disk.watermark.high": "95%"
  }
}'

Force Merge Sırasında IOPS Tavan Yapması

Force merge işlemi, diski yoğun şekilde okuyup yazan (I/O intensive) ağır bir operasyondur. Aynı anda onlarca index warm faza geçip force merge olmaya başlarsa cluster yanıt veremez hale gelebilir.

Çözüm: ILM policy’nizdeki rollover tetikleyicilerini zamansal olarak yaymaya çalışın (örneğin tüm servislerin rollover’ını aynı gece saatinde tetiklemeyin, boyut bazlı rollover tercih edin) ve force merge limitlerini sınırlandırın.

Özet

Bu makalede kurguladığımız hot-warm-cold-delete yapısı sayesinde, aktif yazılan taze log verilerinizi yüksek performanslı disklerde tutarken, geriye dönük analizler için sakladığınız eski verileri minimum kaynak tüketecek şekilde optimize ettik. Shrink ile heap bellek ayak izini düşürdük, force-merge ile diskteki boşlukları temizledik ve soğuk katmanda replikaları azaltarak donanım maliyetlerimizi kalıcı olarak aşağı çektik. Bu kurgu, doğru uygulandığında Elasticsearch log altyapınızın sürdürülebilirliğini katbekat artıracaktır.

Category: Genel | LEAVE A COMMENT
Ağustos 30 2024

Elasticsearch ILM (Index Lifecycle Management) ile Disk Tasarrufu

Her devops mühendisinin kabusudur: Gece yarısı gelen ve uykuyu piç eden o meşhur “Disk Space Low” uyarısı. Hele ki bu uyarı, log analizi için canla başla koşturduğumuz, saniyede on binlerce satır log yutan bir elasticsearch cluster’ından geliyorsa durum daha da can sıkıcı olur. Sürekli büyüyen log yığınlarını yönetmek, sadece daha fazla ve daha pahalı disk satın almakla çözülmez; akıllıca bir ilm (Index Lifecycle Management) stratejisi kurmak gerekir. Bu yazımızda, bütçe dostu ve yüksek performanslı hot-warm-cold-delete mimarisini nasıl kuracağımızı, shrink ve rollover operasyonlarının perde arkasını pratik örneklerle inceleyeceğiz.

Neden Sadece “Daha Büyük Disk” Çözüm Değil?

Kapasite sorunuyla karşılaştığımızda ilk refleks genellikle disk boyutunu artırmak veya cluster’a yeni node’lar eklemek olur. Ancak bu yaklaşım sürdürülebilir değildir. Neden mi?

  • Maliyet: Üretim ortamlarında hızlı yazma (indexing) performansı için NVMe SSD diskler kullanırız. 90 günlük log verisinin tamamını bu pahalı disklerde tutmak bütçeyi sarsar.
  • Performans: Eski ve nadiren sorgulanan loglar, aktif olarak yazılan güncel index’ler ile aynı kaynakları (özellikle heap memory) tüketerek sorgu performansını düşürür.
  • Yönetilebilirlik: Tek bir devasa index yerine, yönetilebilir boyutlarda shard’lara bölünmüş bir yapı hem yedekleme (snapshot) hem de cluster kurtarma süreçlerinde hayat kurtarır.

Hot-Warm-Cold-Delete Mimarisi Nedir?

Verinin yaşlandıkça değerini kaybetmesi felsefesine dayanan bu mimari, veriyi yaşam döngüsüne göre farklı donanım özelliklerine sahip node gruplarına dağıtır:

  • Hot Phase (Sıcak Evre): Yeni logların yazıldığı, yoğun CPU ve NVMe SSD disklere sahip node’lardır. Veri tazedir ve sürekli sorgulanır.
  • Warm Phase (Ilık Evre): Veri artık yazılmaz (read-only), ancak sorgulanmaya devam eder. Daha ucuz SATA SSD diskler barındıran node’lara taşınır. Burada shard sayısı azaltılarak (shrink) sistem üzerindeki yük hafifletilir.
  • Cold Phase (Soğuk Evre): Nadiren sorgulanan, arşiv niteliğindeki verilerdir. HDD tipi ucuz depolama birimlerinde saklanır. Arama performansı düşüktür ama maliyeti minimumdur.
  • Delete Phase (Silme Evresi): Belirlenen saklama süresi (retention period) dolan verilerin güvenli bir şekilde yok edildiği evredir.

Adım Adım Elasticsearch ILM Kurulumu

Gelin, teoriyi pratiğe dökelim. Senaryomuzda günlük uygulama loglarımızı toplayacağız, bunları 50 GB veya 30 gün sınırlamasıyla yeni index’lere böleceğiz (rollover), ardından shrink işlemiyle shard sayısını azaltıp daha ucuz disklere taşıyacağız ve 90 günün sonunda sileceğiz.

1. Node Rollerinin Tanımlanması

Öncelikle Elasticsearch cluster’ınızdaki node’ların hangi katmanda yer alacağını elasticsearch.yml dosyalarında belirtmeniz gerekir. Modern Elasticsearch versiyonlarında (7.10+) veri katmanları (data tiers) kullanılır:

# Hot Node konfigürasyonu
node.roles: [ master, data_content, data_hot ]

# Warm Node konfigürasyonu
node.roles: [ data_warm ]

# Cold Node konfigürasyonu
node.roles: [ data_cold ]

2. ILM Policy Tanımlama

Şimdi Elasticsearch API’sini kullanarak ILM politikamızı tanımlayalım. Bu politikada hot, warm, cold ve delete fazlarındaki geçiş kurallarını ve yapılacak operasyonları belirtiyoruz.

PUT _ilm/policy/kertenkerem_log_policy
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "50gb",
            "max_age": "30d"
          }
        }
      },
      "warm": {
        "min_age": "0d",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          },
          "forcemerge": {
            "max_num_segments": 1
          },
          "allocate": {
            "number_of_replicas": 1
          }
        }
      },
      "cold": {
        "min_age": "60d",
        "actions": {
          "readonly": {}
        }
      },
      "delete": {
        "min_age": "90d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

Buradaki “Neden?” Sorularını Cevaplayalım:

  • Neden max_primary_shard_size? Toplam index boyutu yerine tek bir primary shard boyutunu baz almak en doğru yaklaşımdır. Replica shard’lar hesaba katılmaz ve dengeli bir shard yapısı korunur.
  • Neden warm fazında shrink ve forcemerge yapıyoruz? Yazma işlemi bittiği için artık çoklu shard yapısına ihtiyacımız yok. Shard sayısını 1’e düşürerek (shrink) overhead’i azaltıyoruz. forcemerge ile segment sayısını 1’e indirip disk alanından ciddi tasarruf sağlıyor ve arama hızını optimize ediyoruz.

3. Index Template Oluşturma

Oluşturduğumuz ILM politikasının yeni açılacak log index’lerine otomatik olarak uygulanması için bir index template tanımlıyoruz. Burada dikkat etmemiz gereken en önemli nokta index.lifecycle.rollover_alias tanımıdır.

PUT _index_template/kertenkerem_logs_template
{
  "index_patterns": ["kertenkerem-app-logs-*"],
  "template": {
    "settings": {
      "index.lifecycle.name": "kertenkerem_log_policy",
      "index.lifecycle.rollover_alias": "kertenkerem-app-logs",
      "number_of_shards": 3,
      "number_of_replicas": 1
    }
  }
}

4. İlk Index’in Tetiklenmesi (Bootstrap)

Rollover mekanizmasının doğru çalışabilmesi için ilk index’i bizim manuel olarak oluşturmamız ve yazma iznini (write index) vermemiz gerekir. Index isminin sonunun sıralı bir sayı formatında (örn: -000001) bitmesi şarttır.

PUT kertenkerem-app-logs-000001
{
  "aliases": {
    "kertenkerem-app-logs": {
      "is_write_index": true
    }
  }
}

Bu adımdan sonra log toplayıcı araçlarınızın (Logstash, Fluentd, Vector vb.) doğrudan spesifik index ismine değil, sadece kertenkerem-app-logs alias’ına (takma ad) veri göndermesi gerekir. Elasticsearch, arka planda ILM kurallarına göre yeni index’ler açarak trafiği otomatik yönlendirecektir.

Shrink ve Rollover Operasyonlarının Kritik Detayları

Sistem tıkır tıkır çalışırken bazen arka planda işler karışabilir. DevOps mühendislerinin bu süreçte bilmesi gereken bazı “under the hood” detaylar şunlardır:

Shrink İşlemi Nasıl Gerçekleşir?

Bir index’i shrink edebilmek için Elasticsearch öncelikle o index’e ait tüm primary shard’ları cluster’daki tek bir node üzerinde toplamak zorundadır. ILM bunu otomatik olarak yönetir. Ancak o node üzerinde yeterli disk alanı yoksa shrink işlemi askıda (blocking) kalabilir. Bu yüzden warm node’larınızın disk kapasitesini planlarken bu geçici yoğunlaşmayı hesaba katmalısınız.

Neden Günlük Index (Daily Index) Yerine Rollover?

Eski usul logstash-YYYY.MM.DD yapısında, hafta sonu az log gelen günlerde de, hafta içi devasa log gelen günlerde de aynı sayıda index açılırdı. Bu durum cluster içinde “over-sharding” (aşırı shard birikmesi) sorununa yol açar ve master node’un canını okurdu. Rollover ise boyuta göre tetiklendiği için her shard’ın ideal boyut olan 30-50 GB aralığında kalmasını garanti eder.

Sonuç ve “DevOps Tavsiyeleri”

Bu makalede kurduğumuz ILM yapısı sayesinde, pahalı SSD disklerimizi sadece aktif olarak yazılan taze veriler için rezerve etmiş olduk. Yaşlanan logları daha ucuz disklere taşıyarak, shrink operasyonuyla cluster üzerindeki shard yükünü hafifleterek ve nihayetinde eski verileri silerek disk maliyetlerinde %60’a varan tasarruf sağlayabilirsiniz.

Unutmayın, iyi bir DevOps mühendisi sadece çalışan sistemler kurmaz; aynı zamanda şirketin bulut faturasını da optimize eden kişidir. Loglarınızı kendi haline bırakmayın, ILM ile onları disipline edin!

Category: Genel | LEAVE A COMMENT