Elasticsearch Index Yönetimi ve Lifecycle Policy Yapılandırması

Prodüksiyonda bir gün sabah 07:30’da telefonun çalması ve “Elasticsearch disk doldu, loglar gelmiyor” mesajını almak… Kim yaşadıysa bilir. O panik anında index’lerin nasıl yönetilmesi gerektiğini, lifecycle policy’nin neden hayat kurtardığını çok iyi anlarsınız. Bu yazıda tam olarak o noktadan başlayıp, Elasticsearch index yönetimini ve ILM (Index Lifecycle Management) konusunu gerçek dünyadan örneklerle ele alacağım.

Elasticsearch Index Yönetimi Neden Bu Kadar Kritik?

Elasticsearch’ü sadece “log atılan yer” olarak kullanıyorsanız, er ya da geç sorunlarla karşılaşırsınız. Çünkü Elasticsearch disk bazlı çalışır ve index’ler büyüdükçe hem arama performansı düşer hem de disk alanı tükenir. Özellikle Filebeat, Logstash veya Fluentd gibi araçlarla sürekli akan log verisi söz konusu olduğunda, index yönetimi proaktif bir sorumluluk haline gelir.

Temel sorun şu: Varsayılan kurulumda Elasticsearch, index’leri sonsuza kadar saklar. Siz bir şey yapmazsanız, 6 ay önce yazılmış nginx logları hâlâ orada durur. Bunların büyük çoğunluğuna bir daha bakmazsınız, ama disk alanı yerler, segment merge işlemleri yavaşlar, cluster health bozulur.

Index yaşam döngüsünü doğru kurmak için önce şu kavramları netleştirmek lazım.

Index Lifecycle Management (ILM) Temelleri

ILM, Elasticsearch 6.6 ile hayatımıza girdi ve 7.x ile birlikte çok daha olgunlaştı. Temel fikir basit: Bir index oluşturulduğu andan silindiği ana kadar belirli aşamalardan geçer ve siz bu aşamaları kurallarla tanımlarsınız.

Dört temel aşama vardır:

  • Hot: Aktif olarak yazma ve okuma yapılan aşama. Index’e veriler bu aşamada akar.
  • Warm: Yazma durmuştur, okuma hâlâ aktiftir. Genellikle optimize edilmiş (force merge) haldedir.
  • Cold: Nadiren sorgulanan veriler bu aşamadadır. Daha az kaynak tüketir, arama yavaş olabilir.
  • Delete: Index silinir.

Bunun yanı sıra Elasticsearch 7.14+ ile birlikte Frozen aşaması da geldi, ama onu ayrı bir konuda ele almak daha doğru olur.

Önce mevcut cluster’ınızdaki index durumuna bir bakın:

# Tüm index'leri boyut ve durum bilgisiyle listele
curl -X GET "localhost:9200/_cat/indices?v&s=store.size:desc&h=index,status,health,pri,rep,docs.count,store.size"

Bu komut size hangi index’in ne kadar yer kapladığını gösterir. Çoğu zaman eski tarihli index’lerin toplam alanın yüzde seksenini yediğini görürsünüz.

ILM Policy Oluşturmak

Şimdi gerçek bir senaryo üzerinden gidelim. Diyelim ki bir e-ticaret platformunun access loglarını yönetiyorsunuz. Loglar günlük ortalama 5 GB, 30 günlük hot tutmak istiyorsunuz, 60 güne kadar warm’da kalsın, 90. günde silinsin.

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

Buradaki rollover aksiyonu kritik. Index ya 1 günlük yaşa ulaştığında ya da 5 GB boyutu aştığında yeni bir index’e geçiyor. Bu sayede tek bir devasa index yerine, yönetilebilir parçalar elde ediyorsunuz.

Index Template ve ILM Bağlantısı

Policy’yi oluşturdunuz, ama bunu yeni oluşturulan index’lere otomatik uygulamak için bir index template’e ihtiyacınız var.

curl -X PUT "localhost:9200/_index_template/eticaret-log-template" 
  -H "Content-Type: application/json" 
  -d '{
    "index_patterns": ["eticaret-logs-*"],
    "template": {
      "settings": {
        "number_of_shards": 2,
        "number_of_replicas": 1,
        "index.lifecycle.name": "eticaret-log-policy",
        "index.lifecycle.rollover_alias": "eticaret-logs"
      },
      "mappings": {
        "properties": {
          "@timestamp": {
            "type": "date"
          },
          "status_code": {
            "type": "integer"
          },
          "request_path": {
            "type": "keyword"
          },
          "response_time_ms": {
            "type": "float"
          }
        }
      }
    }
  }'

Template’i oluşturduktan sonra ilk index’i ve alias’ı manuel olarak başlatmanız gerekiyor:

# İlk index'i oluştur ve alias'ı tanımla
curl -X PUT "localhost:9200/eticaret-logs-000001" 
  -H "Content-Type: application/json" 
  -d '{
    "aliases": {
      "eticaret-logs": {
        "is_write_index": true
      }
    }
  }'

Artık loglarınızı eticaret-logs alias’ına yazabilirsiniz. Rollover tetiklendiğinde Elasticsearch otomatik olarak eticaret-logs-000002‘yi oluşturur ve yazma alias’ını oraya taşır.

Mevcut Index’leri Policy’ye Dahil Etmek

Peki ya daha önce oluşturulmuş, yüzlerce index’i olan bir cluster’a policy uygulamak istiyorsanız? Bu durum çok daha yaygın. Şirketin Elasticsearch’ü yıllardır çalışıyor ama hiçbir lifecycle policy yok, disk dolmak üzere.

# Belirli bir pattern'e uyan index'lere toplu settings güncelleme
curl -X PUT "localhost:9200/eticaret-logs-2023*/_settings" 
  -H "Content-Type: application/json" 
  -d '{
    "index": {
      "lifecycle.name": "eticaret-log-policy"
    }
  }'

Dikkat: Mevcut index’lere policy uyguladığınızda, index’in min_age hesaplaması index oluşturma tarihinden itibaren başlar. Yani 2023 başından kalma bir index’iniz varsa ve policy 90 günde sil diyorsa, o index zaten silinebilir durumda demektir. Bunu mutlaka gözden geçirin.

ILM Durumunu İzlemek ve Sorun Gidermek

Prodüksiyonda en sık karşılaştığım sorunlardan biri ILM’in beklenmedik bir noktada takılı kalmasıdır. Rollover alias yanlış tanımlanmış, shard allocation rule uyuşmuyor ya da node resource’ları yetersiz.

# Belirli bir index'in ILM durumunu detaylı incele
curl -X GET "localhost:9200/eticaret-logs-000015/_ilm/explain" | python3 -m json.tool

Bu komutun çıktısında step, phase, action ve varsa failed_step alanlarına bakın. Eğer bir adım başarısız olduysa genellikle şöyle bir mesaj görürsünüz:

"failed_step": "check-rollover-ready",
"is_auto_retryable_error": true,
"step_info": {
  "message": "index.lifecycle.rollover_alias [eticaret-logs] does not point to index [eticaret-logs-000015]"
}

Bu hata alias’ın yanlış index’e işaret ettiği anlamına gelir. Düzeltmek için:

# Alias'ı doğru index'e yönlendir
curl -X POST "localhost:9200/_aliases" 
  -H "Content-Type: application/json" 
  -d '{
    "actions": [
      {
        "add": {
          "index": "eticaret-logs-000015",
          "alias": "eticaret-logs",
          "is_write_index": true
        }
      }
    ]
  }'

# Sonrasında ILM'i retry et
curl -X POST "localhost:9200/eticaret-logs-000015/_ilm/retry"

Curator ile Ek Index Yönetimi

ILM harika bir araç, ama bazı senaryolarda daha esnek bir şeye ihtiyaç duyarsınız. Özellikle kompleks silme kuralları, snapshot alma ve geri yükleme akışları için Elasticsearch Curator hâlâ değerlidir.

Curator’ı ayarlamak için önce bir config dosyası oluşturun:

# /etc/curator/curator.yml
cat > /etc/curator/curator.yml << 'EOF'
client:
  hosts:
    - localhost
  port: 9200
  use_ssl: false
  ssl_no_validate: false
  timeout: 30
  master_only: false

logging:
  loglevel: INFO
  logfile: /var/log/curator/curator.log
  logformat: default
EOF

Şimdi 90 günden eski index’leri silen bir action dosyası oluşturun:

cat > /etc/curator/delete_old_indices.yml << 'EOF'
actions:
  1:
    action: delete_indices
    description: "90 gunden eski eticaret loglarini sil"
    options:
      ignore_empty_list: True
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
      - filtertype: pattern
        kind: prefix
        value: eticaret-logs-
      - filtertype: age
        source: creation_date
        direction: older
        unit: days
        unit_count: 90
  2:
    action: forcemerge
    description: "30-60 gunlik index'leri optimize et"
    options:
      max_num_segments: 1
      delay: 120
      timeout_override: 21600
      continue_if_exception: False
      disable_action: False
    filters:
      - filtertype: pattern
        kind: prefix
        value: eticaret-logs-
      - filtertype: age
        source: creation_date
        direction: older
        unit: days
        unit_count: 30
      - filtertype: age
        source: creation_date
        direction: younger
        unit: days
        unit_count: 60
EOF

Bu action’ı crontab ile çalıştırın:

# Her gece 02:00'de çalıştır
echo "0 2 * * * curator --config /etc/curator/curator.yml /etc/curator/delete_old_indices.yml >> /var/log/curator/cron.log 2>&1" | crontab -

Snapshot ile Silmeden Önce Yedekleme

Prodüksiyonda “sil” demeden önce bir dakika durun. Log verisi olsa bile, compliance ya da audit gereklilikleri nedeniyle uzun süre saklama zorunluluğunuz olabilir. Bu durumda ILM’e snapshot aksiyonu eklemek çok daha akıllıca bir çözümdür.

Önce bir snapshot repository tanımlayın:

# Shared filesystem repository tanımla
curl -X PUT "localhost:9200/_snapshot/log_archive" 
  -H "Content-Type: application/json" 
  -d '{
    "type": "fs",
    "settings": {
      "location": "/mnt/elasticsearch-snapshots/logs",
      "compress": true,
      "chunk_size": "1gb"
    }
  }'

ILM policy’ye cold aşaması ve snapshot aksiyonu ekleyin:

curl -X PUT "localhost:9200/_ilm/policy/eticaret-log-policy-v2" 
  -H "Content-Type: application/json" 
  -d '{
    "policy": {
      "phases": {
        "hot": {
          "min_age": "0ms",
          "actions": {
            "rollover": {
              "max_age": "1d",
              "max_size": "5gb"
            }
          }
        },
        "warm": {
          "min_age": "30d",
          "actions": {
            "forcemerge": {
              "max_num_segments": 1
            },
            "allocate": {
              "require": {
                "data": "warm"
              }
            }
          }
        },
        "cold": {
          "min_age": "60d",
          "actions": {
            "searchable_snapshot": {
              "snapshot_repository": "log_archive"
            }
          }
        },
        "delete": {
          "min_age": "365d",
          "actions": {
            "wait_for_snapshot": {
              "policy": "daily_snapshots"
            },
            "delete": {
              "delete_searchable_snapshot": false
            }
          }
        }
      }
    }
  }'

Bu yapıyla 60-365 gün arası veriler snapshot olarak saklanır, Elasticsearch’ün aktif veri alanından çıkar ama gerektiğinde restore edilebilir. 1 yıl sonra index Elasticsearch’ten siliniyor, ama snapshot’lar storage’da kalmaya devam ediyor.

Disk Watermark ve Index Yönetimi İlişkisi

ILM her şeyi otomatik yönetiyor diye düşünüp rahat olmayın. Disk dolduğunda Elasticsearch index’leri read-only moda alır. Bu noktada ILM bile çalışmaz hale gelebilir çünkü ILM bazı aksiyonları gerçekleştirmek için yazma erişimine ihtiyaç duyar.

Watermark değerlerini izlemek ve uyarmak için şu kontrolü otomatize edin:

#!/bin/bash
# /usr/local/bin/es_disk_check.sh

ES_HOST="localhost:9200"
WARN_THRESHOLD=75
CRIT_THRESHOLD=85

check_disk_usage() {
  curl -s "http://${ES_HOST}/_cat/allocation?v&h=node,disk.percent" | 
  awk 'NR>1 {
    gsub(/%/, "", $2)
    if ($2 > '"$CRIT_THRESHOLD"') {
      print "KRITIK: " $1 " node disk kullanimi " $2 "% - ILM islemleri etkilenebilir"
    } else if ($2 > '"$WARN_THRESHOLD"') {
      print "UYARI: " $1 " node disk kullanimi " $2 "%"
    }
  }'
}

result=$(check_disk_usage)
if [ -n "$result" ]; then
  echo "$result"
  # Buraya email veya Slack notification kodu ekleyin
  # mail -s "Elasticsearch Disk Uyarisi" [email protected] <<< "$result"
fi

Aynı zamanda read-only moda geçmiş index’leri tespit edip düzeltmek için:

# Read-only index'leri listele
curl -s "http://localhost:9200/_cat/indices?v&h=index,status" | 
  grep -v "^index" | awk '{print $1}' | 
  xargs -I{} curl -s "http://localhost:9200/{}/_settings" | 
  python3 -c "
import json, sys
data = json.load(sys.stdin)
for idx, settings in data.items():
    blocks = settings.get('settings', {}).get('index', {}).get('blocks', {})
    if blocks.get('read_only_allow_delete') == 'true':
        print(f'Read-only index: {idx}')
"

Read-only’den çıkarmak için disk temizlendikten sonra:

curl -X PUT "localhost:9200/eticaret-logs-*/_settings" 
  -H "Content-Type: application/json" 
  -d '{"index.blocks.read_only_allow_delete": null}'

Data Tier Mimarisi ile Maliyet Optimizasyonu

Eğer çok node’lu bir cluster yönetiyorsanız, hot-warm-cold mimarisi hem performansı hem de maliyeti optimize etmenin en etkili yoludur. SSD diskli güçlü node’larınızı hot tier için, daha ucuz ve büyük diskli node’larınızı warm/cold tier için kullanabilirsiniz.

Node’lara tier rolü atamak için elasticsearch.yml dosyasını düzenleyin:

# Hot node için /etc/elasticsearch/elasticsearch.yml
node.roles: [ data_hot, master ]

# Warm node için
node.roles: [ data_warm ]

# Cold node için
node.roles: [ data_cold ]

Node’ları yeniden başlattıktan sonra ILM policy’nizdeki allocate aksiyonu otomatik olarak index’leri doğru tier’a taşıyacaktır.

Gerçek Hayat: Kapasite Planlama Hesabı

ILM kurup bırakmak yeterli değil. Sisteminizin ne kadar veri üreteceğini tahmin edip disk kapasitesini planlamak gerekiyor.

# Son 7 günün günlük index boyutunu hesapla
curl -s "localhost:9200/_cat/indices/eticaret-logs-*?v&h=index,creation.date.string,store.size,pri.store.size" | 
  sort -k2 | tail -7 | 
  awk '{print $1, $3}'

Bu çıktıdan ortalama günlük veri büyümesini hesaplayabilirsiniz. Warm aşamasında forcemerge sonrası verinin yaklaşık yüzde yirmi-otuz küçüldüğünü, cold’da searchable snapshot ile yüzde seksen-doksan küçüldüğünü varsayarak total disk ihtiyacını tahmin edin.

Sonuç

Elasticsearch index yönetimi, ELK Stack’in en çok ihmal edilen ama en kritik konularından biridir. Doğru bir ILM policy, uygun snapshot stratejisi ve disk monitoring ile birleştiğinde, hem disk krizi yaşamazsınız hem de cluster sağlığını korursunuz.

Özetle yapmanız gerekenler:

  • ILM policy’sini başlangıçtan kurun: Sonradan kurmak hem zahmetli hem de riskli.
  • Rollover kullanın: Büyük tek index yerine yönetilebilir parçalar çok daha iyidir.
  • Snapshot almayı ihmal etmeyin: Özellikle delete’den önce snapshot alın.
  • Disk watermark’larını izleyin: Read-only moda geçmeden önce haberdar olun.
  • Hot-warm-cold mimarisi: Büyük cluster’larda ciddi maliyet tasarrufu sağlar.
  • ILM durumunu periyodik kontrol edin: Takılı kalan adımlar sessizce sorun biriktirir.

Son olarak şunu söyleyeyim: Bu sistemleri kurup bırakmak değil, düzenli olarak gözden geçirmek lazım. Veri hacmi değişir, retention gereksinimleri değişir, cluster topolojisi değişir. Index yönetimi bir kere yapıp unutulan bir iş değil, sürekli bakım gerektiren bir operasyonel sorumluluktur.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir