📡 Obs · Zero→Hero
หน้าแรก/📈 2 · Metrics/สถาปัตยกรรม Prometheus
📖 บทเรียน⏱ ~14 นาที

สถาปัตยกรรม Prometheus

Prometheus คือ de-facto standard ของ metrics ในโลก cloud-native (เป็นโปรเจกต์ที่ graduate จาก CNCF ตัวที่ 2 ต่อจาก Kubernetes) บทนี้เจาะว่ามันทำงานยังไงข้างใน ก่อนจะลงมือใน lab

ภาพรวม: ทุกอย่างหมุนรอบ "pull"

┌──────────────┐   scrape (HTTP GET /metrics)   ┌─────────────┐
│  Prometheus  │ ──────────────────────────────▶│  Target A   │  (แอปคุณ)
│   Server     │ ──────────────────────────────▶│  Target B   │  (node_exporter)
│              │ ──────────────────────────────▶│  Target C   │  (cAdvisor)
│  ┌────────┐  │                                 └─────────────┘
│  │  TSDB  │  │  เก็บลง time series database
│  └────────┘  │
│      │       │  PromQL
│      ▼       │ ◀──────── Grafana / API (query)
│  Alerting    │ ──push──▶ Alertmanager ──▶ Slack/PagerDuty
└──────────────┘

หัวใจคือ Prometheus ไปดึง (pull) metric จาก target เอง ไม่ใช่ให้ target ส่ง (push) เข้ามา

Pull model — ทำไมถึงดึงแทนที่จะให้ push

target แต่ละตัวเปิด HTTP endpoint (ปกติ /metrics) ที่ return metric เป็น text ธรรมดา Prometheus ก็ไป GET ทุกๆ ช่วง (scrape interval, เช่น 15s)

ลอง curl ดูจะเห็นแบบนี้:

# HELP http_requests_total Total HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="GET",status="200"} 1027
http_requests_total{method="POST",status="500"} 3
process_resident_memory_bytes 4.19e+07

ข้อดีของ pull:

ข้อดี อธิบาย
รู้ว่า target ตายไหม ถ้า scrape ไม่ได้ = target down ทันที (metric up=0) — push model ไม่รู้ความต่างระหว่าง "ปกติแต่เงียบ" กับ "ตาย"
ควบคุมโหลดที่ตัวเอง Prometheus กำหนดจังหวะ scrape เอง target ไม่ถล่มมันด้วยการ push รัวๆ
target เรียบง่าย target แค่เปิด endpoint ไม่ต้องรู้จัก Prometheus ไม่ต้อง config ปลายทาง
debug ง่าย เปิด /metrics ด้วย browser/curl ดูค่าดิบได้เลย

แล้วงานที่อยู่แป๊บเดียวล่ะ (batch job/cron) ที่จบก่อน Prometheus มา scrape? กรณีนั้นใช้ Pushgateway ให้ job push ค่าไปพักไว้ แล้ว Prometheus มา scrape จาก Pushgateway อีกที — เป็นข้อยกเว้น ไม่ใช่ค่า default

Service Discovery — หา target อัตโนมัติ

ในระบบที่ pod เกิด-ดับตลอด (k8s, cloud) คุณ hardcode รายชื่อ target ไม่ไหว Prometheus จึงมี service discovery ที่ถาม k8s/Consul/EC2 ว่า "ตอนนี้มี target อะไรบ้าง" แล้วอัปเดต target list เองอัตโนมัติ

scrape_configs:
  - job_name: 'my-app'
    static_configs:              # แบบง่าย: ระบุตรงๆ
      - targets: ['app:3000']

  - job_name: 'kubernetes-pods'  # แบบ dynamic: ถาม k8s
    kubernetes_sd_configs:
      - role: pod

TSDB — เก็บข้อมูลยังไงให้เล็กและเร็ว

Prometheus มี Time Series Database (TSDB) ของตัวเอง ออกแบบมาเพื่อ metric โดยเฉพาะ:

  • ข้อมูลใหม่เข้ามาเก็บใน memory (head block) ก่อน + เขียน WAL (write-ahead log) กันข้อมูลหายตอน crash
  • ทุก 2 ชั่วโมงยุบเป็น block เขียนลง disk (immutable)
  • ใช้ compression เก่งมาก — ต่อ 1 sample เก็บเฉลี่ยแค่ ~1-2 bytes (เพราะ timestamp เดินสม่ำเสมอ + ค่าใกล้เคียงกัน)

ความเล็กนี่แหละที่ทำให้ metric เก็บได้เป็นปีในราคาถูก — ต่างจาก log ที่ใหญ่กว่าเป็นพันเท่า จำเรื่องนี้จากบทที่ 01 ได้ไหม? นี่คือเหตุผลทางเทคนิคว่าทำไม metric ถึงถูก

ส่วนประกอบของ ecosystem

Prometheus ไม่ได้มาตัวเดียว มักมากับเพื่อน:

ส่วนประกอบ หน้าที่
Prometheus Server scrape + เก็บ + query + ยิง alert rule
Exporters แปลง metric จากระบบที่ไม่รู้จัก Prometheus (Linux, MySQL, Redis) ให้อยู่ในรูปที่ scrape ได้ (บทที่ 22)
Client libraries ฝังใน code แอปเพื่อ expose metric เอง (prom-client, etc.)
Alertmanager รับ alert จาก Prometheus แล้วจัดการ: จัดกลุ่ม, ปิดเสียงซ้ำ, route ไป Slack/PagerDuty (บทที่ lab-metrics-02)
Pushgateway ที่พัก metric สำหรับ batch job
Grafana ทำ dashboard สวยๆ จากข้อมูล Prometheus (บทที่ 23)

Prometheus ไม่ได้ทำ dashboard สวยๆ เอง — มันมี UI พื้นฐานไว้เทส query แต่ dashboard จริงใช้ Grafana เป็นคู่หูมาตรฐาน (Prometheus = คลังข้อมูล, Grafana = หน้าจอ)

ข้อจำกัดที่ต้องรู้

  • ไม่ใช่ระบบเก็บระยะยาว/HA โดยกำเนิด — Prometheus 1 ตัวเก็บ local ถ้าต้องการเก็บนาน/หลาย region ใช้ Thanos, Cortex, หรือ Mimir มาต่อ
  • ไม่เหมาะกับข้อมูลรายเหตุการณ์/cardinality สูง — นั่นคืองานของ logs/traces (ย้ำจากบทที่ 13)
  • ค่าเป็น float + timestamp เท่านั้น — เก็บ string ไม่ได้ (string ไปอยู่ใน label)

สรุป

  • Prometheus ใช้ pull model — ไป GET /metrics จาก target เอง ทำให้รู้ทันทีว่า target ตายไหม
  • target แค่เปิด HTTP endpoint ที่ return metric เป็น text — เปิด curl ดูได้
  • Service discovery หา target อัตโนมัติในระบบที่ pod เกิด-ดับตลอด
  • TSDB + compression ทำให้ metric เล็กและเก็บได้นานในราคาถูก
  • ทำงานเป็น ecosystem: exporters, client libs, Alertmanager, Grafana
  • เก็บระยะยาว/HA ต้องต่อ Thanos/Mimir

บทหน้า: PromQL — ภาษา query ที่ทำให้ metric กองนั้นตอบคำถามได้