GCP Cloud Storage Yaşam Döngüsü Kuralları ile Depolama Yönetimi

Bulut ortamında depolama maliyetleri zamanla kontrolden çıkabiliyor. Özellikle log dosyaları, yedekler ve geçici veriler birikmeye başladığında faturanın sonunda sürprizlerle karşılaşmak kaçınılmaz oluyor. Google Cloud Storage’ın Yaşam Döngüsü Kuralları (Lifecycle Rules) tam da bu noktada devreye giriyor ve nesnelerinizi otomatik olarak yönetmenizi sağlıyor. Bu yazıda GCP Lifecycle Rules’u her açısıyla ele alacağız, gerçek dünya senaryoları üzerinden pratik konfigürasyonları göstereceğiz.

GCP Cloud Storage Yaşam Döngüsü Nedir?

Yaşam döngüsü kuralları, Cloud Storage bucket’larınızdaki nesneler için otomatik eylemler tanımlamanızı sağlar. Bu kurallar sayesinde belirli bir süre geçen dosyaları silebilir, daha ucuz bir depolama sınıfına taşıyabilir ya da eski sürümleri temizleyebilirsiniz.

Kurallar iki temel bileşenden oluşur:

  • Koşul (Condition): Kuralın hangi durumlarda uygulanacağını belirler
  • Eylem (Action): Koşul sağlandığında ne yapılacağını tanımlar

GCP bu kuralları günlük olarak değerlendirir. Yani bir nesne bugün kural koşulunu karşılıyorsa, eylem genellikle 24-48 saat içinde uygulanır. Bu asenkron yapıyı aklınızda bulundurun, kritik silme işlemlerini anlık beklemeyin.

Depolama Sınıfları ve Maliyet Hiyerarşisi

Yaşam döngüsü kurallarını anlamak için önce GCP’nin depolama sınıflarını bilmek gerekiyor:

  • Standard: Sık erişilen veriler için, en pahalı depolama sınıfı
  • Nearline: Ayda bir ya da daha az erişilen veriler için, minimum 30 günlük depolama
  • Coldline: Çeyrek başı ya da daha az erişilen veriler için, minimum 90 günlük depolama
  • Archive: Yılda bir ya da daha az erişilen veriler için, minimum 365 günlük depolama, en ucuz seçenek

Yaşam döngüsü kurallarının asıl amacı nesneleri zamanla daha ucuz sınıflara taşımak ve gereksiz nesneleri silmektir.

Temel Koşul Parametreleri

Kurallar tanımlarken kullanabileceğiniz koşullar şunlardır:

  • age: Nesnenin oluşturulma tarihinden itibaren geçen gün sayısı
  • createdBefore: Belirtilen tarihten önce oluşturulan nesneler
  • customTimeBefore: Nesne üzerinde tanımlı özel zaman damgasına göre filtreleme
  • daysSinceCustomTime: Özel zaman damgasından bu yana geçen gün sayısı
  • daysSinceNonturrentTime: Nesnenin güncel olmayan (noncurrent) hale gelmesinden bu yana geçen gün sayısı
  • isLive: Versiyonlama aktifken canlı mı yoksa eski sürüm mü olduğunu kontrol eder
  • matchesPrefix: Belirtilen prefix ile başlayan nesnelere uygulanır
  • matchesSuffix: Belirtilen suffix ile biten nesnelere uygulanır
  • matchesStorageClass: Belirli bir depolama sınıfındaki nesnelere filtre uygular
  • noncurrentTimeBefore: Belirli bir tarihten önce güncel dışı hale gelen nesneler
  • numNewerVersions: Nesnenin kaç tane daha yeni sürümü olduğunu kontrol eder

Temel Eylem Tipleri

  • Delete: Nesneyi siler
  • SetStorageClass: Nesneyi belirtilen depolama sınıfına taşır
  • AbortIncompleteMultipartUpload: Tamamlanmamış çok parçalı yüklemeleri iptal eder

İlk Konfigürasyon: JSON ile Kural Tanımlama

GCP Lifecycle Rules’u üç farklı şekilde yönetebilirsiniz: Google Cloud Console, gcloud CLI ya da JSON/YAML konfigürasyon dosyaları. Production ortamlarında JSON/YAML tercih edin çünkü bu dosyaları Git’te versiyonlayabilirsiniz.

Önce basit bir senaryo ile başlayalım. 30 günden eski log dosyalarını silmek istiyorsunuz:

cat > lifecycle-logs.json << 'EOF'
{
  "lifecycle": {
    "rule": [
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "age": 30,
          "matchesPrefix": ["logs/"]
        }
      }
    ]
  }
}
EOF

gsutil lifecycle set lifecycle-logs.json gs://your-bucket-name

Mevcut lifecycle kurallarını görüntülemek için:

gsutil lifecycle get gs://your-bucket-name

Gerçek Dünya Senaryosu 1: Log Yönetimi

Bir e-ticaret şirketinde çalıştığınızı düşünün. Uygulama logları, access logları ve error logları her gün yüzlerce GB büyüyor. Compliance gereği error loglarını 1 yıl, access loglarını 90 gün, debug loglarını ise 7 gün saklamamız gerekiyor. İşte bu senaryo için konfigürasyon:

cat > ecommerce-lifecycle.json << 'EOF'
{
  "lifecycle": {
    "rule": [
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "age": 7,
          "matchesPrefix": ["logs/debug/"]
        }
      },
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "NEARLINE"
        },
        "condition": {
          "age": 30,
          "matchesPrefix": ["logs/access/"]
        }
      },
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "age": 90,
          "matchesPrefix": ["logs/access/"]
        }
      },
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "COLDLINE"
        },
        "condition": {
          "age": 30,
          "matchesPrefix": ["logs/error/"]
        }
      },
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "ARCHIVE"
        },
        "condition": {
          "age": 180,
          "matchesPrefix": ["logs/error/"]
        }
      },
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "age": 365,
          "matchesPrefix": ["logs/error/"]
        }
      }
    ]
  }
}
EOF

gsutil lifecycle set ecommerce-lifecycle.json gs://ecommerce-logs-bucket

Bu konfigürasyonda dikkat edilmesi gereken nokta: GCP aynı nesne için birden fazla kural değerlendirdiğinde önce koşulları kontrol eder, sonra uygun eylemi uygular. Silme eylemi her zaman depolama sınıfı değiştirme eyleminden önce gelir, bu yüzden yaş koşullarınızı dikkatli belirleyin.

Versiyonlama ile Birlikte Kullanım

Bucket versiyonlamasını aktif ettiğinizde eski sürümler (noncurrent versions) birikmaya başlar ve beklediğinizden çok daha fazla alan kaplar. Bunu kontrol altına almak kritik önem taşır:

# Önce versiyonlamayı aktif et
gsutil versioning set on gs://your-versioned-bucket

# Eski sürümler için lifecycle kuralı
cat > versioning-lifecycle.json << 'EOF'
{
  "lifecycle": {
    "rule": [
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "NEARLINE"
        },
        "condition": {
          "daysSinceNoncurrentTime": 30,
          "isLive": false
        }
      },
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "numNewerVersions": 3,
          "isLive": false
        }
      },
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "daysSinceNoncurrentTime": 90,
          "isLive": false
        }
      }
    ]
  }
}
EOF

gsutil lifecycle set versioning-lifecycle.json gs://your-versioned-bucket

Bu konfigürasyonla şunu sağlıyoruz: Her nesnenin en fazla 3 eski sürümü tutulsun, 30 günden eski eski sürümler Nearline’a taşınsın ve 90 günden eski eski sürümler tamamen silinsin.

Gerçek Dünya Senaryosu 2: Yedekleme Stratejisi

Bir veritabanı yedekleme senaryosunu ele alalım. Günlük yedekleri 30 gün, haftalık yedekleri 6 ay, aylık yedekleri ise 2 yıl saklamamız gerekiyor:

cat > backup-lifecycle.json << 'EOF'
{
  "lifecycle": {
    "rule": [
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "NEARLINE"
        },
        "condition": {
          "age": 7,
          "matchesPrefix": ["daily/"]
        }
      },
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "age": 30,
          "matchesPrefix": ["daily/"]
        }
      },
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "COLDLINE"
        },
        "condition": {
          "age": 30,
          "matchesPrefix": ["weekly/"]
        }
      },
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "age": 180,
          "matchesPrefix": ["weekly/"]
        }
      },
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "COLDLINE"
        },
        "condition": {
          "age": 90,
          "matchesPrefix": ["monthly/"]
        }
      },
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "ARCHIVE"
        },
        "condition": {
          "age": 365,
          "matchesPrefix": ["monthly/"]
        }
      },
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "age": 730,
          "matchesPrefix": ["monthly/"]
        }
      }
    ]
  }
}
EOF

gsutil lifecycle set backup-lifecycle.json gs://database-backups-bucket

Tamamlanmamış Yüklemeleri Temizlemek

Çok parçalı yüklemeler (multipart uploads) başarısız olduğunda parçalar bucket’ta kalmaya devam eder ve sessiz sedasız para yer. Bu gerçekten sık karşılaşılan bir sorun:

cat > cleanup-lifecycle.json << 'EOF'
{
  "lifecycle": {
    "rule": [
      {
        "action": {
          "type": "AbortIncompleteMultipartUpload"
        },
        "condition": {
          "age": 3
        }
      }
    ]
  }
}
EOF

gsutil lifecycle set cleanup-lifecycle.json gs://your-upload-bucket

Bu kuralı tüm bucket’larınıza uygulamak iyi bir pratik. 3 gün içinde tamamlanmayan yüklemeler zaten başarısız kabul edilmeli.

Terraform ile Infrastructure as Code

Production ortamlarında lifecycle kurallarını Terraform ile yönetmek çok daha sağlıklı. Değişiklikler incelenebilir, geri alınabilir ve CI/CD pipeline’ına entegre edilebilir:

cat > main.tf << 'EOF'
resource "google_storage_bucket" "app_data" {
  name          = "mycompany-app-data"
  location      = "EU"
  force_destroy = false

  versioning {
    enabled = true
  }

  lifecycle_rule {
    action {
      type          = "SetStorageClass"
      storage_class = "NEARLINE"
    }
    condition {
      age                   = 30
      matches_prefix        = ["uploads/"]
      matches_storage_class = ["STANDARD"]
    }
  }

  lifecycle_rule {
    action {
      type          = "SetStorageClass"
      storage_class = "COLDLINE"
    }
    condition {
      age                   = 90
      matches_prefix        = ["uploads/"]
      matches_storage_class = ["NEARLINE"]
    }
  }

  lifecycle_rule {
    action {
      type = "Delete"
    }
    condition {
      age        = 365
      is_live    = false
      num_newer_versions = 2
    }
  }

  lifecycle_rule {
    action {
      type = "AbortIncompleteMultipartUpload"
    }
    condition {
      age = 3
    }
  }
}
EOF

terraform init
terraform plan
terraform apply

Lifecycle Kurallarını Doğrulama ve İzleme

Kuralları uyguladıktan sonra düzgün çalışıp çalışmadığını kontrol etmek isteyeceksiniz:

# Mevcut lifecycle kurallarını kontrol et
gsutil lifecycle get gs://your-bucket-name

# Bucket içindeki nesnelerin storage class'larını listele
gsutil ls -L gs://your-bucket-name/** | grep "Storage class"

# Belirli bir prefix altındaki dosyaları detaylı listele
gsutil ls -l gs://your-bucket-name/logs/

# Bucket boyutunu storage class'a göre kontrol et
gsutil du -s gs://your-bucket-name

# Tüm noncurrent versiyonları listele
gsutil ls -a gs://your-versioned-bucket

Cloud Storage’da lifecycle değişikliklerini izlemek için Cloud Audit Logs’u aktif etmenizi öneririm. Bu sayede hangi nesnelerin ne zaman sınıf değiştirdiğini ya da silindiğini görebilirsiniz.

Sık Yapılan Hatalar ve Çözümleri

Minimum depolama süresi tuzağı: Nearline için minimum 30 gün, Coldline için 90 gün, Archive için 365 gün depolama süresi uygulanır. Standard’dan Nearline’a geçirdiğiniz bir nesneyi 10 gün sonra silerseniz, kalan 20 günün ücretini yine ödersiniz. Bu yüzden yaş koşullarınızı minimum sürelere göre ayarlayın.

Kural sırası yanılgısı: GCP tüm kuralları değerlendirir ve en uygun eylemi seçer. Kurallar birbirini ezmez, her biri bağımsız değerlendirilir. Çakışan kurallardan Delete önceliklidir.

Lifecycle’ın anlık çalışmaması: Kurallar günlük çalışır ve genellikle 24-48 saat içinde etkili olur. Acil temizlik için gsutil rm komutunu kullanın.

Prefix eşleşme hassasiyeti: logs/ prefix’i logs/2024/access.log ile eşleşir ama application-logs/error.log ile eşleşmez. Prefix’lerinizi dikkatli tanımlayın.

Maliyet Optimizasyon Stratejisi

Gerçek bir örnek üzerinden hesaplama yapalım. 100 TB Standard depolama alanınız var ve veriler zamanla şöyle bir dağılıma sahip:

  • Son 30 gün verisi (aktif): 20 TB Standard
  • 30-90 gün arası veri: 30 TB, Nearline’a taşınabilir
  • 90-365 gün arası veri: 30 TB, Coldline’a taşınabilir
  • 1 yıldan eski veri: 20 TB, Archive’a taşınabilir
# Mevcut depolama kullanımını analiz et
gsutil du -s -h gs://your-bucket-name

# Belirli yaş gruplarına göre analiz için
# (nesne metadata'sından tarih bilgisini çekerek)
gsutil ls -l gs://your-bucket-name | awk '{print $1, $2, $3}' | sort -k2

Standard fiyatlarına kıyasla Nearline yaklaşık %40, Coldline %70, Archive %90 daha ucuzdur. Uygun bir lifecycle stratejisiyle aylık depolama maliyetinizi ciddi ölçüde düşürebilirsiniz.

Custom Time ile Gelişmiş Konfigürasyon

Bazı senaryolarda nesnenin oluşturulma tarihine göre değil, iş mantığınıza göre belirlediğiniz bir tarihe göre lifecycle uygulamak istersiniz. Bunun için Custom Time metadata alanını kullanabilirsiniz:

# Nesneye custom time set et
gsutil -h "x-goog-custom-time:2024-12-31T00:00:00Z" 
  cp local-file.txt gs://your-bucket/path/

# Custom time'a göre lifecycle kuralı
cat > custom-time-lifecycle.json << 'EOF'
{
  "lifecycle": {
    "rule": [
      {
        "action": {
          "type": "Delete"
        },
        "condition": {
          "daysSinceCustomTime": 90
        }
      }
    ]
  }
}
EOF

gsutil lifecycle set custom-time-lifecycle.json gs://your-bucket-name

Bu özellik özellikle içerik üretim platformlarında işe yarar. Bir videonun yayın tarihi biliniyorsa, yayın tarihinden 90 gün sonra arşive taşınmasını custom time ile kolayca sağlayabilirsiniz.

Otomasyona Entegrasyon

Lifecycle kurallarını CI/CD pipeline’ınıza entegre etmek için basit bir script:

#!/bin/bash
# deploy-lifecycle.sh

BUCKET_NAME=$1
ENV=$2
CONFIG_FILE="lifecycle-configs/${ENV}-lifecycle.json"

if [ -z "$BUCKET_NAME" ] || [ -z "$ENV" ]; then
  echo "Kullanim: $0 <bucket-name> <environment>"
  exit 1
fi

if [ ! -f "$CONFIG_FILE" ]; then
  echo "Hata: $CONFIG_FILE bulunamadi"
  exit 1
fi

echo "Lifecycle kurali uygulanıyor: $BUCKET_NAME"
gsutil lifecycle set "$CONFIG_FILE" "gs://$BUCKET_NAME"

echo "Dogrulama yapiliyor..."
gsutil lifecycle get "gs://$BUCKET_NAME"

echo "Tamamlandi!"

Bu scripti GitHub Actions veya Cloud Build pipeline’ınıza ekleyerek lifecycle değişikliklerini otomatik olarak yönetebilirsiniz.

Sonuç

GCP Cloud Storage Yaşam Döngüsü Kuralları, bulut depolama maliyetlerini kontrol altında tutmanın en etkili yollarından biri. Doğru konfigüre edildiğinde hem bütçenizi korur hem de veri yönetimini otomatikleştirmiş olursunuz.

Önemli çıkarımları özetleyecek olursak: Her bucket için tamamlanmamış yüklemeleri temizleyen bir AbortIncompleteMultipartUpload kuralı ekleyin, bu neredeyse bedava tasarruf. Versiyonlama kullanıyorsanız noncurrent version temizleme kuralları zorunlu, yoksa farkında olmadan devasa depolama faturaları sizi bekliyor olabilir. Lifecycle konfigürasyonlarınızı her zaman kod olarak yönetin, JSON dosyalarını Git’e commit edin.

Son olarak şunu söyleyelim: Bu kuralları bir kez tanımlayıp unutmayın. Uygulamanız büyüdükçe, veri yapınız değiştikçe lifecycle kurallarınızı da gözden geçirin. Aylık bir bucket maliyet analizi yapmak ve gerektiğinde kuralları güncellemek sizi uzun vadede çok ciddi tasarruflarla ödüllendirecek.

Bir yanıt yazın

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