Makale

Zaman Serisi Veritabanları: Zaman İçinde Değişen Verileri Yönetme

Zaman Serisi Veritabanları: Zaman İçinde Değişen Verileri Yönetme

Bir zaman serisi veritabanı (TSDB), zamana göre indekslenen veri noktalarını (sensör okumaları, sunucu ölçümleri, uygulama günlükleri, finansal onay verileri ve IoT telemetrisi) depolamak ve sorgulamak için uzmanlaşmıştır. Zaman serisi verileri, geleneksel veritabanlarını optimalin altında kılan benzersiz özelliklere sahiptir:

3 dk okumaDil: TR TürkçeÜcretsiz0 alkış0 yorum
TeknolojiMühendislik MakaleleriTimeDatabasesTechnologyEngineering ArticlesSeries
Okuma seçenekleri

Giriş

Bir zaman serisi veritabanı (TSDB), zamana göre indekslenen veri noktalarını (sensör okumaları, sunucu ölçümleri, uygulama günlükleri, finansal onay verileri ve IoT telemetrisi) depolamak ve sorgulamak için uzmanlaşmıştır. Zaman serisi verileri, geleneksel veritabanlarını optimalin altında kılan benzersiz özelliklere sahiptir:

  • Yoğun yazma — Günde milyonlarca ila milyarlarca veri noktası.
  • Yalnızca ekleme — Veriler nadiren güncellenir, neredeyse her zaman eklenir.
  • Zaman sıralı — Sorgular her zaman bir zaman aralığı içerir.
  • Saklamaya dayalı — Eski veriler zamanla özetlenir veya silinir.
  • Altörneklenmiş — Daha eski veriler daha düşük çözünürlükte depolanır.

Zaman Serisi Veri Özellikleri

Veri Modeli

Her zaman serisi veri noktası şunları içerir:

Bileşen Örnek Açıklama
Zaman damgası 2026-05-24T14:30:00Z Ölçümün alındığı zaman
Değer 42.5 Ölçülen değer
Metrik cpu_usage Ne ölçülüyor
Etiketler/Etiketler ana bilgisayar=web01, bölge=abd-doğu Filtreleme için meta veriler
Metric: cpu_usage{host="web01", region="us-east"}
┌─────────────────────┬───────┐
│ Timestamp           │ Value │
├─────────────────────┼───────┤
│ 2026-05-24T14:30:00 │ 42.5  │
│ 2026-05-24T14:30:01 │ 43.2  │
│ 2026-05-24T14:30:02 │ 41.8  │
│ ...                 │ ...   │
└─────────────────────┴───────┘

Zaman Serisi ve Geleneksel Veritabanları

Operasyon PostgreSQL Zaman ÖlçeğiDB (PostgreSQL + TS) AkışDB (TSDB)
Yazma verimi 10.000 satır/sn 100K-1M satır/sn 1 milyonun üzerinde satır/sn
Sorgu: Ortalama 1 saat, 5 dakikaya kadar Dakika (tam tarama) Saniye (sürekli toplam) Saniye
Depolama Satır odaklı Hibrit satır/sütun Sütun odaklı
Sıkıştırma Varsayılan olarak yok %90+ (yerel sıkıştırma) 90%+
Saklama politikaları Manuel bölüm yönetimi Otomatik Otomatik
Veri altörnekleme Manuel sorgular Sürekli agregalar Sorguları altörnekleme
SQL desteği Tam Tam (SQL) Sınırlı (Akı/SQL)

Zaman Serisi Veritabanı Karşılaştırması

Özellik Zaman ÖlçeğiDB AkışDB Prometheus VictoriaMetrics GörevDB
Motor PostgreSQL uzantısı Özel TS motoru Özel çekme tabanlı Özel TS motoru Sütunlu
Sorgu dili SQL SQL/Akı PromQL PromQL uyumlu SQL + Akışı
Yuma oranı 1 milyon+/sn 1 milyon+/sn 500K/sn 1 milyon+/sn 2 milyon+/sn
Sıkıştırma %90-97 90+% Yok 90+% 90+%
Kümeleme Çok düğümlü (zaman ölçeklib) kurumsal Yerel parçalama Yerli Yok
Saklama Politikalarla otomatik Otomatik Yapılandırılabilir Yapılandırılabilir Manuel
Sürekli agregalar Evet (yerli) Hayır (ayrı görev) Kayıt kuralları Kayıt kuralları Hayır
Şunlar için en iyisi SQL kullanıcıları, operasyonel veriler Nesnelerin İnterneti, DevOps Kubernetes, Bulutta Yerel Yüksek ölçekli metrikler Finansal, yüksek hızlı

InfluxDB: Özel TSDB

Veri Modeli

# InfluxDB v3 — data model
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS

client = InfluxDBClient(url="http://localhost:8086", token="my-token")
write_api = client.write_api(write_options=SYNCHRONOUS)

# A point = measurement + tags + fields + timestamp
point = (
    Point("temperature")
    .tag("sensor", "sensor-001")
    .tag("location", "warehouse-a")
    .field("value", 23.5)
    .field("humidity", 65.2)
    .time(datetime.utcnow())
)

write_api.write(bucket="sensors", record=point)

Sorgulama

-- InfluxDB SQL (v3)
SELECT time, value
FROM temperature
WHERE sensor = 'sensor-001'
  AND time >= NOW() - INTERVAL '1 hour'
ORDER BY time DESC;

-- Aggregation with downsampling
SELECT time_bucket(INTERVAL '5 minutes', time) as bucket,
       AVG(value) as avg_temp,
       MAX(value) as max_temp,
       MIN(value) as min_temp
FROM temperature
WHERE location = 'warehouse-a'
  AND time >= NOW() - INTERVAL '24 hours'
GROUP BY bucket
ORDER BY bucket;

Saklama Politikaları

-- InfluxDB: automatic data lifecycle
CREATE RETENTION POLICY "one_hour"
ON "sensors"
DURATION 1h
REPLICATION 1
DEFAULT;

CREATE RETENTION POLICY "one_week"
ON "sensors"
DURATION 168h
REPLICATION 1;

-- Create downsample task
CREATE TASK "downsample_1h" ON "sensors"
  EVERY 1 HOUR
  BEGIN
    -- Aggregate 1-minute data to 1-hour averages
    SELECT time_bucket(INTERVAL '1 hour', time) as time,
           AVG(value) as value
    INTO "one_week"."temperature_hourly"
    FROM "one_hour"."temperature"
    WHERE time >= NOW() - INTERVAL '2 hours'
    GROUP BY 1, sensor, location;
  END;

Prometheus: Bulutta Yerel İzleme

Mimari (Çekme Modeli)

┌─────────────────────────────────────────────────┐
│              Prometheus Server                   │
│  ┌──────────┐  ┌──────────┐  ┌───────────────┐  │
│  │ Retrieval│  │ TSDB     │  │ Alertmanager  │  │
│  │ (pull)   │──│ (storage)│──│ (alerts)      │  │
│  └─────┬────┘  └──────────┘  └───────────────┘  │
│        │                                          │
└────────┼──────────────────────────────────────────┘
         │
    ┌────┼────────────┬──────────────┐
    ▼    ▼            ▼              ▼
  App  App   Node Exporter   Custom Exporter

PromQL (Prometheus Sorgu Dili)

# Basic queries
cpu_usage{host="web01"}
http_requests_total[5m]

# Rate (per-second average)
rate(http_requests_total[5m])

# Aggregation
avg by (host) (cpu_usage)

# Histogram quantile
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

# Predict linear regression
predict_linear(node_disk_free_bytes[1h], 3600) < 0

# Recording rule (pre-computed)
- record: job:http_requests:rate5m
  expr: rate(http_requests_total[5m])

Hizmet Keşfi ve Hedefler

# prometheus.yml
scrape_configs:
  - job_name: 'kubernetes-nodes'
    kubernetes_sd_configs:
      - role: node
    relabel_configs:
      - source_labels: [__meta_kubernetes_node_label_kubernetes_io_role]
        regex: control-plane
        action: drop

  - job_name: 'custom-app'
    static_configs:
      - targets: ['app01:8080', 'app02:8080', 'app03:8080']

TimescaleDB: Zaman Serileri için PostgreSQL

TimescaleDB, tam SQL uyumluluğunu korurken zaman serisi yetenekleri ekleyen PostgreSQL'in bir uzantısıdır.

Hipertablolar

-- Create a hypertable (automatically partitions by time)
CREATE TABLE temperature (
    time TIMESTAMPTZ NOT NULL,
    sensor_id INTEGER,
    location TEXT,
    value DOUBLE PRECISION,
    humidity DOUBLE PRECISION
);

-- Convert to hypertable (partitions by 1 day chunks)
SELECT create_hypertable('temperature', 'time',
    chunk_time_interval => INTERVAL '1 day');

-- Add partitioning by location (optional, for multi-node)
SELECT add_dimension('temperature', 'location', number_partitions => 4);

Sıkıştırma

-- Enable compression on hypertable
ALTER TABLE temperature SET (
    timescaledb.compress,
    timescaledb.compress_segmentby = 'sensor_id',
    timescaledb.compress_orderby = 'time DESC'
);

-- Compression policy: compress data older than 7 days
SELECT add_compression_policy('temperature', INTERVAL '7 days');

-- Compression ratio: 90-97%
-- 100GB of raw data → 3-10GB compressed

Sürekli Toplamalar (Gerçekleştirilmiş Görünümler)

-- Create 5-minute aggregates (refreshed every minute)
CREATE MATERIALIZED VIEW temperature_hourly
WITH (timescaledb.continuous) AS
SELECT time_bucket('5 minutes', time) as bucket,
       sensor_id,
       AVG(value) as avg_temp,
       MAX(value) as max_temp,
       MIN(value) as min_temp,
       stddev(value) as temp_stddev
FROM temperature
GROUP BY bucket, sensor_id;

-- Refresh policy
SELECT add_continuous_aggregate_policy('temperature_hourly',
    start_offset => INTERVAL '3 days',
    end_offset => INTERVAL '1 hour',
    schedule_interval => INTERVAL '1 minute');

Veri Saklama

-- Automatic data removal
SELECT add_retention_policy('temperature_raw', INTERVAL '30 days');
SELECT add_retention_policy('temperature_hourly', INTERVAL '1 year');
SELECT add_retention_policy('temperature_daily', INTERVAL '5 years');

Sorgu Kalıpları

Altörnekleme

-- Raw data: 1m intervals, kept 30 days
-- 5m average: kept 1 year
-- 1h average: kept 5 years

SELECT time_bucket('1 hour', time) as hour,
       AVG(value) as avg_temperature,
       PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY value) as p95
FROM temperature
WHERE time >= NOW() - INTERVAL '7 days'
GROUP BY hour
ORDER BY hour;

İnterpolasyon (Boşlukları Doldurma)

-- Fill missing data with linear interpolation
SELECT time_bucket('5 minutes', time) as bucket,
       INTERPOLATE(AVG(value)) as temperature
FROM temperature
WHERE sensor_id = 1
  AND time >= NOW() - INTERVAL '1 hour'
GROUP BY bucket
ORDER BY bucket;

-- Or use LAST observation carried forward (LOCF)
SELECT time_bucket('5 minutes', time) as bucket,
       LOCF(AVG(value)) as temperature
FROM temperature
GROUP BY bucket
ORDER BY bucket;

Anormallik Tespiti

-- Detect values outside 3 standard deviations
WITH stats AS (
    SELECT AVG(value) as mean,
           stddev(value) as sigma
    FROM temperature
    WHERE time >= NOW() - INTERVAL '24 hours'
)
SELECT time, value,
       (value - mean) / sigma as z_score
FROM temperature, stats
WHERE time >= NOW() - INTERVAL '1 hour'
  AND ABS((value - mean) / sigma) > 3
ORDER BY time;

Depolama ve Sıkıştırma

TSDB'ler Yüksek Sıkıştırmaya Nasıl Ulaşır?

Raw data layout (row-oriented):
time, sensor_id, location, value
14:30:00, 1, "room_a", 23.5
14:30:01, 1, "room_a", 23.6
14:30:02, 1, "room_a", 23.4
14:30:03, 1, "room_a", 23.7

Column-oriented + Delta encoding:
time:    14:30:00, +1s, +1s, +1s  → 1 value + 3 deltas
sensor_id: 1, 1, 1, 1 → run-length encoding: "1 × 4"
location: "room_a" × 4 → run-length encoding: "room_a × 4"
value: 23.5, +0.1, -0.2, +0.3 → delta encoding

Result: ~95% compression vs. raw text

Sıkıştırma Oranları

Veritabanı Ham Sıkıştırılmış Oran
Zaman ÖlçeğiDB 100GB 3-10GB %90-97
AkışDB 100GB 5-15GB %85-95
Prometheus 100GB 20-25GB %75-80
VictoriaMetrics 100GB 3-8GB %92-97

Kullanım Durumları

1. Altyapı İzleme

# Node exporter metrics collected every 15 seconds
metrics:
  - cpu_usage{host="web01", cpu="0"}
  - memory_used{host="web01", type="RAM"}
  - disk_io{host="web01", device="sda", type="read_bytes"}
  - network_bytes{host="web01", interface="eth0", direction="in"}
  - load_average{host="web01", duration="1m"}

storage:
  raw: 15s intervals, 7 days
  aggregated: 5m intervals, 30 days
  daily: 1h intervals, 1 year

2. IoT Sensör Verileri

# Millions of devices sending data every minute
from timescaledb import hypertable

sensors = hypertable('sensor_data', 'time',
    chunk_time='1 day',
    compression='7 days',
    retention='90 days'
)

# Query: average temperature per device per hour
query = """
    SELECT time_bucket('1 hour', time) as hour,
           device_id,
           AVG(temperature) as avg_temp,
           COUNT(*) as samples
    FROM sensor_data
    WHERE time >= NOW() - INTERVAL '24 hours'
    GROUP BY hour, device_id
"""

3. Mali Kene Verisi

-- Stock price ticks: 10M+ per day per instrument
CREATE TABLE ticks (
    time TIMESTAMPTZ NOT NULL,
    symbol TEXT NOT NULL,
    price DOUBLE PRECISION,
    volume BIGINT,
    bid DOUBLE PRECISION,
    ask DOUBLE PRECISION
);

SELECT create_hypertable('ticks', 'time',
    chunk_time_interval => INTERVAL '1 hour');

-- OHLC (Open-High-Low-Close) candlestick query
SELECT time_bucket('5 minutes', time) as bucket,
       symbol,
       FIRST(price, time) as open,
       MAX(price) as high,
       MIN(price) as low,
       LAST(price, time) as close,
       SUM(volume) as volume
FROM ticks
WHERE symbol = 'AAPL'
  AND time >= NOW() - INTERVAL '1 day'
GROUP BY bucket, symbol;

En İyi Uygulamalar

Şema Tasarımı

-- Good schema: separate metrics by table
CREATE TABLE cpu_usage (time TIMESTAMPTZ, host TEXT, value DOUBLE PRECISION);
CREATE TABLE memory_usage (time TIMESTAMPTZ, host TEXT, value DOUBLE PRECISION);

-- Avoid: single wide table with all metrics as columns
-- (leads to sparse data, poor compression)

Parça Boyutu Ayarı

-- Too small: too many partitions, slow queries
-- Too large: poor memory management, slow ingestion
-- Rule of thumb: each chunk should be 1-10GB compressed

-- For 1000 writes/sec, 1KB each = 86GB/day
-- 1 day chunks = 86GB (too large)
-- 6 hour chunks = 21GB (good)
SELECT set_chunk_time_interval('temperature', INTERVAL '6 hours');

Sonuç

Zaman serisi veritabanları, modern sistemlerin çoğunu ürettiği veriler için amaca yönelik olarak oluşturulmuştur: uygulamalardan, altyapıdan, IoT cihazlarından ve finansal piyasalardan alınan zaman damgalı ölçümler.

Kullanım Örneği Önerilen Veritabanı
Altyapı izleme (Kubernetes) Prometheus + VictoriaMetrics
SQL sorgularıyla IoT sensör verileri Zaman ÖlçeğiDB
Gerçek zamanlı analiz, DevOps AkışDB
Yüksek frekanslı finansal veriler GörevDB
Bulutta yerel, çekme tabanlı ölçümler Prometheus

Temel çıkarımlar:

  1. TSDB'ler yazma açısından optimize edilmiştir — tek bir düğümde saniyede 1 milyondan fazla veri noktasını işler.
  2. Yüksek sıkıştırma (%90+) — daha az maliyetle daha fazla veri depolayın.
  3. Otomatik veri yaşam döngüsü — saklama politikaları + alt örnekleme, depolama maliyetlerini azaltır.
  4. Mümkün olduğunda SQL desteği — TimescaleDB tam SQL uyumluluğu sağlar.
  5. Farklı ihtiyaçlar için farklı araçlar — Bulutta yerel için Prometheus, DevOps için InfluxDB, SQL konusunda uzman kullanıcılar için TimescaleDB.

Doğru zaman serisi mimarisi, verileri verimli bir şekilde alır, zarif bir şekilde yaşlandırır ve anında sorgulayarak ham zaman damgalı sayıları eyleme geçirilebilir içgörülere dönüştürür.

Öne Çıkan Makaleler

2026’da Oluşturmaya Değer 50 Claude Skill
EditoryalTR
8 dkÜcretsiz

2026’da Oluşturmaya Değer 50 Claude Skill

Claude Skills, tekrarlanan promptları yeniden kullanılabilir workflow’lara dönüştürebilir. İşte yazma, kodlama, araştırma, iş, üretkenlik, tasarım, analiz ve destek için 50 pratik Claude Skill.

TeknolojiAIAi GuidesAI Agents
0 alkış
Oku
Senior Engineer’lardan Öğrendiğim 6 Kodlama Pattern’i
EditoryalTR
8 dkÜcretsiz

Senior Engineer’lardan Öğrendiğim 6 Kodlama Pattern’i

TeknolojiCodeProgrammingCoding
0 alkış
Oku
Özel Bir Yapay Zeka Not Asistanı Kurun
Öne çıkanTR
9 dkÜcretsiz

Özel Bir Yapay Zeka Not Asistanı Kurun

Markdown notlarını özel taslakları açığa çıkarmadan aranabilir bir asistana dönüştürün.

TeknolojiPlatform RehberleriYapay Zeka YazımıAIAutomationData
0 alkış
Oku

Yorumlar

0 yorum

Henüz onaylı yorum yok. Yeni yanıtlar moderasyon bekleyebilir.