← Kursa Dön
📄 Text · 35 min

Backup ve Restore — Snapshot/Restore, SLM

Giriş — Snapshot/Restore ile Verilerinizi Koruyun

Diyelim ki fotoğraflarını yalnızca telefonunda tutuyorsun. Bir gün telefon suya düşüyor — tüm anılar gitti. Ama buluta yedekleme açıksan? Yeni telefona geçer, her şeyi geri yüklersin. Elasticsearch'te snapshot/restore tam olarak bu iş: verilerini güvenli bir yere kopyala, ihtiyaç olduğunda geri yükle.

Production'da Elasticsearch çalıştırıyorsanız backup olmadan çalışmak, emniyet kemeri takmadan araba sürmek gibidir — kaza olana kadar sorun yok, ama kaza olduğunda çok geç. Bir yanlış DELETE komutu, bir disk arızası, bir yazılım hatası — backup yoksa veri kaybı kaçınılmaz.

Bu derste snapshot repository tiplerini, snapshot oluşturma/restore sürecini, incremental snapshot mantığını, partial restore, Snapshot Lifecycle Management (SLM) ve cross-cluster restore konularını ele alacağız.


1. Snapshot/Restore Temelleri

Snapshot Nedir?

Snapshot, belirli bir andaki index'lerinizin (veya tüm cluster'ınızın) durumunun bir kopyasıdır. Dosya sistemi seviyesinde bir kopya değil — Elasticsearch'ün kendi formatında, segment bazlı bir yedektir.

Önemli özellikler:

  • Incremental: İlk snapshot tam kopya alır. Sonrakiler sadece değişen segment'leri yedekler. Bu sayede ikinci snapshot, birincisinin 1/10'u kadar sürebilir.

  • Non-blocking: Snapshot alırken cluster çalışmaya devam eder — okuma/yazma durmuyor.

  • Consistent: Snapshot başladığı andaki veriyi yakalar. Snapshot sürerken eklenen yeni veriler dahil edilmez.

  • Sıkıştırılmış: Veriler compress edilir, depolama alanından tasarruf sağlar.

Repository Nedir?

Repository, snapshot'ların saklandığı yerdir. Snapshot almadan önce mutlaka bir repository tanımlamanız gerekir. Elasticsearch'ün kendisi veri saklamaz — sadece repository'e yazar ve oradan okur.

Bunu şöyle düşün: snapshot bir fotoğraf, repository ise fotoğraf albümü. Fotoğrafı çekebilirsin ama bir albüme koymazsan kaybolur.


2. Repository Tipleri

2.1 Shared File System (fs)

En basit tip — tüm node'ların erişebildiği bir dosya yolu:

# elasticsearch.yml — Tüm node'larda aynı olmalı
path.repo: ["/mnt/backups/elasticsearch"]
// Repository oluştur
PUT _snapshot/my_fs_backup
{
  "type": "fs",
  "settings": {
    "location": "/mnt/backups/elasticsearch/my_fs_backup",
    "compress": true,
    "max_snapshot_bytes_per_sec": "40mb",
    "max_restore_bytes_per_sec": "40mb"
  }
}

⚠️ Dikkat: path.repo ayarı elasticsearch.yml dosyasında tanımlanmalı ve cluster restart gerektirir. Paylaşılan dosya sistemi (NFS, CIFS) tüm data ve master node'lardan erişilebilir olmalıdır.

Ne zaman kullanılır? Küçük-orta cluster'lar, on-premise kurulumlar, NFS mount'lu ortamlar.

2.2 Amazon S3

Production'da en popüler seçenek. S3 plugin'i gerekir:

# Plugin kurulumu (tüm node'larda)
bin/elasticsearch-plugin install repository-s3

# AWS credential'ları keystore'a ekle
bin/elasticsearch-keystore add s3.client.default.access_key
bin/elasticsearch-keystore add s3.client.default.secret_key
// S3 repository oluştur
PUT _snapshot/s3_backup
{
  "type": "s3",
  "settings": {
    "bucket": "my-company-es-backups",
    "region": "eu-west-1",
    "base_path": "production/snapshots",
    "compress": true,
    "server_side_encryption": true,
    "storage_class": "standard_ia",
    "max_snapshot_bytes_per_sec": "100mb",
    "max_restore_bytes_per_sec": "100mb"
  }
}

S3 Storage Class stratejisi:

Storage ClassMaliyetKullanım
standardYüksekSık erişilen backup'lar (son 7 gün)
standard_iaOrtaAylık backup'lar
intelligent_tieringDeğişkenErişim bilinmiyorsa
glacierDüşükUzun süreli saklama (compliance)

💡 İpucu: S3 Lifecycle Policy ile eski snapshot'ları otomatik olarak glacier'a taşıyabilirsiniz. Elasticsearch'ün SLM'i eski snapshot'ları siler, ama silmek yerine arşivlemek istiyorsanız S3 tarafında yapın.

2.3 Google Cloud Storage (GCS)

# Plugin kurulumu
bin/elasticsearch-plugin install repository-gcs

# Service account key'i ayarla
bin/elasticsearch-keystore add-file gcs.client.default.credentials_file \
  /path/to/service-account.json
PUT _snapshot/gcs_backup
{
  "type": "gcs",
  "settings": {
    "bucket": "my-company-es-backups",
    "base_path": "production/snapshots",
    "compress": true
  }
}

2.4 Azure Blob Storage ve HDFS

Azure ve HDFS de benzer pattern'da çalışır — plugin kur, credential ekle, repository tanımla:

# Azure
bin/elasticsearch-plugin install repository-azure
bin/elasticsearch-keystore add azure.client.default.account
bin/elasticsearch-keystore add azure.client.default.key

# HDFS
bin/elasticsearch-plugin install repository-hdfs

Repository Karşılaştırma Tablosu

TipHızMaliyetDayanıklılıkKurulum
fs (NFS)⚡⚡⚡DüşükOrtaKolay
S3⚡⚡OrtaÇok yüksekOrta
GCS⚡⚡OrtaÇok yüksekOrta
Azure⚡⚡OrtaÇok yüksekOrta
HDFS⚡⚡⚡DüşükYüksekZor

Repository Doğrulama

// Repository'nin düzgün çalışıp çalışmadığını doğrula
POST _snapshot/s3_backup/_verify

// Tüm repository'leri listele
GET _snapshot/_all

// Belirli repository bilgisi
GET _snapshot/s3_backup

3. Snapshot Oluşturma

Tam Cluster Snapshot

// Tüm index'leri ve cluster state'i yedekle
PUT _snapshot/s3_backup/snapshot_2024_01_15
{
  "indices": "*",
  "ignore_unavailable": true,
  "include_global_state": true
}

Belirli Index'leri Yedekleme

// Sadece belirli index'leri yedekle
PUT _snapshot/s3_backup/daily_logs_2024_01_15
{
  "indices": "logs-2024.01.*,metrics-2024.01.*",
  "ignore_unavailable": true,
  "include_global_state": false,
  "metadata": {
    "taken_by": "backup-cron",
    "reason": "Daily backup",
    "environment": "production"
  }
}

Parametreler

ParametreVarsayılanAçıklama
indices*Hangi index'ler yedeklenecek (pattern destekler)
ignore_unavailablefalseEksik index'leri atla
include_global_statetrueCluster settings, templates, ILM policies
partialfalseTüm shard'ları olmayan index'leri de dahil et
metadata-Snapshot'a özel metadata (etiketleme)

Incremental Snapshot — Nasıl Çalışır?

İlk snapshot tüm segment'leri kopyalar. Sonraki snapshot'lar sadece yeni veya değişen segment'leri yazar:

Snapshot 1 (İlk):     [Seg-A] [Seg-B] [Seg-C]           → 10 GB
                        ↓ (7 gün sonra, merge + yeni veri)
Snapshot 2:            [Seg-A] [Seg-B] [Seg-D] [Seg-E]   → 3 GB (sadece D ve E yeni)
                        ↓
Snapshot 3:            [Seg-A] [Seg-F] [Seg-G]            → 2 GB (F ve G yeni)

Snapshot 1'i silerseniz, Seg-C silinir ama Seg-A ve Seg-B (Snapshot 2'de de kullanılıyor) silinmez. Elasticsearch hangi segment'in hangi snapshot'ta kullanıldığını takip eder.

💡 İpucu: Bu yüzden günlük snapshot almak ucuzdur — veri değişim oranına bağlı olarak ilk snapshot'un %5-15'i kadar ek alan kullanır.


4. Snapshot İzleme

Snapshot Progress

// Devam eden snapshot'un durumunu gör
GET _snapshot/s3_backup/snapshot_2024_01_15/_status
// → state: IN_PROGRESS, stats.processed vs stats.total ile ilerleme
// → indices.<name>.shards_stats ile shard bazlı durum

Snapshot Listeleme ve İptal

// Tamamlanan snapshot detayı
GET _snapshot/s3_backup/snapshot_2024_01_15

// Tüm snapshot'ları listele
GET _snapshot/s3_backup/_all

// Devam eden veya tamamlanan snapshot'u sil/iptal et
DELETE _snapshot/s3_backup/snapshot_2024_01_15

5. Restore — Geri Yükleme

Tam Restore

// Tüm index'leri geri yükle
POST _snapshot/s3_backup/snapshot_2024_01_15/_restore
{
  "indices": "*",
  "ignore_unavailable": true,
  "include_global_state": true
}

⚠️ Dikkat: Restore, hedef index'in kapalı olmasını veya mevcut olmamasını gerektirir. Açık bir index'e restore yapamazsınız.

Belirli Index'leri Restore Etme

// Sadece belirli index'leri geri yükle
POST _snapshot/s3_backup/snapshot_2024_01_15/_restore
{
  "indices": "logs-2024.01.15",
  "ignore_unavailable": true,
  "include_global_state": false
}

Farklı İsimle Restore (Rename)

Mevcut index'i bozmadan test amaçlı restore yapmak isterseniz:

POST _snapshot/s3_backup/snapshot_2024_01_15/_restore
{
  "indices": "logs-2024.01.15",
  "ignore_unavailable": true,
  "include_global_state": false,
  "rename_pattern": "(.+)",
  "rename_replacement": "restored_$1",
  "index_settings": {
    "index.number_of_replicas": 0
  }
}

Bu komut logs-2024.01.15 index'ini restored_logs-2024.01.15 olarak geri yükler. Regex pattern kullanarak isimlendirme yapabilirsiniz.

Partial Restore — Belirli Shard'ları Geri Yükleme

Büyük index'lerde sadece ihtiyacınız olan kısımları geri yükleyebilirsiniz:

POST _snapshot/s3_backup/snapshot_2024_01_15/_restore
{
  "indices": "logs-2024.01.15",
  "ignore_unavailable": true,
  "partial": true,
  "index_settings": {
    "index.number_of_replicas": 0,
    "index.routing.allocation.require._tier_preference": null
  }
}

partial: true ile bazı shard'ları olmayan (incomplete) snapshot'lardan bile geri yükleme yapabilirsiniz.

Restore Sırasında Index Ayarlarını Değiştirme

POST _snapshot/s3_backup/snapshot_2024_01_15/_restore
{
  "indices": "logs-*",
  "ignore_unavailable": true,
  "index_settings": {
    "index.number_of_replicas": 1,
    "index.refresh_interval": "30s",
    "index.routing.allocation.require._tier_preference": "data_warm"
  },
  "ignore_index_settings": [
    "index.routing.allocation.require._tier_preference"
  ]
}

ignore_index_settings ile orijinal snapshot'taki bazı ayarları görmezden gelebilirsiniz — özellikle tier preference gibi hedef cluster'da geçerli olmayabilecek ayarlar için kullanışlıdır.

Restore İzleme

// Restore progress
GET _cat/recovery/logs-2024.01.15?v&h=index,shard,type,stage,files_percent,bytes_percent

// Çıktı:
index              shard type     stage   files_percent bytes_percent
logs-2024.01.15    0     SNAPSHOT done    100.0%        100.0%
logs-2024.01.15    1     SNAPSHOT index   65.3%         45.2%
logs-2024.01.15    2     SNAPSHOT index   30.1%         22.8%

6. Snapshot Lifecycle Management (SLM)

SLM Nedir?

Manuel snapshot almak unutulur, hata yapılır, gece 3'te kalkıp çalıştırmak istemezsin. SLM, snapshot'ları otomatik olarak oluşturur ve eski olanları siler.

Bunu bir çamaşır makinesi gibi düşün: zamanlayıcıyı ayarla, deterjanı koy, gerisini makine halleder.

SLM Policy Oluşturma

// Günlük backup policy
PUT _slm/policy/daily_backup
{
  "schedule": "0 30 2 * * ?",
  "name": "<daily-snap-{now/d}>",
  "repository": "s3_backup",
  "config": {
    "indices": ["*"],
    "ignore_unavailable": true,
    "include_global_state": true
  },
  "retention": {
    "expire_after": "30d",
    "min_count": 7,
    "max_count": 60
  }
}

Schedule formatı (Cron): saniye dakika saat gün ay haftanın_günü

ÖrnekAnlam
0 30 2 * * ?Her gün saat 02:30
0 0 */6 * * ?Her 6 saatte bir
0 0 3 * * 1Her Pazartesi saat 03:00
0 0 0 1 * ?Her ayın 1'i gece yarısı

Snapshot İsimlendirme

<daily-snap-{now/d}> gibi date math kullanabilirsiniz:

PatternSonuç
{now/d}2024.01.15
{now/M}2024.01
{now/d{yyyy-MM-dd}}2024-01-15

Retention Policy Detayları

"retention": {
  "expire_after": "30d",    // 30 günden eski snapshot'ları sil
  "min_count": 7,           // En az 7 snapshot tut (expire_after'dan öncelikli)
  "max_count": 60           // En fazla 60 snapshot tut
}

Kurallar:

  • min_count her zaman expire_after'dan önceliklidir — 30 günlük olsa bile min_count'un altına düşmez

  • max_count her zaman geçerlidir — min_count'tan fazla olsa bile max_count'un üstüne çıkmaz

  • Retention, SLM tarafından periyodik olarak çalıştırılır (varsayılan: günde 1 kez)

Farklı Index Grupları İçin Ayrı Policy'ler

// Kritik veriler — sık yedekle, uzun tut
PUT _slm/policy/critical_hourly
{
  "schedule": "0 0 * * * ?",
  "name": "<critical-{now/d{yyyy.MM.dd-HH}}>",
  "repository": "s3_backup",
  "config": {
    "indices": ["orders-*", "users-*", "payments-*"],
    "ignore_unavailable": true,
    "include_global_state": false
  },
  "retention": {
    "expire_after": "90d",
    "min_count": 24,
    "max_count": 2160
  }
}

// Log verileri — günlük yedekle, kısa tut
PUT _slm/policy/logs_daily
{
  "schedule": "0 0 3 * * ?",
  "name": "<logs-{now/d}>",
  "repository": "s3_backup",
  "config": {
    "indices": ["logs-*", "filebeat-*"],
    "ignore_unavailable": true,
    "include_global_state": false
  },
  "retention": {
    "expire_after": "14d",
    "min_count": 5,
    "max_count": 30
  }
}

SLM Yönetimi

// Tüm policy'leri listele
GET _slm/policy

// Belirli policy detayı
GET _slm/policy/daily_backup

// Policy'yi hemen çalıştır (test için)
POST _slm/policy/daily_backup/_execute

// Retention'ı hemen çalıştır
POST _slm/_execute_retention

// SLM istatistikleri
GET _slm/stats

// Policy sil
DELETE _slm/policy/daily_backup

SLM Status Kontrol

GET _slm/policy/daily_backup

// Yanıt:
{
  "daily_backup": {
    "version": 1,
    "modified_date_millis": 1705286400000,
    "policy": { "..." },
    "last_success": {
      "snapshot_name": "daily-snap-2024.01.15",
      "time_string": "2024-01-15T02:30:15.000Z"
    },
    "last_failure": null,
    "next_execution_millis": 1705372200000,
    "stats": {
      "snapshots_taken": 45,
      "snapshots_failed": 0,
      "snapshots_deleted": 15,
      "snapshot_deletion_failures": 0
    }
  }
}

7. Cross-Cluster Restore

Senaryo: Disaster Recovery

Production cluster'ınız çöktü. Yeni bir cluster kuruyorsunuz ve eski backup'lardan geri yüklemeniz gerekiyor.

Adım Adım Cross-Cluster Restore

Adım 1: Yeni cluster'da aynı repository'yi tanımla

// Yeni cluster'da — AYNI S3 bucket'ını göster
PUT _snapshot/s3_backup
{
  "type": "s3",
  "settings": {
    "bucket": "my-company-es-backups",
    "region": "eu-west-1",
    "base_path": "production/snapshots",
    "readonly": true
  }
}

⚠️ Dikkat: Yeni cluster'ın yanlışlıkla eski snapshot'ları bozmaması için readonly: true kullanın.

Adım 2: Mevcut snapshot'ları kontrol et

GET _snapshot/s3_backup/_all?verbose=false

Adım 3: İstediğiniz snapshot'u restore edin

POST _snapshot/s3_backup/snapshot_2024_01_15/_restore
{
  "indices": "*",
  "ignore_unavailable": true,
  "include_global_state": true,
  "index_settings": {
    "index.number_of_replicas": 0
  }
}

💡 İpucu: Restore sırasında number_of_replicas: 0 yapın — önce tüm primary shard'ları geri yükleyin, sonra replica'ları artırın. Bu restore süresini dramatik şekilde kısaltır.

Adım 4: Restore tamamlandıktan sonra replica'ları ayarla

PUT */_settings
{
  "index": {
    "number_of_replicas": 1
  }
}

Versiyon Uyumluluğu

Snapshot'ları farklı versiyonlara restore edebilir misiniz?

KaynakHedefDurum
7.x7.x✅ Desteklenir
7.x8.x✅ Desteklenir
8.x8.x✅ Desteklenir
8.x7.x❌ Desteklenmez
6.x8.x❌ Desteklenmez (7.x ara adım gerek)

Genel kural: Snapshot'lar sadece bir major versiyon ileri restore edilebilir.


8. Java ile Snapshot/Restore

Snapshot Oluşturma

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.snapshot.*;

public class SnapshotManager {

    private final ElasticsearchClient client;

    public SnapshotManager(ElasticsearchClient client) {
        this.client = client;
    }

    // Repository oluştur
    public void createRepository(String repoName, String bucket) throws Exception {
        client.snapshot().createRepository(r -> r
            .name(repoName)
            .type("s3")
            .settings(s -> s
                .bucket(bucket)
                .compress(true)
            )
        );
        System.out.println("Repository oluşturuldu: " + repoName);
    }

    // Snapshot al
    public void createSnapshot(String repo, String snapshotName,
                               String... indices) throws Exception {
        CreateSnapshotResponse response = client.snapshot().create(c -> c
            .repository(repo)
            .snapshot(snapshotName)
            .indices(java.util.Arrays.asList(indices))
            .ignoreUnavailable(true)
            .includeGlobalState(false)
            .waitForCompletion(true)
        );

        System.out.printf("Snapshot: %s, Durum: %s, Shard: %d/%d%n",
            snapshotName,
            response.snapshot().state(),
            response.snapshot().shards().successful(),
            response.snapshot().shards().total()
        );
    }

    // Snapshot durumunu kontrol et
    public void checkStatus(String repo, String snapshotName) throws Exception {
        GetSnapshotResponse response = client.snapshot().get(g -> g
            .repository(repo)
            .snapshot(snapshotName)
        );

        response.snapshots().forEach(snap -> {
            System.out.printf("Snapshot: %s | Durum: %s | Başlangıç: %s%n",
                snap.snapshot(), snap.state(), snap.startTime());
        });
    }
}

Restore İşlemi

public class RestoreManager {

    private final ElasticsearchClient client;

    public RestoreManager(ElasticsearchClient client) {
        this.client = client;
    }

    public void restoreIndex(String repo, String snapshotName,
                             String indexName) throws Exception {
        // Önce mevcut index'i kapat (varsa)
        try {
            client.indices().close(c -> c.index(indexName));
            System.out.println("Index kapatıldı: " + indexName);
        } catch (Exception e) {
            System.out.println("Index mevcut değil, devam ediliyor...");
        }

        // Restore et
        RestoreResponse response = client.snapshot().restore(r -> r
            .repository(repo)
            .snapshot(snapshotName)
            .indices(indexName)
            .ignoreUnavailable(true)
            .includeGlobalState(false)
            .indexSettings(s -> s
                .numberOfReplicas("0")
            )
        );

        System.out.printf("Restore başladı. Shard: %d/%d%n",
            response.snapshot().shards().successful(),
            response.snapshot().shards().total()
        );
    }

    // Farklı isimle restore
    public void restoreWithRename(String repo, String snapshotName,
                                   String indexName) throws Exception {
        client.snapshot().restore(r -> r
            .repository(repo)
            .snapshot(snapshotName)
            .indices(indexName)
            .renamePattern("(.+)")
            .renameReplacement("restored_$1")
            .includeGlobalState(false)
        );

        System.out.println("Restored as: restored_" + indexName);
    }
}

9. Best Practices

✅ Yap

KonuÖneri
Otomatik backupSLM ile otomatik, zamanlanmış snapshot'lar
Retention policyEski snapshot'ları otomatik sil — disk dolmasın
Farklı lokasyonRepository, cluster'dan farklı fiziksel lokasyonda olsun
S3/GCS/AzureProduction'da object storage kullan — dayanıklı ve ucuz
Restore testiAyda bir backup'tan restore testi yap — backup çalışıyor mu emin ol
Replica = 0 restoreRestore sırasında replica 0, sonra artır
MonitoringSLM policy başarısızlıklarını izle, alert kur
Cross-clusterDR senaryosu için farklı region'daki cluster'dan erişim test et

❌ Yapma

KonuNeden
Manuel snapshotİnsan unutur, SLM kullan
Tek repositoryTek noktadan arıza — farklı storage'lara yedekle
Retention'sız SLMDisk/S3 dolup taşar
Local disk repoDisk arızasında hem veri hem backup gider
Restore test etmemek"Backup var" güveni yanlış olabilir — test et
include_global_state: true her zamanSadece tam cluster restore için gerek, index restore'da false yap

10. Yaygın Hatalar ve Çözümleri

Hata 1: "Repository verification failed"

// Sorun: Node'lar repository'ye erişemiyor
POST _snapshot/s3_backup/_verify

// Çözüm: Tüm node'larda plugin yüklü mü?
// AWS credential'lar doğru mu?
// Network erişimi var mı? (Security Group, IAM)

Hata 2: "Snapshot contains indices that already exist"

// Sorun: Restore etmeye çalıştığınız index zaten açık
// Çözüm 1: Index'i kapat
POST logs-2024.01.15/_close

// Çözüm 2: Index'i sil (dikkatli!)
DELETE logs-2024.01.15

// Çözüm 3: Farklı isimle restore et
POST _snapshot/s3_backup/snap1/_restore
{
  "indices": "logs-2024.01.15",
  "rename_pattern": "(.+)",
  "rename_replacement": "restored_$1"
}

Hata 3: "Concurrent snapshot operations not allowed"

// Sorun: Aynı anda birden fazla snapshot işlemi
// Elasticsearch aynı repository'de paralel snapshot desteklemez

// Çözüm: Devam eden snapshot'u bekle veya iptal et
GET _snapshot/s3_backup/_current
DELETE _snapshot/s3_backup/stuck_snapshot

Hata 4: "Repository is read-only"

// Sorun: readonly: true ayarlı repository'ye snapshot almaya çalışıyorsunuz
// Bu, cross-cluster restore için kasıtlı olabilir

// Çözüm: Yazma izni gereken repository'de readonly: false olmalı
PUT _snapshot/s3_backup
{
  "type": "s3",
  "settings": {
    "bucket": "my-company-es-backups",
    "readonly": false
  }
}

11. Gerçek Dünya Senaryosu — Tam Backup Stratejisi

Bir e-commerce şirketi için kapsamlı backup planı:

┌──────────────────────────────────────────────────────────┐
│                    BACKUP STRATEJİSİ                     │
├────────────────┬─────────────────────────────────────────┤
│ Kritik Veriler │ orders-*, users-*, payments-*           │
│ SLM Policy     │ Her saat, 90 gün retention             │
│ Repository     │ S3 (eu-west-1) + S3 (us-east-1) cross  │
├────────────────┼─────────────────────────────────────────┤
│ Operasyonel    │ products-*, inventory-*, search-logs-*  │
│ SLM Policy     │ Her 6 saat, 30 gün retention           │
│ Repository     │ S3 (eu-west-1)                         │
├────────────────┼─────────────────────────────────────────┤
│ Log Verileri   │ logs-*, filebeat-*, metricbeat-*        │
│ SLM Policy     │ Günlük, 14 gün retention               │
│ Repository     │ S3 Standard-IA                          │
├────────────────┼─────────────────────────────────────────┤
│ Compliance     │ audit-*, financial-*                    │
│ SLM Policy     │ Haftalık, 7 yıl retention              │
│ Repository     │ S3 Glacier                              │
└────────────────┴─────────────────────────────────────────┘

Bu stratejiyi SLM policy'lerine çevirelim:

// 1. Kritik veriler — saatlik
PUT _slm/policy/critical_hourly
{
  "schedule": "0 0 * * * ?",
  "name": "<critical-{now/d{yyyy.MM.dd-HH}}>",
  "repository": "s3_primary",
  "config": {
    "indices": ["orders-*", "users-*", "payments-*"],
    "ignore_unavailable": true,
    "include_global_state": false
  },
  "retention": {
    "expire_after": "90d",
    "min_count": 24,
    "max_count": 2200
  }
}

// 2. Operasyonel veriler — 6 saatlik
PUT _slm/policy/operational_6h
{
  "schedule": "0 0 */6 * * ?",
  "name": "<operational-{now/d{yyyy.MM.dd-HH}}>",
  "repository": "s3_primary",
  "config": {
    "indices": ["products-*", "inventory-*", "search-logs-*"],
    "ignore_unavailable": true,
    "include_global_state": false
  },
  "retention": {
    "expire_after": "30d",
    "min_count": 4,
    "max_count": 120
  }
}

// 3. Log verileri — günlük
PUT _slm/policy/logs_daily
{
  "schedule": "0 30 2 * * ?",
  "name": "<logs-{now/d}>",
  "repository": "s3_logs",
  "config": {
    "indices": ["logs-*", "filebeat-*", "metricbeat-*"],
    "ignore_unavailable": true,
    "include_global_state": false
  },
  "retention": {
    "expire_after": "14d",
    "min_count": 5,
    "max_count": 30
  }
}

// 4. Compliance — haftalık, uzun saklama
PUT _slm/policy/compliance_weekly
{
  "schedule": "0 0 1 ? * 1",
  "name": "<compliance-{now/d{yyyy.MM.dd}}>",
  "repository": "s3_archive",
  "config": {
    "indices": ["audit-*", "financial-*"],
    "ignore_unavailable": true,
    "include_global_state": false
  },
  "retention": {
    "expire_after": "2555d",
    "min_count": 52,
    "max_count": 520
  }
}

💡 İpucu: Ayda bir DR (Disaster Recovery) testi yapın — son snapshot'u farklı bir cluster'da restore edip veri sayısını doğrulayın. "Backup var" güveni, test edilmedikçe yanıltıcıdır.


Özet

  1. Snapshot Elasticsearch'ün resmi backup mekanizmasıdır — incremental, non-blocking ve segment bazlı çalışır. İlk snapshot sonrasındaki yedekler çok daha hızlı ve küçüktür.

  2. Repository tipleri arasında fs (NFS), S3, GCS, Azure ve HDFS bulunur — production için object storage (S3/GCS/Azure) önerilir çünkü dayanıklıdır ve cluster'dan bağımsızdır.

  3. SLM (Snapshot Lifecycle Management) ile snapshot'ları otomatik zamanla ve retention policy ile eski olanları otomatik sil — manuel backup güvenilmezdir.

  4. Restore sırasında rename_pattern ile farklı isimle geri yükleyebilir, index_settings ile replica sayısını değiştirebilirsiniz — replica=0 ile başlayıp sonra artırmak restore süresini kısaltır.

  5. Cross-cluster restore için aynı repository'yi farklı cluster'da readonly: true olarak tanımlayın — disaster recovery senaryolarında hayat kurtarır.

  6. Searchable snapshots ile eski veriyi restore etmeden arayabilirsiniz — frozen tier'da maliyet optimizasyonu sağlar. Ayda bir DR testi yaparak backup'larınızın gerçekten çalıştığını doğrulayın.