SiamCafe · Blog
QuestDB Time Series Progressive Delivery —
บทความ

QuestDB Time Series Progressive Delivery —

เผยแพร่ 28 พฤษภาคม 2569

QuestDB Progressive Delivery

QuestDB Time Series Database Progressive Delivery Canary Blue-Green SQL InfluxDB Line Protocol Grafana Metrics Monitoring

FeatureQuestDBInfluxDBTimescaleDBPrometheus
Query LanguageSQLInfluxQL/FluxSQLPromQL
Ingestion Speed1M+ rows/s300K rows/s200K rows/s100K samples/s
StorageMemory-mappedTSM EnginePostgreSQLCustom TSDB
GrafanaPostgreSQL DSNative DSPostgreSQL DSNative DS
LicenseApache 2.0MIT (OSS)Apache 2.0Apache 2.0

QuestDB Setup & Query

# === QuestDB Setup and Time Series Queries ===

# Docker Installation
# docker run -p 9000:9000 -p 9009:9009 -p 8812:8812 questdb/questdb

# Create Table for Deployment Metrics
# CREATE TABLE deployment_metrics (
#     timestamp TIMESTAMP,
#     service SYMBOL,
#     version SYMBOL,
#     environment SYMBOL,
#     latency_ms DOUBLE,
#     error_rate DOUBLE,
#     throughput DOUBLE,
#     cpu_percent DOUBLE,
#     memory_mb DOUBLE
# ) timestamp(timestamp) PARTITION BY DAY WAL;

# Insert via InfluxDB Line Protocol (TCP 9009)
# deployment_metrics, service=api, version=v2.1-canary, environment=prod latency_ms=45.2, error_rate=0.01, throughput=1500 1700000000000000000

# Canary vs Stable Comparison Query
# SELECT
#     version,
#     avg(latency_ms) as avg_latency,
#     max(latency_ms) as p99_latency,
#     avg(error_rate) as avg_error_rate,
#     avg(throughput) as avg_throughput
# FROM deployment_metrics
# WHERE timestamp > now() - 30m
#   AND service = 'api'
# GROUP BY version;

# Time-bucketed Analysis with SAMPLE BY
# SELECT
#     timestamp,
#     version,
#     avg(latency_ms) as avg_latency,
#     avg(error_rate) as avg_error_rate
# FROM deployment_metrics
# WHERE timestamp > now() - 1h
#   AND service = 'api'
# SAMPLE BY 1m ALIGN TO CALENDAR;

from dataclasses import dataclass

@dataclass
class QueryExample:
    name: str
    sql: str
    purpose: str
    use_case: str

queries = [
    QueryExample("Canary vs Stable",
        "SELECT version, avg(latency_ms), avg(error_rate) "
        "FROM metrics WHERE timestamp > now()-30m GROUP BY version",
        "เปรียบเทียบ Performance ระหว่าง Version",
        "ตัดสินใจ Promote หรือ Rollback"),
    QueryExample("Time Bucketed",
        "SELECT timestamp, avg(latency_ms) FROM metrics "
        "SAMPLE BY 1m ALIGN TO CALENDAR",
        "ดู Trend ทุก 1 นาที",
        "Grafana Dashboard Time Series Panel"),
    QueryExample("Latest Value per Service",
        "SELECT * FROM metrics LATEST ON timestamp "
        "PARTITION BY service",
        "ดูค่าล่าสุดของแต่ละ Service",
        "Status Dashboard Current Value"),
    QueryExample("Percentile Analysis",
        "SELECT version, "
        "percentile_disc(0.99) WITHIN GROUP (ORDER BY latency_ms) as p99 "
        "FROM metrics WHERE timestamp > now()-1h GROUP BY version",
        "ดู P99 Latency แต่ละ Version",
        "SLA Monitoring"),
]

print("=== Query Examples ===")
for q in queries:
    print(f"\n  [{q.name}]")
    print(f"    SQL: {q.sql}")
    print(f"    Purpose: {q.purpose}")
    print(f"    Use: {q.use_case}")

Progressive Delivery Pipeline

# === Progressive Delivery with QuestDB Metrics ===

@dataclass
class DeliveryStage:
    stage: str
    traffic_split: str
    duration: str
    success_criteria: str
    action_on_fail: str

stages = [
    DeliveryStage("Deploy Canary (1%)",
        "Stable 99% / Canary 1%",
        "10 นาที",
        "Error Rate < 1% AND P99 Latency < 200ms",
        "Rollback ทันที"),
    DeliveryStage("Increase to 10%",
        "Stable 90% / Canary 10%",
        "15 นาที",
        "Error Rate < 0.5% AND P99 < 150ms AND Throughput > 90%",
        "Rollback to 1% หรือ Full Rollback"),
    DeliveryStage("Increase to 50%",
        "Stable 50% / Canary 50%",
        "30 นาที",
        "Error Rate < 0.1% AND P99 < 120ms AND No Alerts",
        "Rollback to 10%"),
    DeliveryStage("Full Promotion (100%)",
        "Canary 100% (ตอนนี้เป็น Stable ใหม่)",
        "Monitor 1 ชั่วโมง",
        "All Metrics Normal AND No Customer Complaints",
        "Rollback to Old Stable"),
    DeliveryStage("Cleanup",
        "ลบ Old Stable Pods",
        "ทันที",
        "New Version ทำงานปกติ 1 ชั่วโมง+",
        "Keep Old Stable ไว้ 24 ชั่วโมง Just in Case"),
]

print("=== Delivery Stages ===")
for s in stages:
    print(f"\n  [{s.stage}] Traffic: {s.traffic_split}")
    print(f"    Duration: {s.duration}")
    print(f"    Success: {s.success_criteria}")
    print(f"    Fail: {s.action_on_fail}")

Grafana Integration

# === Grafana Dashboard for Progressive Delivery ===

@dataclass
class GrafanaPanel:
    panel: str
    query: str
    visualization: str
    alert: str

panels = [
    GrafanaPanel("Latency Comparison",
        "SELECT timestamp, version, avg(latency_ms) "
        "FROM metrics SAMPLE BY 1m",
        "Time Series (2 lines: canary vs stable)",
        "Canary P99 > Stable P99 × 1.5 → Alert"),
    GrafanaPanel("Error Rate Comparison",
        "SELECT timestamp, version, avg(error_rate)*100 "
        "FROM metrics SAMPLE BY 1m",
        "Time Series (2 lines: canary vs stable)",
        "Canary Error > 1% → Alert"),
    GrafanaPanel("Traffic Split",
        "SELECT version, count(*) FROM metrics "
        "WHERE timestamp > now()-5m GROUP BY version",
        "Pie Chart (Canary % vs Stable %)",
        "Traffic Split ≠ Expected → Alert"),
    GrafanaPanel("Throughput",
        "SELECT timestamp, version, avg(throughput) "
        "FROM metrics SAMPLE BY 1m",
        "Time Series",
        "Canary Throughput < Stable × 0.8 → Alert"),
    GrafanaPanel("Resource Usage",
        "SELECT timestamp, version, avg(cpu_percent), avg(memory_mb) "
        "FROM metrics SAMPLE BY 5m",
        "Time Series (CPU + Memory)",
        "CPU > 80% OR Memory > 90% → Alert"),
]

print("=== Grafana Panels ===")
for p in panels:
    print(f"  [{p.panel}]")
    print(f"    Query: {p.query}")
    print(f"    Viz: {p.visualization}")
    print(f"    Alert: {p.alert}")

เคล็ดลับ

  • SAMPLE BY: ใช้ SAMPLE BY สำหรับ Time Aggregation เร็วกว่า GROUP BY
  • LATEST ON: ใช้ LATEST ON สำหรับ Latest Value ต่อ Symbol
  • Line Protocol: ใช้ InfluxDB Line Protocol TCP 9009 สำหรับ High Throughput
  • Partition: PARTITION BY DAY สำหรับ Metrics ที่เก็บหลายเดือน
  • Grafana: ใช้ PostgreSQL Data Source port 8812 เชื่อม QuestDB

QuestDB คืออะไร

Open Source Time Series Database SQL 1M+ rows/second Memory-mapped InfluxDB Line Protocol PostgreSQL Wire Grafana IoT Finance DevOps

อ่านเพิ่ม: Monitoring คืออะไร? สอน Observability ตั้งแต่ Prometheus Gra · อ่านเพิ่ม: Prometheus และ Grafana คืออะไร? สอนสร้าง Monitoring Stack สำ · อ่านเพิ่ม: Apache Kafka เจาะลึก สอน Kafka Streams, Connect, Schema Regi