Veritabanı Yönetimi

    InfluxDB ile Metrik Saklama

    Zaman serisi metriklerini InfluxDB'de saklamanın, sorgulamanın ve budamanın pratik yolu.

    13 dk okuma Güncellendi: 25 Ağustos 2026

    Sunucularınızın CPU kullanımını, disk doluluğunu, nginx istek sayısını ve uygulama gecikmesini dakikada bir kaydetmeye başladığınızda ortaya çok özel bir veri tipi çıkar: her satırı bir zaman damgası taşıyan, asla güncellenmeyen, sadece eklenen ve birkaç hafta sonra büyük ölçüde değerini yitiren veri. Bu veriyi MySQL'e yazmayı denediyseniz ne olduğunu biliyorsunuzdur; tablo birkaç ayda yüz milyonlarca satıra çıkar, GROUP BY içeren basit bir grafiğin sorgusu dakikalarca sürer ve indeksler diskten daha çok yer kaplamaya başlar. InfluxDB ile metrik saklama tam olarak bu problemi çözmek için tasarlanmış bir yaklaşımdır: veriyi zamana göre bloklar hâlinde sıkıştırır, eski veriyi otomatik siler ve zaman penceresi üzerinden yapılan toplama işlemlerini olağan bir işlem gibi çalıştırır.

    Bu rehberde InfluxDB'nin veri modelini (measurement, tag, field, timestamp) net biçimde ayıracağız, tek sunuculu bir kurulumu baştan sona yapacağız, line protocol ile veri yazmayı ve Telegraf ile otomatik toplamayı göstereceğiz, Flux sorgularının mantığını çözeceğiz ve en önemlisi işin ucunda sizi bekleyen iki tuzağı anlatacağım: kardinalite patlaması ve retention politikasını unutmak. Bu ikisi, "InfluxDB neden 200 GB diskimi yedi" sorusunun neredeyse tamamının cevabıdır.

    Zaman Serisi Verisi Neden Ayrı Bir Veritabanı İster#

    İlişkisel bir veritabanı, satırların bağımsız olarak güncellenebildiği, silinebildiği ve rastgele okunabildiği bir dünya için tasarlanmıştır. Metrik verisi ise bunun tam tersi bir profil çizer: yazma neredeyse her zaman "en yeni zaman damgası" ile sonlanır, güncelleme diye bir şey yoktur, silme tek tek satır değil koca zaman aralıkları hâlinde yapılır ve okumaların büyük çoğunluğu "son 6 saatin ortalamasını 1 dakikalık pencerelerde ver" biçimindedir. Bu profil, depolama motorunu bambaşka kurmanıza izin verir.

    InfluxDB verileri sütun bazlı bloklar hâlinde saklar ve zaman damgaları ile sayısal değerler için delta kodlama, çift sıkıştırma gibi teknikler kullanır. Sonuç şudur: ardışık ve birbirine yakın değerlerden oluşan bir CPU metriği, ham hâlinin küçük bir kesri kadar disk tutar. Buna karşılık InfluxDB'de JOIN yoktur, güçlü bir transaction modeli yoktur ve keyfi alanlar üzerinde ikincil indeks beklentisine girerseniz hayal kırıklığı yaşarsınız. Yani bu bir genel amaçlı veritabanı değildir; hangi işi hangi motora vereceğinizi seçme konusunda daha kapsamlı bir bakış için SQL mi NoSQL mu seçim rehberi yazısına da göz atın.

    Özellikİlişkisel veritabanıInfluxDB
    Baskın yazma deseniRastgele INSERT/UPDATEZaman sırasıyla append
    Silme deseniSatır bazlı DELETEZaman aralığı / retention
    Tipik sorguJOIN + WHERE + LIMITrange + filter + aggregateWindow
    ŞemaKatı, önceden tanımlıYazma anında oluşur
    Sıkışma oranıDüşük–ortaYüksek (sayısal seriler)
    Eski veriyi budamaElle kurgulanırPolitika ile otomatik

    Veri Modeli: Measurement, Tag, Field ve Timestamp#

    InfluxDB'de her nokta dört parçadan oluşur ve bu dördünün farkını anlamak, ilerideki tüm performans kararlarınızı belirler. Measurement, ilişkisel dünyadaki tablo adına en yakın kavramdır: cpu, disk, nginx_requests gibi. Tag ler indekslenen, metin tipinde etiketlerdir: host=web01, region=istanbul, disk=/dev/sda1. Field ler indekslenmeyen, asıl ölçüm değerleridir: usage_idle=92.4, bytes_sent=88213i. Timestamp ise nanosaniye çözünürlüklü zaman damgasıdır.

    Buradaki en kritik ayrım şudur: tag'ler indekslenir, field'lar indekslenmez. Bir değere göre filtreleme yapacaksanız (WHERE host = 'web01') o değer tag olmalıdır. Bir değerin ortalamasını, toplamını, yüzdelik dilimini alacaksanız o değer field olmalıdır. Ve asla değişken, sınırsız sayıda farklı değer alabilen bir şeyi (istek kimliği, oturum numarası, kullanıcı e-postası) tag yapmayın. Neden yapmamanız gerektiğini birazdan kardinalite bölümünde bütün acılığıyla anlatacağım.

    Bu dört parça birleşince line protocol dediğimiz metin biçimi ortaya çıkar:

    # Biçim: measurement,tag_seti alan_seti zaman_damgasi
    # Tag'ler virgülle, alan seti boşlukla ayrılır. Boşluk sayısı önemlidir.
    cpu,host=web01,region=istanbul usage_idle=92.4,usage_system=3.1 1755100800000000000
    disk,host=web01,path=/ used_percent=61.2 1755100800000000000
    nginx,host=web01,vhost=firmaniz.com requests=1420i,latency_ms=38.5 1755100800000000000
    

    Sondaki i son eki değerin tam sayı olarak saklanacağını söyler; onu yazmazsanız değer kayan noktalı sayı olur. Bir field'ın tipini sonradan değiştiremezsiniz — aynı measurement içinde bir gün requests=1420i, ertesi gün requests=1420 yazarsanız yazma hatası alırsınız. Bu, üretimde en sık karşılaşılan "neden veri düşüyor" sebeplerinden biridir.

    Kurulum ve İlk Bucket#

    Ubuntu tabanlı bir sunucuda InfluxDB 2.x kurulumu paket deposu üzerinden yapılır. Aşağıdaki adımlar tek sunuculu, kendi altyapınızda barındırdığınız bir kurulum içindir:

    1. Resmî depoyu ve GPG anahtarını sisteme ekleyin.
    2. influxdb2 paketini kurun ve servisi başlatın.
    3. influx setup ile ilk organizasyonu, kullanıcıyı ve bucket'ı oluşturun.
    4. Üretilen API token'ını güvenli bir yere alın; bu token yazma ve okuma yetkisinin tamamıdır.
    5. 8086 portunu güvenlik duvarında yalnızca ihtiyacınız olan kaynaklara açın.
    # Servisi başlat ve açılışta otomatik başlamasını sağla
    sudo systemctl enable --now influxdb
    sudo systemctl status influxdb --no-pager
    
    # İlk kurulum sihirbazı: org, kullanıcı, ilk bucket ve token üretir
    influx setup \
      --org firmaniz \
      --bucket metrics \
      --username admin \
      --retention 30d \
      --force
    
    # Kurulum sonrası bucket listesi
    influx bucket list
    

    --retention 30d parametresi burada tesadüfen yazılmış değil; bucket'ı saklama süresi belirtmeden oluşturursanız veri sonsuza kadar saklanır ve diskiniz sessizce dolar. Bir bucket'ın retention süresini sonradan da değiştirebilirsiniz:

    # Var olan bucket'ın saklama süresini 90 güne çek
    influx bucket update --name metrics --retention 90d
    
    # Yalnızca uzun dönem özetler için ikinci bir bucket
    influx bucket create --name metrics_rollup --retention 730d
    

    Bu ikinci bucket'ı neden açtığımızı downsampling bölümünde göreceksiniz. Kurulumu kendi sunucunuzda yapıyorsanız disk tipinin önemi büyüktür: InfluxDB yazma yolunda sürekli WAL dosyasına dokunur, bu yüzden NVMe SSD ile dönen disk arasındaki fark buradadır ve ölçülebilir. Kaynak ayırmak istemiyorsanız VDS veya bulut sunucu paketleri, izleme yığınını ana uygulama sunucunuzdan ayırmak için makul bir başlangıçtır.

    Veri Yazma: HTTP API ve Telegraf#

    Veriyi InfluxDB'ye yazmanın en dolaysız yolu HTTP API'sine line protocol göndermektir. Bu, herhangi bir dilden ya da doğrudan curl ile yapılabilir:

    # Token'ı ortam değişkenine al, komut geçmişine yazmaktan kaçın
    export INFLUX_TOKEN="BURAYA_TOKEN"
    
    curl -s -X POST "http://127.0.0.1:8086/api/v2/write?org=firmaniz&bucket=metrics&precision=s" \
      -H "Authorization: Token ${INFLUX_TOKEN}" \
      -H "Content-Type: text/plain; charset=utf-8" \
      --data-binary 'temp,host=web01,room=rack3 value=23.7'
    

    Başarılı bir yazma HTTP 204 döner, yani gövde boştur. 400 alıyorsanız line protocol biçiminde bir sorun vardır (çoğunlukla fazladan boşluk ya da tip çakışması), 401 alıyorsanız token yanlış, 404 alıyorsanız bucket adı yanlıştır. Elle yazma iyidir ama üretimde metriklerin çoğunu bir toplayıcı ajan üretir. InfluxData'nın kendi ajanı olan Telegraf, yüzlerce girdi eklentisiyle gelir ve TOML yapılandırma dosyasıyla yönetilir:

    [agent]
      interval = "10s"          # Toplama sıklığı
      flush_interval = "10s"    # Gönderim sıklığı
      hostname = "web01"        # Boş bırakılırsa sistem hostname'i kullanılır
    
    [[outputs.influxdb_v2]]
      urls  = ["http://127.0.0.1:8086"]
      token = "$INFLUX_TOKEN"
      organization = "firmaniz"
      bucket = "metrics"
    
    [[inputs.cpu]]
      percpu = false            # Çekirdek başına seri üretme, kardinaliteyi düşürür
      totalcpu = true
    
    [[inputs.disk]]
      ignore_fs = ["tmpfs", "devtmpfs", "overlay"]
    
    [[inputs.nginx]]
      urls = ["http://127.0.0.1/nginx_status"]
    

    percpu = false satırı basit görünür ama 32 çekirdekli bir makinede seri sayısını 32'ye bölerek düşürür. Telegraf'ı çalıştırmadan önce yapılandırmayı test etmek iyi bir alışkanlıktır:

    # Yapılandırmayı doğrula ve tek bir toplama turunu ekrana bas
    telegraf --config /etc/telegraf/telegraf.conf --test
    
    # Sorun yoksa servisi başlat
    sudo systemctl enable --now telegraf
    

    Flux ile Sorgulama ve Grafik Üretme#

    InfluxDB 2.x'in sorgu dili Flux, SQL'e benzemez; bir veri akışını boru hattından (pipe) geçirerek dönüştürür. Mantığı bir kez oturttuğunuzda oldukça okunaklıdır. Tipik bir sorgu şu üç adımı içerir: kaynağı seç, zaman aralığını daralt, filtrele ve topla.

    // Son 6 saatte web01 sunucusunun boşta CPU yüzdesi, 1 dakikalık ortalamalarla
    from(bucket: "metrics")
      |> range(start: -6h)
      |> filter(fn: (r) => r._measurement == "cpu")
      |> filter(fn: (r) => r._field == "usage_idle")
      |> filter(fn: (r) => r.host == "web01")
      |> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
      |> yield(name: "cpu_idle_1m")
    

    Buradaki range() çağrısı isteğe bağlı değildir; zaman aralığı vermeden yapılan bir sorgu tüm bucket'ı taramaya kalkar ve büyük veri setlerinde sunucuyu zorlar. aggregateWindow ise zaman serisi işinin kalbidir: veriyi eşit pencerelere böler ve her pencerede bir toplama fonksiyonu çalıştırır. mean dışında max, min, sum, last ve yüzdelik için quantile kullanabilirsiniz.

    Gecikme metriklerinde ortalama yerine yüzdelik kullanmak neredeyse her zaman daha doğrudur, çünkü ortalama birkaç hızlı isteğin arkasına saklanan yavaşlığı gizler:

    // p95 yanıt süresi, 5 dakikalık pencerelerde
    from(bucket: "metrics")
      |> range(start: -24h)
      |> filter(fn: (r) => r._measurement == "nginx" and r._field == "latency_ms")
      |> aggregateWindow(
           every: 5m,
           fn: (tables=<-, column) => tables |> quantile(q: 0.95, column: column),
           createEmpty: false
         )
    

    Eski InfluxQL sorguları hâlâ desteklenir ve SQL'e alışkın gözler için daha tanıdıktır; InfluxDB'nin 3.x serisiyle birlikte SQL üzerinden sorgulama da mümkün hâle gelmiştir. Ancak 2.x kurulumlarında yeni yazacağınız her şeyi Flux ile yazmak, görev (task) ve uyarı (alert) altyapısıyla aynı dili paylaştığı için daha tutarlı olur.

    Retention, Downsampling ve Disk Kontrolü#

    Metrik verisinin değeri zamanla üstel biçimde düşer. Dünkü CPU grafiğinin 10 saniyelik çözünürlüğe ihtiyacı vardır; altı ay önceki aynı grafiğin saatlik ortalamadan fazlasına ihtiyacı yoktur. Downsampling tam olarak budur: ham veriyi kısa süre saklarsınız, özetlenmiş hâlini uzun süre. InfluxDB'de bunu zamanlanmış bir görev (task) ile yaparsınız:

    // Her saat çalışır: ham metrikleri saatlik ortalamaya indirip rollup bucket'ına yazar
    option task = {name: "cpu_hourly_rollup", every: 1h}
    
    from(bucket: "metrics")
      |> range(start: -1h)
      |> filter(fn: (r) => r._measurement == "cpu")
      |> aggregateWindow(every: 1h, fn: mean, createEmpty: false)
      |> to(bucket: "metrics_rollup", org: "firmaniz")
    

    Bu görevle birlikte metrics bucket'ında 30 günlük ham veri, metrics_rollup bucket'ında iki yıllık saatlik özet tutarsınız. Disk kullanımınız bir yıl sonra bile öngörülebilir kalır. Ne kadar disk gerektiğini kabaca hesaplamak için seri sayısı × yazma sıklığı × nokta başına ortalama sıkıştırılmış boyut formülünü kullanabilirsiniz; ağ ve depolama kapasitesi planlarken bant genişliği hesaplayıcı aracı da işinizi kolaylaştırır.

    Diskin nereye gittiğini merak ettiğinizde veri dizinini doğrudan inceleyebilirsiniz:

    # Bucket bazında disk kullanımı (varsayılan veri dizini)
    sudo du -sh /var/lib/influxdb/engine/data/* | sort -h | tail -20
    
    # Yazma öncesi log (WAL) boyutu — sürekli büyüyorsa yazma sıkışması vardır
    sudo du -sh /var/lib/influxdb/engine/wal
    

    Kardinalite: En Pahalı Hata#

    InfluxDB'de bir seri (series), measurement adı ile tag değerlerinin benzersiz kombinasyonudur. cpu,host=web01,region=istanbul ile cpu,host=web02,region=istanbul iki ayrı seridir. Toplam seri sayısına kardinalite denir ve InfluxDB'nin bellek kullanımını doğrudan belirleyen sayı budur; çünkü seri indeksi büyük ölçüde bellekte tutulur.

    Şimdi klasik felakete bakalım. Bir geliştirici, API isteklerini izlemek için request_id değerini tag olarak yazmaya başlar. Günde 2 milyon istek alıyorsanız, bir günde 2 milyon yeni seri üretmişsiniz demektir. Bellek kullanımı birkaç saat içinde tavan yapar, sorgular yavaşlar ve süreç OOM ile öldürülür. Aynı senaryo user_email, session_id, trace_id, hatta zaman damgasını tag'e yazan kodlar için de geçerlidir.

    Kural nettir: tag değeri sınırlı ve öngörülebilir bir kümeden gelmelidir. Sunucu adı, bölge, ortam, disk aygıtı, HTTP durum kodu, vhost adı iyi tag adaylarıdır. Benzersiz kimlikler ise ya field olarak yazılmalı ya da hiç yazılmamalıdır. Mevcut kardinalitenizi düzenli kontrol edin:

    // Bir bucket'taki toplam seri sayısı
    import "influxdata/influxdb"
    influxdb.cardinality(bucket: "metrics", start: -30d)
    
    Tag adayıOlası değer sayısıKarar
    hostSunucu sayısı kadarTag yap
    regionBirkaç bölgeTag yap
    http_statusOnlarca kodTag yap
    path (şablonlanmış)YüzlerceDikkatli, şablonla
    user_idMilyonlarcaAsla tag yapma
    request_idHer istekte yeniAsla tag yapma

    Sık Yapılan Diğer Hatalar#

    Kardinaliteden sonra en çok baş ağrıtan konu zaman damgası hassasiyetidir. InfluxDB varsayılan olarak nanosaniye bekler; siz saniye cinsinden zaman damgası gönderip precision parametresini belirtmezseniz verileriniz 1970'lerin başına düşer ve grafiklerde hiçbir şey görünmez. HTTP yazmalarında precision=s, precision=ms gibi bir parametre vermeyi alışkanlık hâline getirin.

    İkinci hata, token'ı her yere aynı yetkiyle dağıtmaktır. Kurulum sırasında üretilen operatör token'ı her şeyi yapabilir; onu Telegraf yapılandırmasına, uygulama koduna ve Grafana'ya kopyalamak, tek bir sızıntıyla tüm izleme altyapınızın silinmesi anlamına gelir. Yazma için yalnızca yazma yetkisi olan, okuma için yalnızca okuma yetkisi olan ayrı token'lar üretin ve bunları şifre üretici gibi araçlarla ürettiğiniz güçlü değerlerle birlikte gizli tutun.

    Üçüncüsü, yedeklemeyi hiç düşünmemektir. Metrik verisi "zaten yeniden üretilir" diye düşünülür ama kapasite planlaması, SLA raporlaması ve olay sonrası inceleme için geçmiş veriye ihtiyacınız olur. InfluxDB kendi yedekleme komutunu sunar:

    # Tüm bucket'ları dizine yedekle
    influx backup /yedek/influx-$(date +%F) --token "${INFLUX_TOKEN}"
    
    # Belirli bir bucket'ı geri yükle
    influx restore /yedek/influx-2026-08-25 --bucket metrics --token "${INFLUX_TOKEN}"
    

    Bu yedekleri tek bir diskte tutmak yeterli değildir; kopyaların nasıl dağıtılacağı konusunda veritabanları için 3-2-1 yedekleme stratejisi yazısındaki kurgu InfluxDB için de aynen geçerlidir.

    Sıkça Sorulan Sorular#

    InfluxDB ücretsiz mi#

    InfluxDB'nin açık kaynaklı sürümü ücretsizdir ve tek sunucu üzerinde sınırsız bucket, kullanıcı ve metrik ile çalışabilirsiniz. Ücretli olan taraf, kümeleme (clustering), yüksek erişilebilirlik ve yönetilen bulut hizmetidir. Küçük ve orta ölçekli bir altyapı için açık kaynaklı sürüm tek başına fazlasıyla yeterlidir; darboğaza girerseniz genellikle önce donanım ve kardinalite yönetimiyle çözersiniz, kümelemeye ihtiyaç duymanız çok daha ileri bir aşamadır.

    InfluxDB mi Prometheus mu kullanmalıyım#

    İkisi de zaman serisi verisi saklar ama toplama modelleri farklıdır. Prometheus hedeflerden veriyi kendisi çeker (pull), InfluxDB'ye ise veri gönderilir (push). Kısa ömürlü işler, IoT cihazları ve ağ üzerinden dışarıdan gelen metrikler için push modeli daha rahattır. Kubernetes ve servis keşfi ağırlıklı ortamlarda Prometheus'un çekme modeli daha doğal oturur. Uzun dönem saklama ihtiyacınız yüksekse InfluxDB'nin retention ve downsampling altyapısı avantaj sağlar.

    Kardinalite sorununu nasıl kontrol ederim#

    Öncelikle mevcut seri sayınızı influxdb.cardinality() fonksiyonuyla ölçün ve bunu haftalık takip edin; sayı düzenli olarak artıyorsa bir yerde sınırsız tag üretiliyordur. Ardından hangi measurement'ın kardinaliteyi büyüttüğünü measurement bazında ölçerek bulun. Suçluyu bulduğunuzda çözüm genellikle o tag'i field'a çevirmek ya da tamamen kaldırmaktır. Yazma tarafını düzelttikten sonra eski serilerin temizlenmesi için ilgili zaman aralığını silmeniz gerekebilir.

    Eski verileri otomatik silmek için ne yapmalıyım#

    Her bucket'ın bir saklama süresi (retention) vardır ve süresi dolan veriler arka planda otomatik silinir. Bucket'ı oluştururken --retention 30d gibi bir değer verin; süre belirtmezseniz veri sonsuza kadar saklanır. Uzun dönem grafik ihtiyacınız varsa ham veriyi kısa süre saklayın ve zamanlanmış bir görevle saatlik veya günlük özetleri ayrı bir bucket'a yazın. Bu ikili yapı hem disk kullanımını sabit tutar hem de geçmiş raporlamayı korur.

    Grafana ile InfluxDB'yi nasıl bağlarım#

    Grafana'da yeni bir veri kaynağı ekleyip InfluxDB'yi seçer, sorgu dili olarak Flux'ı işaretlersiniz. URL alanına InfluxDB adresini, kimlik doğrulama bölümüne organizasyon adını, varsayılan bucket'ı ve yalnızca okuma yetkisi olan bir API token'ı girersiniz. Bağlantıyı test ettikten sonra panolarda doğrudan Flux sorguları yazabilirsiniz. Grafana'ya operatör token'ı vermekten kaçının; okuma yetkili ayrı bir token üretmek dakikalar sürer ve olası bir sızıntının etkisini görüntülemeyle sınırlar.

    Yazma yaptığım hâlde veri neden görünmüyor#

    En sık üç sebep vardır. Birincisi zaman damgası hassasiyetidir: saniye cinsinden zaman damgası gönderip precision parametresini belirtmediyseniz veriler çok eski bir tarihe düşer ve varsayılan zaman aralığında görünmez. İkincisi field tipi çakışmasıdır; aynı alanı bir kez tam sayı bir kez ondalık yazarsanız sonraki yazmalar reddedilir. Üçüncüsü ise yanlış bucket ya da organizasyon adıdır. Yazma isteğinin HTTP durum kodunu mutlaka kontrol edin; 204 dışındaki her cevap size sorunun ne olduğunu söyler.

    Kapanış#

    InfluxDB, metrik verisini doğru araca vermenin en pratik yollarından biri; ama gücü de riski de aynı yerden geliyor: şemayı yazma anında siz belirliyorsunuz. Aklınızda kalması gereken dört alışkanlık şunlar: tag'leri yalnızca sınırlı değer kümeleri için kullanın ve benzersiz kimlikleri asla tag yapmayın; her bucket'a mutlaka bir retention süresi verin; ham veriyi kısa, özetlenmiş veriyi uzun süre saklayacak bir downsampling görevi kurun; ve yazma ile okuma için ayrı, dar yetkili token'lar üretin. Bu dördünü baştan doğru kurarsanız izleme altyapınız yıllarca bakım istemez.

    İzleme yığınını uygulama sunucunuzdan ayırmak istiyorsanız tam root erişimli VDS ya da esnek ölçeklenen bulut sunucu paketleri InfluxDB ve Telegraf için rahat bir ev olur. Kurulumu, güvenlik duvarı kurallarını ve yedek planını kendiniz üstlenmek istemiyorsanız sunucu yönetimi hizmetimiz bu işi devralabilir; metrik verinizin kopyalarını düzenli ve sınanmış biçimde saklamak içinse yedekleme çözümlerimize göz atabilirsiniz.

    InfluxDBZaman Serisiİzleme

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.