InfluxDB Performans Optimizasyonu ve Disk Yönetimi
Zaman serisi veritabanları söz konusu olduğunda InfluxDB, özellikle metrik toplama ve IoT senaryolarında çok güçlü bir seçenek. Ama ne yazık ki yanlış yapılandırılmış bir InfluxDB kurulumu zamanla ciddi performans sorunlarına yol açabiliyor. Disk dolmaya başlıyor, sorgular yavaşlıyor, retention policy’ler yanlış ayarlanmış oluyor ve bir gün gelip sistemi kurtarmaya çalışıyorsun. Bu yazıda gerçek dünya senaryolarından yola çıkarak InfluxDB’yi nasıl optimize edeceğini ve disk yönetimini nasıl yapacağını ele alacağız.
InfluxDB’nin Depolama Mimarisini Anlamak
Optimizasyon yapmadan önce InfluxDB’nin veriyi nasıl sakladığını anlamak gerekiyor. InfluxDB, TSM (Time-Structured Merge Tree) adlı bir depolama motoru kullanıyor. Bu motor önce WAL (Write-Ahead Log) dosyalarına yazıyor, ardından bu veriler TSM dosyalarına compaction işlemiyle taşınıyor.
Varsayılan veri dizini şu şekilde görünür:
# InfluxDB veri dizin yapısını inceleyelim
ls -lh /var/lib/influxdb/
# Çıktı genellikle şu şekildedir:
# data/ -> TSM dosyaları
# wal/ -> Write-Ahead Log dosyaları
# meta/ -> Metadata (retention policies, users vb.)
# Disk kullanımını detaylı görmek için
du -sh /var/lib/influxdb/*
du -sh /var/lib/influxdb/data/*
WAL dosyaları, henüz compaction işleminden geçmemiş ham verilerdir. Sistem aniden çökerse bu dosyalar sayesinde veri kaybetmezsin. Ancak WAL dosyaları çok büyürse bu bir sorun işareti.
Temel Konfigürasyon Dosyasını Optimize Etmek
InfluxDB’nin kalbi /etc/influxdb/influxdb.conf dosyasında atıyor. Pek çok sysadmin bu dosyayı varsayılan haliyle bırakıyor, bu da ciddi sorunlara yol açıyor.
# Mevcut konfigürasyonu yedekle
cp /etc/influxdb/influxdb.conf /etc/influxdb/influxdb.conf.bak
# Konfigürasyonu düzenle
nano /etc/influxdb/influxdb.conf
Kritik parametreler ve açıklamaları:
[data] bölümü için önerilen ayarlar:
- cache-max-memory-size: In-memory cache için maksimum bellek. Varsayılan 1GB’dır, yüksek yazma trafiğinde artırılmalı
- cache-snapshot-memory-size: Cache bu değere ulaşınca diske yazılır. 25MB-100MB arası makul
- cache-snapshot-write-cold-duration: Son yazma işleminin üzerinden bu kadar süre geçince snapshot alınır
- compact-full-write-cold-duration: Tam compaction için bekleme süresi
- max-series-per-database: Veritabanı başına maksimum seri sayısı, cardinality kontrolü için kritik
# influxdb.conf içindeki [data] bölümü örneği
cat >> /etc/influxdb/influxdb.conf << 'EOF'
[data]
dir = "/var/lib/influxdb/data"
wal-dir = "/var/lib/influxdb/wal"
# Yüksek yazma yükü için cache ayarları
cache-max-memory-size = 2147483648 # 2GB
cache-snapshot-memory-size = 52428800 # 50MB
cache-snapshot-write-cold-duration = "10m"
# Compaction agresifliği
compact-full-write-cold-duration = "4h"
max-concurrent-compactions = 4
# Serisi yüksek olan senaryolar için
max-series-per-database = 3000000
# TSM index tipi (tsi1 disk bazlı, inmem bellek bazlı)
index-version = "tsi1"
EOF
index-version parametresi çok önemli. Eğer çok sayıda seri (high cardinality) varsa tsi1 kullanmak zorundasın. inmem index tüm indexi RAM’de tutuyor ve millions of series söz konusu olduğunda belleği bitirebilir.
WAL Dizinini Ayrı Bir Diske Taşımak
Gerçek dünyada en sık yaptığım optimizasyonlardan biri WAL dizinini SSD’ye, data dizinini ise kapasiteli ama daha yavaş bir diske taşımak. WAL sürekli yazma yapıyor, data dizini ise daha çok okuma/compaction işlemi görüyor.
# Önce servisi durdur
systemctl stop influxdb
# Yeni WAL dizinini oluştur (örneğin NVMe SSD'de)
mkdir -p /mnt/nvme/influxdb/wal
chown -R influxdb:influxdb /mnt/nvme/influxdb/
# Mevcut WAL dosyalarını taşı
mv /var/lib/influxdb/wal/* /mnt/nvme/influxdb/wal/
# influxdb.conf'u güncelle
sed -i 's|wal-dir = "/var/lib/influxdb/wal"|wal-dir = "/mnt/nvme/influxdb/wal"|'
/etc/influxdb/influxdb.conf
# Servisi başlat ve kontrol et
systemctl start influxdb
systemctl status influxdb
# Log'ları izle
journalctl -u influxdb -f
Bu basit değişiklik yüksek yazma trafiğinde çok ciddi performans farkı yaratıyor. Özellikle Telegraf ile binlerce metriği saniye başı toplayan senaryolarda fark gece ile gündüz arasındaki kadar belirgin oluyor.
Retention Policy Yönetimi ve Otomatik Temizlik
InfluxDB’de veri birikiminin önüne geçmenin en temiz yolu retention policy’leri doğru yapılandırmak. Çok fazla kişinin bu adımı atladığını görüyorum ve sonuçta disk dolup sistem çöküyor.
# InfluxDB CLI'ya bağlan (InfluxDB 1.x için)
influx -host localhost -port 8086
# Mevcut retention policy'leri listele
SHOW RETENTION POLICIES ON "telegraf"
# Yeni bir retention policy oluştur (30 günlük saklama)
CREATE RETENTION POLICY "30_days" ON "telegraf"
DURATION 30d REPLICATION 1 DEFAULT
# Varolan policy'yi güncelle
ALTER RETENTION POLICY "autogen" ON "telegraf"
DURATION 90d REPLICATION 1
# Shard duration'ı da optimize et (yüksek yazma için)
CREATE RETENTION POLICY "metrics_1week" ON "telegraf"
DURATION 7d REPLICATION 1 SHARD DURATION 1d DEFAULT
Shard duration performans açısından kritik bir parametre. InfluxDB her shard’ı ayrı bir dosya grubu olarak yönetiyor. Shard duration çok uzunsa tek bir dosya grubu devasa büyüyor, çok kısaysa çok fazla dosya oluşuyor ve compaction maliyeti artıyor.
Genel kural olarak:
- 1 haftadan kısa retention: 1 saatlik shard duration
- 1 ay retention: 1 günlük shard duration
- 6 ay ve üzeri retention: 1 haftalık shard duration
Cardinality Sorununu Tespit Etmek ve Çözmek
High cardinality, InfluxDB’nin en yaygın performans katilidir. Cardinality, bir measurement içindeki unique tag kombinasyonlarının sayısıdır. Kubernetes ortamlarında pod ID’lerini veya UUID’leri tag olarak kullanmak buna klasik bir örnek.
# Cardinality'yi kontrol et (InfluxDB CLI)
influx -execute "SHOW SERIES CARDINALITY ON telegraf"
# Measurement bazlı cardinality
influx -execute "SHOW MEASUREMENT CARDINALITY ON telegraf"
# Sorunlu tag'leri bul
influx -execute "SHOW TAG KEYS ON telegraf FROM cpu"
influx -execute "SHOW TAG VALUES ON telegraf FROM cpu WITH KEY = host"
# Cardinality'yi HTTP API ile de kontrol edebilirsin
curl -G 'http://localhost:8086/query'
--data-urlencode "q=SHOW SERIES CARDINALITY ON telegraf"
--data-urlencode "db=telegraf" | python3 -m json.tool
Eğer bir measurement’ta millions of series varsa, önce hangi tag’lerin buna yol açtığını bul. Ardından ya o tag’leri kaldır ya da field’a dönüştür. Tag’ler indexleniyor, field’lar indexlenmiyor. Yani UUID gibi yüksek cardinality’li değerler field olarak saklanmalı.
Disk Kullanımını İzlemek ve Yönetmek
Disk yönetimi için önce mevcut durumu net görmek gerekiyor. Bunu yapan basit ama etkili bir script yazalım:
#!/bin/bash
# influxdb_disk_monitor.sh
# InfluxDB disk kullanımını izler ve uyarı verir
INFLUX_DATA_DIR="/var/lib/influxdb"
ALERT_THRESHOLD=80 # Yüzde olarak uyarı eşiği
LOG_FILE="/var/log/influxdb_disk_monitor.log"
EMAIL="[email protected]"
check_disk_usage() {
local dir=$1
local usage=$(df -h "$dir" | awk 'NR==2 {gsub(/%/,""); print $5}')
echo "$usage"
}
get_influx_stats() {
echo "=== InfluxDB Disk Kullanım Raporu ===" >> "$LOG_FILE"
echo "Tarih: $(date)" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
echo "Toplam veri dizini boyutu:" >> "$LOG_FILE"
du -sh "$INFLUX_DATA_DIR/data" >> "$LOG_FILE"
echo "WAL dizini boyutu:" >> "$LOG_FILE"
du -sh "$INFLUX_DATA_DIR/wal" >> "$LOG_FILE"
echo "Veritabanı bazlı boyutlar:" >> "$LOG_FILE"
du -sh "$INFLUX_DATA_DIR/data/"* >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
}
disk_usage=$(check_disk_usage "$INFLUX_DATA_DIR")
get_influx_stats
if [ "$disk_usage" -gt "$ALERT_THRESHOLD" ]; then
echo "UYARI: InfluxDB disk kullanımı %$disk_usage seviyesinde!" |
mail -s "InfluxDB Disk Uyarısı" "$EMAIL"
echo "UYARI gönderildi: %$disk_usage" >> "$LOG_FILE"
fi
# Crontab'a ekle: */30 * * * * /usr/local/bin/influxdb_disk_monitor.sh
# Script'i çalıştırılabilir yap ve cron'a ekle
chmod +x /usr/local/bin/influxdb_disk_monitor.sh
echo "*/30 * * * * root /usr/local/bin/influxdb_disk_monitor.sh" >> /etc/cron.d/influxdb-monitor
Compaction İşlemlerini Yönetmek
Compaction, TSM dosyalarını birleştirerek disk alanı kazandıran ve okuma performansını artıran bir işlem. Ancak yoğun saatlerde compaction hem CPU hem disk I/O tüketebilir.
# Mevcut compaction durumunu HTTP API ile kontrol et
curl -s http://localhost:8086/debug/vars |
python3 -c "
import json, sys
data = json.load(sys.stdin)
for key in data:
if 'compaction' in key.lower():
print(f'{key}: {data[key]}')
"
# InfluxDB istatistiklerini izle
influx -execute "SHOW STATS" | grep -i compact
# Belirli bir veritabanı için shard bilgisi
influx -execute "SHOW SHARDS" | head -30
Compaction ayarlarını optimize etmek için şu yaklaşımı uygulayabilirsin:
- max-concurrent-compactions: Paralel compaction işlemi sayısı. CPU core sayısının yarısı makul bir başlangıç
- compact-throughput: Compaction işleminin disk yazma hızı limiti. Yoğun ortamlarda yazma trafiğini boğmaması için sınırla
- compact-throughput-burst: Kısa süreli burst limiti
Sorgu Performansını Artırmak
Yavaş sorgular çoğu zaman yanlış yazılmış Flux veya InfluxQL sorgularından kaynaklanıyor. En yaygın hatalar şunlar:
- Çok geniş zaman aralığı seçmek
- Tag yerine field üzerinden filtreleme yapmak
- GROUP BY olmadan aggregate kullanmak
# Yavaş sorguları log'larda tespit etmek için
grep -i "slow" /var/log/influxdb/influxdb.log
# influxdb.conf'ta slow query log'u aktif et
cat >> /etc/influxdb/influxdb.conf << 'EOF'
[coordinator]
# 10 saniyeden uzun sorguları logla
log-queries-after = "10s"
max-select-point = 0
max-select-series = 0
max-select-buckets = 0
EOF
# Sorgu optimizasyonu örneği - Kötü sorgu:
# SELECT * FROM cpu WHERE host='web01' (zaman aralığı yok!)
# İyi sorgu - son 1 saat, specific tag filtresi:
influx -execute "SELECT mean(usage_idle) FROM cpu
WHERE host='web01' AND time > now() - 1h
GROUP BY time(1m)"
# Continuous Query ile önceden aggregate et (1.x için)
influx -execute "
CREATE CONTINUOUS QUERY cq_cpu_1h ON telegraf
BEGIN
SELECT mean(usage_idle) INTO cpu_hourly
FROM cpu GROUP BY time(1h), host
END"
Backup ve Restore Stratejisi
Disk optimizasyonu yaparken backup’ı ihmal etmek büyük risk. InfluxDB’nin kendi backup mekanizmasını ve bunu otomatize eden bir script görelim:
#!/bin/bash
# influxdb_backup.sh
# Günlük InfluxDB backup script'i
BACKUP_BASE_DIR="/backup/influxdb"
INFLUX_HOST="localhost"
INFLUX_PORT="8086"
RETENTION_DAYS=7
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="$BACKUP_BASE_DIR/$DATE"
# Backup dizinini oluştur
mkdir -p "$BACKUP_DIR"
echo "[$(date)] Backup başlıyor: $BACKUP_DIR"
# Tüm veritabanlarını listele ve backup al
databases=$(influx -host "$INFLUX_HOST" -port "$INFLUX_PORT"
-execute "SHOW DATABASES" -format csv | grep -v "name,name" |
grep -v "_internal" | cut -d',' -f2)
for db in $databases; do
echo "[$(date)] $db veritabanı backup alınıyor..."
influxd backup
-portable
-host "$INFLUX_HOST:$INFLUX_PORT"
-database "$db"
"$BACKUP_DIR/$db"
if [ $? -eq 0 ]; then
echo "[$(date)] $db backup başarılı"
else
echo "[$(date)] HATA: $db backup başarısız!"
fi
done
# Backup'ı sıkıştır
tar -czf "$BACKUP_BASE_DIR/${DATE}_influxdb_backup.tar.gz"
-C "$BACKUP_BASE_DIR" "$DATE"
rm -rf "$BACKUP_DIR"
# Eski backup'ları temizle
find "$BACKUP_BASE_DIR" -name "*.tar.gz" -mtime +"$RETENTION_DAYS" -delete
echo "[$(date)] Backup tamamlandı: ${DATE}_influxdb_backup.tar.gz"
echo "[$(date)] Backup boyutu: $(du -sh $BACKUP_BASE_DIR/${DATE}_influxdb_backup.tar.gz | cut -f1)"
# Restore için: influxd restore -portable -host localhost:8086 /backup/dizin
# Script'i günlük gece 02:00'de çalıştır
chmod +x /usr/local/bin/influxdb_backup.sh
echo "0 2 * * * root /usr/local/bin/influxdb_backup.sh >> /var/log/influxdb_backup.log 2>&1"
>> /etc/cron.d/influxdb-backup
Sistem Kaynaklarını InfluxDB İçin Optimize Etmek
InfluxDB’yi Linux üzerinde maksimum performansla çalıştırmak için işletim sistemi seviyesinde de birkaç ayar yapmak gerekiyor.
# Açık dosya limiti kontrolü ve artırma
ulimit -n
cat /proc/$(pgrep influxd)/limits | grep "open files"
# /etc/security/limits.conf'a ekle
cat >> /etc/security/limits.conf << 'EOF'
influxdb soft nofile 65536
influxdb hard nofile 65536
EOF
# systemd servis limitlerini de güncelle
mkdir -p /etc/systemd/system/influxdb.service.d/
cat > /etc/systemd/system/influxdb.service.d/limits.conf << 'EOF'
[Service]
LimitNOFILE=65536
LimitNPROC=65536
EOF
# Swappiness'i azalt (time series DB için önemli)
echo "vm.swappiness=10" >> /etc/sysctl.conf
# Dirty ratio ayarları (yazma performansı için)
echo "vm.dirty_ratio=15" >> /etc/sysctl.conf
echo "vm.dirty_background_ratio=5" >> /etc/sysctl.conf
# Değişiklikleri uygula
sysctl -p
# Servisi yeniden başlat
systemctl daemon-reload
systemctl restart influxdb
Neden bu ayarlar önemli?
- nofile limiti: InfluxDB çok sayıda TSM dosyası açıyor. Default 1024 limiti yetersiz kalıyor
- vm.swappiness=10: Bellek baskısı altında bile mümkün oldukça swap kullanmadan çalışmasını sağlıyor. Swap’a düşen InfluxDB felç oluyor
- dirty ratio: Kernel’in ne kadar dirty page biriktirebileceğini ve ne zaman diske yazacağını kontrol ediyor
Monitoring ve Alerting Kurulumu
Optimize ettiğin sistemin sağlıklı çalışıp çalışmadığını izlemek için InfluxDB’nin kendi /debug/vars endpoint’ini kullanabilirsin. Telegraf ile bu metrikleri toplayıp Grafana’da görselleştirmek en yaygın yaklaşım.
# Telegraf'ın InfluxDB'yi izlemesi için konfigürasyon
cat > /etc/telegraf/telegraf.d/influxdb_monitoring.conf << 'EOF'
[[inputs.influxdb]]
urls = ["http://localhost:8086/debug/vars"]
timeout = "5s"
[[inputs.internal]]
collect_memstats = false
EOF
# Kritik metrikleri sorgula
curl -s http://localhost:8086/debug/vars | python3 -c "
import json, sys
data = json.load(sys.stdin)
# Write istatistikleri
if 'write' in data:
print('Write istatistikleri:')
for k, v in data['write']['values'].items():
print(f' {k}: {v}')
# Memory kullanımı
if 'memstats' in data:
memstats = data['memstats']['values']
heap_mb = memstats.get('HeapInuse', 0) / 1024 / 1024
print(f'Heap kullanımı: {heap_mb:.2f} MB')
"
Yaygın Sorunlar ve Hızlı Çözümler
Sahada en çok karşılaştığım sorunları ve çözümlerini şöyle özetleyebilirim:
Disk doldu, servis ayağa kalkmıyor:
# Önce acil alan aç
systemctl stop influxdb
# Eski WAL dosyalarını temizle (dikkatli ol, veri kaybı olabilir)
find /var/lib/influxdb/wal -name "*.wal" -mtime +1 -delete
# Ya da geçici dosyaları temizle
find /tmp -name "influx*" -delete
# Servisi başlat
systemctl start influxdb
# Hemen retention policy oluştur
influx -execute "ALTER RETENTION POLICY autogen ON telegraf DURATION 7d"
Compaction dondu, disk I/O yüzde yüz:
- Compaction’ı geçici olarak yavaşlat:
compact-throughputdeğerini düşür max-concurrent-compactionsdeğerini 1’e indir- Servisi restart etmek çoğu zaman çözüyor çünkü compaction sıfırlanıyor
Memory sürekli artıyor:
cache-max-memory-sizedeğerini kontrol etindex-version = "tsi1"kullandığından emin ol- Cardinality patlaması olup olmadığını kontrol et
Sonuç
InfluxDB optimizasyonu tek seferlik bir iş değil, sürekli takip gerektiren bir süreç. Özellikle şu noktalara odaklanmak gerekiyor:
- WAL ve data dizinlerini farklı disk türlerine ayırmak büyük fark yaratıyor
- Retention policy’leri baştan doğru kurmak disk dolma krizlerini önlüyor
- Cardinality kontrolü yapılmazsa sistemin belleği ve performansı zamanla çöküyor
- OS seviyesi ayarlar (nofile limiti, swappiness) çoğu zaman göz ardı ediliyor ama kritik
- Düzenli backup olmadan optimizasyon yapmak riskli
Bu yazıdaki scriptleri ve ayarları kendi ortamınıza göre uyarlayın. Her sistemin yazma/okuma yükü farklı, bu yüzden parametreleri deneme yanılma yöntemiyle fine-tune etmek kaçınılmaz. Ama doğru temeli attıktan sonra InfluxDB gerçekten çok stabil ve performanslı çalışıyor.
