kertenkerem_
· DevOps · 4 dk okuma

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

DevOps tarafındaki en acı maliyet kalemlerinden biri, her gün çığ gibi büyüyen log verileridir. Elasticsearch üzerinde koşan log kümeleri kontrolsüz büyüyünce disk doluluk alarmları ve şişen bulut faturaları kaçınılmaz olur. Akıllı bir ILM (Index Lifecycle Management) stratejisi kurmak, disk ve donanım maliyetlerini kalıcı olarak düşürmenin en etkili yoludur. Yalnızca eski verileri silmek çözüm değildir. Veri yaşlandıkça daha ucuz kaynaklara taşınmalı, sıkıştırılmalı ve segmentleri birleştirilmelidir. Bu yazıda 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ı anlatıyorum.

1. Altyapının hazırlanması: node rollerinin dağıtımı

ILM’in veriyi doğru katmanlar arasında taşıyabilmesi için önce Elasticsearch cluster üyelerinin rollerini net biçimde 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ımları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 tutuyoruz. Arama sıklığı düşmüş eski verileri barındıran warm ve cold node’larda ise daha ucuz depolama kullanarak maliyeti ciddi oranda dengeliyoruz.

2. Agresif bir ILM policy tanımlama

Şimdi disk tasarrufunu asıl sağlayacak ILM policy yapısını kuralım. Senaryomuzda fazlar şöyle:

  • 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), segmentler birleştirilir (force-merge) ve 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ı cluster’a şöyle 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?

Birçok DevOps mühendisi yalnızca rollover ve delete adımlarını kullanır. Oysa asıl disk tasarrufu warm fazdaki iki adımda gizlidir:

  1. Shrink: Hot fazda yazma performansı için muhtemelen 5 primary shard kullandınız. Veri salt okunur (read-only) olduğunda bu kadar shard’a ihtiyacınız kalmaz. Shard sayısını 1’e düşürünce Elasticsearch JVM Heap bellek tüketimi azalır, metadata overhead’i de sıfırlanır.
  2. Force Merge (max_num_segments: 1): Elasticsearch verileri arka planda sürekli segmentler halinde yazar. Silinen veya güncellenen dökümanlar fiziksel olarak hemen silinmez, yalnızca silindi olarak işaretlenir. Force merge ile tüm segmentleri tek bir segmente indiririz. Bu işlem silinmiş verileri diskten fiziksel olarak kazır ve sıkıştırma algoritmasının (LZ4/DEFLATE) en verimli çalışmasını sağlar. Ortalama %20 ila %40 arasında anlık disk tasarrufu getirir.

4. Index template ve bootstrap oluşturma

ILM politikasının yeni index’lere otomatik uygulanabilmesi için bir index template tanımlamamız gerekiyor. Burada önemli 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"
    }
  }
}'

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

İlk bootstrap index’inin tetiklenmesi

Rollover’ın çalışabilmesi için alias’ın işaret ettiği fiziksel bir index bulunmalıdır. İlk index’i write_index olarak tanımlayıp 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şletip index boyutlarını izleyecek, eşikler aşıldığında rollover yaparak süreci warm katmanına devredecek.

5. SRE gözünden production sorunları ve çözümler

Bu yapıyı production ortamlarında koştururken karşınıza çıkabilecek tipik tıkanma noktaları ve çözümleri şunlar:

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 üzerinde toplanması gerekir. 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ı olduğundan emin olun. Gerekirse disk limit sınırlarını (watermark) geçici olarak 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’un tavan yapması

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

Çözüm: ILM policy’nizdeki rollover tetikleyicilerini zamana yaymaya çalışın. Örneğin tüm servislerin rollover’ını aynı gece saatinde tetiklemeyin, boyut bazlı rollover tercih edin. Force merge limitlerini de sınırlandırın.

Özet

Kurguladığımız hot-warm-cold-delete yapısıyla aktif yazılan taze logları yüksek performanslı disklerde tutuyoruz, geriye dönük analizler için sakladığımız eski verileri ise minimum kaynakla işletiyoruz. Shrink heap bellek ayak izini düşürdü, force-merge diskteki boşlukları temizledi, soğuk katmanda replikaları azaltmak da donanım maliyetini kalıcı olarak aşağı çekti. Doğru uygulandığında bu kurgu Elasticsearch log altyapınızın sürdürülebilirliğini katbekat artıracaktır.