สถาปัตยกรรม 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 กองนั้นตอบคำถามได้