Veri Tazeliği SLO’su Nasıl Tasarlanır? Eşik Uydurmaktan Ölçülebilir Taahhüde
Veri platformunda SLI/SLO/SLA ayrımı, tazelik eşiği belirleme atölyesi, error budget, alarm yorgunluğunu önleyen for:5m ve absent() kuralları ve 90 günlük plan.
▸ Kısa Açıklama ve Yönetici Özeti
Çoğu veri ekibinin tazelik tanımı bir sayıdan ibarettir: *"veri 15 dakika içinde gelmeli."* Bu sayı nereden gelir? Genellikle bir toplantıda birinin söylediği bir tahminden.
Sorun şu: uydurulmuş bir eşik iki şekilde de zarar verir. Çok sıkıysa ekip sürekli alarmla yaşar ve gerçek olayları görmezden gelmeyi öğrenir (alarm yorgunluğu). Çok gevşekse kullanıcı bayat veriyle karar verir ve kimse fark etmez.
Doğru eşik bir mühendislik tercihi değil bir ürün kararıdır: hangi veri ürünü, hangi karar için, ne kadar eskiyebilir?
Temel sav üç maddede:
- 1Altyapı metriği SLO değildir.
replay_lag_bytes > 50MBbir erken uyarı sinyalidir. "Analist son 15 dakikadaki siparişi panoda görebilmeli" bir SLO'dur. - 2Tazelik tek sayı değildir. p50, p95 ve maksimum birlikte tanımlanmalıdır; aksi halde "ortalama iyi" olan bir sistem her gün 4 saat boyunca çok kötü olabilir.
- 3SLO'nun bir bütçesi olmalıdır. İhlal edilemeyecek bir SLO, SLO değil bir dilektir.
1. SLI, SLO, SLA: veri platformunda üç farklı şey
| Kavram | Tanım | Veri örneği | Kime ait |
|---|---|---|---|
| SLI (Indicator) | Ölçülen ham değer | "%98.4 veri tazeliği karşılandı" | Mühendislik |
| SLO (Objective) | Hedeflenen iç eşik | "Aylık %99 tazelik" | Mühendislik + ürün |
| SLA (Agreement) | Dış taahhüt + yaptırım | "Tazelik %95 altına düşerse kredi" | Ticari / hukuk |
Kritik ayrım: SLA her zaman SLO'dan gevşek olmalıdır. SLO %99 ise SLA %95 olabilir. Aksi halde iç hedefiniz dış taahhüdünüzle aynı olur ve her küçük sapma sözleşme ihlali haline gelir.
▸Veri ürünü tiplerine göre tazelik sınıfları
| Sınıf | Tipik veri ürünü | Önerilen hedef (p95) | Örnek |
|---|---|---|---|
| Gerçek zamanlı | Kullanıcı akışı, fraud sinyali, sepet | < 60 saniye | Clickstream telemetri |
| Operasyonel | Stok, sipariş durumu, finansal defter | < 5–30 dakika | Warehouse inventory |
| Analitik | Günlük pano, kohort analizi | < 6 saat | Customer 360 |
| Raporsal | Aylık kapanış, regülatif rapor | < 1 gün | Finansal mutabakat |
2. Eşik belirleme atölyesi (4 adım)
Uydurulmuş eşiklerin panzehiri, eşiği bir atölyede üretmektir. 60–90 dakika sürer; şu kişiler gerekir: veri ürünü sahibi, bir analist (tüketici), bir veri mühendisi.
▸Adım 1 — Tüketim anını yazın
Eşik, tüketimin zamanlamasına bağlıdır. Sorun: *"Bu veriyi kim, hangi saatte, hangi karar için kullanıyor?"*
| Soru | Örnek cevap |
|---|---|
| Hangi karar? | Sabah 09:00 bölge toplantısında dünün satışları |
| Karar ne zaman veriliyor? | 09:00–09:30 |
| Karar geri dönülebilir mi? | Hayır — tedarik siparişi veriliyor |
| Bayat veri neye yol açar? | Yanlış stok seviyesi → fazla sipariş |
▸Adım 2 — "Kabul edilebilir en kötü" anı tanımlayın
*"En kötü durumda veri kaç saat eski olabilir?"* sorusuna iş tarafının verdiği cevap SLO'yu belirler.
- Toplantı 09:00'da ise veri 08:30'da hazır olmalı.
- Buna 1 saat güvenlik payı ekleyin → gerçek hedef 07:30.
▸Adım 3 — p50 / p95 / max tanımlayın
Tek bir "ortalama" tazelik metriği yanıltıcıdır. Üç değeri birlikte yazın:
Freshness SLO (örnek):
p50 ≤ 2 saat (tipik gün, normal davranış)
p95 ≤ 3 saat (20 iş gününün 19'unda sağlanmalı)
max ≤ 6 saat (hiçbir gün aşılmamalı)
Pencere: son 30 gün, yalnızca iş günlerimax ise "hiç olmamalı" çizgisidir.▸Adım 4 — Ölçüm noktasını kilitleyin
| Ölçüm noktası | Ne ölçer | Risk |
|---|---|---|
Kaynak sistemde yazılma anı (T_source) | Gerçek üretim | Downstream gecikmeyi görmez |
Ambar tablosunda max(updated_at) | Yükleme tamamlanma | Modelleme süresini görmez |
| BI panosunda görünme anı | Kullanıcı deneyimi ✅ | Ölçmesi en zor ama en doğru |
Öneri: SLI'yi kullanıcıya en yakın noktada tanımlayın (pano/API), teşhis için kaynak metriklerini ayrıca tutun. İkisini karıştırmayın.
3. Error budget: "ne kadar kötü olabiliriz"
SLO = %99 ise, 30 günde %1 kötü olma hakkınız var. Bu bir bütçedir ve tüketilebilir.
▸Bütçe matematiği
30 günlük pencere, günlük partisyon (30 partisyon)
SLO: %99 → bütçe = 30 × 0.01 = 0.3 parti ≈ 1 bozuk gün / 3 ay
Haftalık pencere, saatlik partisyon (168 partisyon)
SLO: %99 → bütçe = 168 × 0.01 = 1.68 saat▸Bütçe tüketimine göre politika
| Bütçe tüketimi | Politika |
|---|---|
| %0–50 | Normal akış. Yeni özellik geliştirilebilir. |
| %50–75 | Dikkat. Yeni veri ürünü onboarding'i yavaşlatılır. |
| %75–100 | Yalnızca güvenilirlik işi. Yeni pipeline deploy'u yalnızca zorunluysa. |
| %100 aşıldı | Deploy freeze. Tüm ekip kök nedene odaklanır. SLO gözden geçirilir (*çok mu sıkıydı?*). |
▸SLO çok sıkıysa ne olur?
Bütçe sürekli tükeniyorsa iki olasılık vardır: (1) sistem gerçekten yetersiz → yatırım gerekir, (2) SLO gerçekçi değil → hedef gevşetilir.
İkincisini yapmak zayıflık değildir; yanlış hedefe yatırım yapmaktan iyidir. Ancak gerekçeyi yazın: *"p95 hedefi 2 saatten 3 saate çekildi çünkü üst kaynak sistemin batch penceresi 02:00–04:00 arası ve SLO o pencereyi hesaba katmıyordu."*
4. Altı ilkeyi operasyonelleştirme
/observability sayfasındaki 6 ilke doğrudur ama soyut kalır. Her birini bir alarm kuralına ve bir sahibe bağlamak gerekir.
| # | İlke | Operasyonel karşılığı | Sahip |
|---|---|---|---|
| 1 | Freshness | source_freshness_seconds metriği + SLO ihlal alarmı | Veri platform |
| 2 | Volume | Satır sayısı için dinamik eşik (mevsimsellik dahil) + ani düşüş alarmı | Veri platform |
| 3 | Schema drift | CI'da şema kilidi + üretimde sonradan uyarı | Üretici ekip + CI |
| 4 | Column lineage | upstream_column → downstream_dashboard eşlemesi; etki analizi için | Veri platform |
| 5 | Quality assertions | Zorunlu test seti (not-null, unique, accepted_values, relationships) | Veri kalitesi |
| 6 | Cost telemetry | Sorgu başına maliyet + pahalı model listesi | Analytics engineering |
▸Hangi ilke hangi sorunu çözer?
Alarm yorgunluğunun en yaygın nedeni, ilk iki ilkenin (freshness + volume) her pipeline'a uygulanmasıdır. Bunun yerine kritiklik sınıfına göre uygulayın:
| Veri ürünü kritikliği | Freshness | Volume | Schema | Lineage | Assertions | Cost |
|---|---|---|---|---|---|---|
| Tier 1 (gelir/regülasyon) | ✅ sıkı | ✅ sıkı | ✅ bloklayıcı | ✅ | ✅ tam | ✅ |
| Tier 2 (operasyon) | ✅ | ✅ | ✅ uyarı | ✅ | ✅ temel | ✅ |
| Tier 3 (keşif/analiz) | ⚠️ gevşek | ⚠️ gevşek | ⚠️ uyarı | ❌ | ⚠️ minimum | ❌ |
Tier tanımlanmazsa her şey Tier 1 olur ve alarm sistemi çöker.
5. Alarm yorgunluğunu önleyen 4 kural
▸Kural 1 — `for: 5m` zorunlu
Tek bir örnekleme anında eşiği aşan geçici dalgalanma alarm değildir. En az 5 dakika süregelen ihlal alarmdır.
# Prometheus Alertmanager
- alert: DataFreshnessSLOBreach
expr: source_freshness_seconds > 10800 # 3 saat = p95 hedefi
for: 5m # ← bu satır olmadan alarm çöptür
labels:
severity: warning
slo: freshness_p95
annotations:
summary: "{{ $labels.dataset }} tazelik p95 hedefini aştı"
runbook: "https://dataopsphere.com/reliability/recovery-readiness"▸Kural 2 — `absent()` her zaman eşlik etmeli
Sistem çöktüğünde metrik gelmez. Klasik alarmlar "değer yüksek mi?" diye bakar ve sessiz kalır. Bu, en tehlikeli durumdur: sistem ölü, alarm suskun.
- alert: DataPipelineTelemetryAbsent
expr: absent(source_freshness_seconds{job="dbt-exporter"})
for: 10m
labels:
severity: critical
annotations:
summary: "dbt exporter 10 dakikadır metrik göndermiyor — SİSTEM KÖR"▸Kural 3 — Rölanti (idle) durumunu ayırt et
Gece hiç yazma olmayan bir tabloda freshness alarmı çalmasın. Kural, "yazma oldu mu?" ön koşuluna bağlanmalı:
expr: (time() - max(source_max_updated_at) > 10800) and (produce_events_total > 0)▸Kural 4 — Alarm bütçesi koy
Haftada belirli sayıdan fazla alarm çalan bir kural, ya eşiği yanlış ya da sistemi gerçekten bozuk demektir. Aylık olarak:
| Ölçüm | Eşik | Aksiyon |
|---|---|---|
| Kural başına haftalık alarm sayısı | > 5 | Eşiği veya pencereyi gözden geçir |
| Alarm → aksiyon oranı | < %50 | Kural kaldırılır veya severity düşürülür |
| Gece 02:00–06:00 alarm oranı | > %30 | Pencere/batch uyumsuzluğu araştır |
6. Olgunluk değerlendirmesi
| Seviye | Ad | Koşullar |
|---|---|---|
| 0 | Reaktif | Sorunlar kullanıcılar tarafından bildiriliyor. Tazelik izlenmiyor. |
| 1 | Temel izleme | Pipeline başarı/başarısızlık durumu izleniyor. Tazelik eşiği yok veya uydurulmuş. |
| 2 | Ölçülen tazelik | Her kritik veri ürünü için yazılı SLO var (p50/p95/max). for: penceresi ve absent() kuralı tanımlı. |
| 3 | Bütçelenen | Error budget hesaplanıyor ve panoda görünüyor. Bütçe politikası yazılı ve uygulanıyor. Alarm → aksiyon oranı ölçülüyor. |
| 4 | Öngörülü | Tazelik trendi önceden tahmin ediliyor (batch süresi büyüme eğrisi). Kapasite planı SLO verisine bağlı. Kolon seviyesi lineage üzerinden otomatik etki analizi yapılıyor. |
Pratik hedef: İlk 90 günde Seviye 2, ilk yılda Seviye 3.
▸▸ Hızlı öz değerlendirme
Her "evet" 1 puan. 0–3: Seviye 0–1 · 4–7: Seviye 2 · 8–10: Seviye 3+
- Her kritik veri ürünü için yazılı tazelik SLO'su var
- SLO'da p50 ve p95 ayrı tanımlı (tek "ortalama" yok)
- Her tazelik alarmında
for: 5m(veya daha uzun) penceresi var absent()tabanlı "telemetri yok" alarmı tanımlı- Rölanti/idle durumu için ayrı koşul var
- Veri ürünleri kritiklik sınıfına (Tier 1/2/3) ayrılmış
- Error budget hesaplanıyor ve görünür
- Bütçe aşımında ne yapılacağı yazılı (deploy freeze politikası)
- Alarm → aksiyon oranı ölçülüyor
- Kolon seviyesi lineage ile etki analizi yapılabiliyor
7. Metrikler: observability yatırımının karşılığı
| Metrik | Tanım | İyi sinyal |
|---|---|---|
| MTTD | Hatalı veri üretimi → tespit | Düşen trend, hedef < 15 dk (Tier 1) |
| SLO uyum oranı | SLO sağlanan pencere ÷ toplam pencere | > %99 (Tier 1) |
| Yanlış alarm oranı | Aksiyonsuz kapanan alarm ÷ toplam alarm | < %10 |
| Alarm → aksiyon oranı | Aksiyon doğuran alarm ÷ toplam | > %50 |
| Kullanıcı-bildirimli olay oranı | Kullanıcının bildirdiği ÷ toplam olay | < %20 ← en önemli |
| Kapsama oranı | SLO'su tanımlı Tier 1 ürün ÷ tüm Tier 1 | %100 |
| Telemetri boşluğu sayısı | absent() alarmı çalan exporter sayısı | 0 |
8. İlk 90 gün planı
▸1 — 1–2. hafta: Envanter ve Tier
- Tüm veri ürünlerini listeleyin; her birine bir Tier atayın (Tier 1/2/3).
- Tier 1 ürünler için mevcut tazelik değerini ölçün (geçmiş 30 gün).
- Hangi alarmların var olduğunu ve kaçının aksiyona dönüştüğünü çıkarın.
▸2 — 3–4. hafta: İlk SLO
- Tek bir Tier 1 ürün için atölye yapın (bölüm 2, 4 adım).
- Yazılı SLO'yu yayınlayın: p50 / p95 / max + pencere + iş günü tanımı.
for: 5mveabsent()kurallarını ekleyin.- Kanıt: Exporter'ı staging'de durdurup
absent()alarmının çaldığını görün.
▸3 — 5–8. hafta: Yay ve bütçe
- Kalan Tier 1 ürünlere SLO yazın.
- Error budget panosunu kurun.
- Bütçe politikasını (deploy freeze eşiği) yayınlayın ve ekip onayını alın.
- Alarm → aksiyon oranını ölçmeye başlayın; %50 altındaki kuralları revize edin.
▸4 — 9–12. hafta: Lineage ve maliyet
- Airflow/Dagster'a OpenLineage entegrasyonunu ekleyin (kolon seviyesi).
- Bir "etki analizi" tatbikatı yapın: bir kolonu kasıtlı değiştirin, kaç panonun etkilendiğini lineage'dan çıkarın.
- Sorgu başına maliyet panosunu kurun; en pahalı 5 modeli listeleyin.
Kabul kriteri (90. gün): Tüm Tier 1 ürünler için yazılı SLO, absent() alarmı çalışır durumda, error budget panoda görünür, ve kullanıcı-bildirimli olay oranı ölçülmüş.
9. Şablonlar
▸9.1 dbt `sources.yml` — tazelik tanımı
sources:
- name: orders_db
database: prod
schema: public
freshness:
warn_after: { count: 2, period: hour } # p50 hedefi
error_after: { count: 3, period: hour } # p95 hedefi
filter: loaded_at_field is not null
loaded_at_field: _ingested_at
tables:
- name: orders
description: "Sipariş master tablosu — Tier 1"
columns:
- name: order_id
tests: [unique, not_null]
- name: amount_usd
tests: [not_null]▸9.2 Elementary — anomali ve tazelik
# elementary_config.yml
models:
elementary:
+schema: elementary
freshness_anomalies:
enabled: true
# Haftalık mevsimselliği hesaba kat
training_period:
period: day
count: 14
volume_anomalies:
enabled: true
# Önemli: yeni veri setlerinde ilk 7 gün anomali üretme (soğuma)
ignore_small_changes:
spike_ratio: 0.2
drop_ratio: 0.2▸9.3 SLO tanım dosyası (önerilen format)
# slos/orders-freshness.yaml
service: orders_master
tier: 1
owner_role: "Data Platform Team"
sli:
type: freshness
measurement_point: bi_dashboard # kullanıcıya en yakın nokta
metric: max(_ingested_at)
objective:
window: 30d
business_days_only: true
p50: 2h
p95: 3h
max: 6h
error_budget:
slo_target: 0.99
policy:
warn_at: 0.75
freeze_at: 1.00
alerts:
breach:
for: 5m
severity: warning
telemetry_absent:
for: 10m
severity: critical
idle_guard: true10. Kaynaklar ve ilgili rehberler
Bu sayfanın dayandığı kaynaklar
- Google SRE Workbook — *Implementing SLOs*, *Alerting on SLOs*
- dbt Docs — *Source freshness*
- Elementary — *Freshness & volume anomaly monitors*
- OpenLineage — *Column-level lineage specification*
- Prometheus — *Alerting rules best practices* (
for,absent())
dataopsphere iç bağlantılar
- Replication Lag Alarmından Müdahaleye: Eskalasyon Runbook'u — altyapı metriği vs SLO ayrımının PostgreSQL versiyonu
- Postmortem Kültürü: Suçlamasız Vaka Analizi — tespit edici aksiyonların olay sonrası takibi
- Data Contracts Library — sözleşmelerde tanımlı freshness SLA'ları
- Veri Kalitesi Hatasına Müdahale & Karantina —
UNVERIFIEDdurumu ve devre kesici - Uçtan Uca Data Observability — 6 temel ilke ve konfigürasyon şablonları
▸▸ 3 SİTELİ TRİAD: Veri Tazeliği ve SLO
- dbaguide.com · Teknik —
pg_stat_replication, WAL LSN farkı ve tazelik sorguları - dataxtools.com · Araç Seçimi — Elementary vs Soda vs Monte Carlo vs Bigeye karşılaştırması
- dataopsphere.com · Operasyonel Olgunluk — *Bu sayfa*: SLO tasarımı, error budget, alarm politikası
Restore Tatbikatı & Kurtarma Deneyiminizi Paylaşın
Altyapınızdaki gerçek tatbikat sonuçlarını, RTO/RPO hedeflerinizi ve karşılaştığınız operasyonel engelleri anonim veya isimli olarak paylaşın. Sektör benchmark'ına katkıda bulunun.
Bu mimariyi üretimde test etmek ister misiniz?
DataOpsphere CI/CD şablonlarını ve Docker Compose ortamlarını kopyalayıp hemen çalıştırabilirsiniz.