Bu yazıda Prometheus ekosisteminde sık karşılaştığım ve altyapı yöneticisi bakış açısıyla çözümünü uyguladığım kardinalite kaynaklı maliyet ve operasyonel zorlukları ele alacağım. 18+ yıllık Linux, açık kaynak, ağ ve DevOps tecrübemden yola çıkarak sahadan edindiğim pratik çıkarımlar, kısa kod örnekleri ve uygulanabilir kontrol listesi sunuyorum. Amacım teoriden ziyade üretimde işe yarayan yaklaşımları paylaşmak: ölçülebilir, geri alınabilir ve güvenli.
Neden kardinalite problemidir? - Prometheus, etiket (label) kombinasyonlarını zaman serisi kimliği olarak ele alır. Her benzersiz kombinasyon yeni bir zaman serisi demektir. - Yüksek kartinalite; bellek, disk, CPU, ağ ve sorgu gecikmeleri üzerinde doğrudan maliyet oluşturur. - Üretimde problemler genellikle beklenmeyen etiketlerin (ör. request_id, user_id, dynamic path segment) metriğe sızmasıyla başlar.
Temel prensipler 1. "Etiketleri ölçün, sadece saklamayın": Yeni bir etiket eklerken önce kaç benzersiz değer bekleniyor? Bu kesin sayı bilinmiyorsa önce ölçün (ör. temporary metric ile). 2. "Kısıtlama + Özetleme": Ham yüksek-kardinalite veriyi saklamak yerine, örneğin request_id gibi verileri kesip yalnızca sayısal özetleri saklayın. 3. "Güvenli varsayımlar ve geri alma": Değişiklikleri küçük adımlarla ve kısa-retention testiyle uygulayın; kolay geri alma planı hazırlayın. 4. "Sorgu dostu tasarım": Sık kullanılan sorguları kayıt (recording) kuralı ile özetleyin; canlı sorguların maliyetini azaltın.
Saha çıkarımları (pratik, tekrar eden gözlemler) - Dinamik path segmentleri (ör. /user/12345/orders) doğrudan label haline getirilirse çok hızlı kartinalite patlaması olur. Bunun yerine path'leri normalize edin veya grup etiketleri kullanın (örn. /user/:id/orders → route=/user/orders). - Uygulama loglarından otomatik olarak yaratılan label'lar üretimde tehlikelidir; log-based iş akışları ile cross-check yapmadan metriğe label eklemeyin. - Eksik relabeling veya yanlış scrape config'leri beklenmedik etiket patlamalarına yol açar; yeni hedefler eklenmeden önce dry-run ve `promtool check` kullanın. - Sorgularda regex kullanımı, yüksek kardinalite dönemlerinde Prometheus CPU kullanımını hızla yükseltir; mümkünse kayıt kuralları ile hazırlayın.
Kısa kod örneği: relabel ile path parametre temizleme ve recording rule ile özetleme
- relabel örneği (scrape config içinde): dynamic path segmentleri capture edip sabit route etiketi koyma. - job_name: 'my-app' static_configs: - targets: ['10.0.0.5:9100'] metrics_path: /metrics relabel_configs: # Örnek: endpoint etiketi varsa /user/12345/orders -> route=/user/orders - source_labels: [__metrics_path__] regex: '/user/[^/]+/orders' replacement: '/user/orders' target_label: route # request_id gibi eşsiz değerleri sil - regex: 'request_id|session_id|trace_id' action: labeldrop
- recording rule örneği: yüksek hacimli raw zaman serilerini özetleyip sorgu maliyetini azaltma. groups: - name: app_summary.rules rules: - record: job:http_requests:rate5m expr: sum by (job, route, status) (rate(http_requests_total[5m])) - record: job:http_error_ratio:5m expr: sum by (job, route) (rate(http_requests_total{status=~"5.."}[5m])) / sum by (job, route) (rate(http_requests_total[5m]))
Uygulama adımları (sıralı, geri alınabilir) 1. Ölç: Potansiyel riskli label'lar için benzersiz değer sayısını belirle. Örneğin kısa süreli scrape ile `count_values` veya hedef uygulamada sayaç/örnekleme ile ölçüm yap. 2. Küçük değişiklikle başla: İlk olarak sadece relabel veya labeldrop ile blacklist uygula, ardından gözlemle (24-72 saat). 3. Kayıt kuralları ekle: Sorgu yoğun metrikleri için recording rules oluştur ve dashboard sorgularını buna bağla. 4. Retention/TSDB ayarı: Eğer disk maliyeti sorun ise retention süresini yeniden değerlendir; sıcak/soğuk katmanlama (thanos, cortex gibi) düşün. 5. İzle: Bellek, disk, scrape başarısızlıkları, `prometheus_tsdb_head_series` gibi metrikleri izleyin. 6. Otomatize uyarı: Yeni seri sayısı ani artışında alarm tetikleyen uyarılar kurun.
Kontrol listesi (production-ready, uygulanabilir) - [ ] Kritik metriklere yeni label eklenmeden önce benzersiz değer sayısı ölçüldü mü? - [ ] Scrape relabel_configs içerisinde istenmeyen dinamik label'lar droplandı mı? - [ ] Path ve URL parametreleri normalize edildi mi (route etiketi kullanılarak)? - [ ] Recording rules ile maliyetli sorgular özetlendi mi? - [ ] Dashboarlar doğrudan yüksek-dereceli metrikleri sorgulamıyor; recording rule'ları kullanıyor mu? - [ ] Prometheus sunucularının heap/TSDB kullanımını sürekli izleyen alarm setleri mevcut mu? - [ ] Yeni konfigürasyon önce test cluster'ında (veya kısa retention ile production'da güvenli kısımda) doğrulandı mı? - [ ] Eğer gerekiyorsa uzun süreli saklama için dış depo (Cortex/Thanos/remote_write) planı hazır mı? - [ ] Ingest noktasında (exporter/app) örnekleme (sampling) politikası belirlendi mi? - [ ] Yeni etiketlerin eklenmesi için kod incelemesi / ops onay süreci tanımlandı mı?
Ek ipuçları - Label açıklamaları ve belgeleme: Hangi label'ın neden eklendiğini reposunda kısa bir açıklama olarak saklayın. Geçmişte pek çok sorun belgelendirme eksikliğinden kaynaklandı. - Canary/deney bölgesi: Büyük değişiklikleri önce küçük bir servis grubunda deneyin. Etkiyi sınırlı tutmak geri alma maliyetini azaltır. - Exporter tarafı: Mümkünse exporter'larda cardinality azaltıcı ayarlara (label whitelist/blacklist, quantization) izin verin. - Kullanıcı sorgularını eğitin: Ekiplerin sorguları daha verimli yazmasını teşvik edin; PromQL stilleri konusunda rehber hazırlayın.
Sonuç Kardinaliteyi yönetmek teknik olarak karmaşık olmakla birlikte operasyonel bir disiplindir: ölçme, sınırlama, özetleme, izleme ve otomasyon. Küçük, güvenli ve geri alınabilir adımlarla ilerlerseniz hem Prometheus maliyetlerini kontrol altında tutar hem de üretim stabilitesini korursunuz. Bu yazıda paylaştığım pratik yaklaşımlar ve kontrol listesi, günlük işletim yükünüzü azaltmak için uygulanabilir ilk adımları sunuyor.
Eğer isterseniz mevcut Prometheus konfigürasyonunuzun kritik bölümlerine göz atabilirim; relabel veya recording rule önerileriyle spesifik bir plan çıkarabiliriz.

