ติดตั้ง InfluxDB บน VPS ฐานข้อมูล Time Series
InfluxDB คือฐานข้อมูล time series ที่ออกแบบเพื่อเก็บข้อมูล metrics ที่มีเวลากำกับเป็นจำนวนมาก — ใช้สำหรับเก็บ CPU usage, memory, disk I/O, temperature sensor, stock price, IoT data ทั้งหมดที่มีเวลาบ้าน ต่างจากฐานข้อมูลแบบ relational (MySQL, PostgreSQL) ที่เก็บข้อมูล static InfluxDB ทำให้ write/query metrics นี้ได้เร็วมาก — compress ได้ดี ใช้ disk เพียง 20-30% ของ MySQL บทความนี้สอนติดตั้ง InfluxDB 2.x + Telegraf agent + เชื่อมต่อ Grafana เพื่อ visualize metrics real-time
ฐานข้อมูล Time Series คืออะไร
ฐานข้อมูล time series เก็บข้อมูลที่มี timestamp — แต่ละตัวเลข metrics มาพร้อม timestamp แล้ว ทำให้ query ได้เร็ว ตัวอย่าง:
- Metrics: CPU usage = 45.2% ที่เวลา 14:30:00
- Tags: host=web1, region=thailand, env=prod (metadata ที่ใช้ filter)
- Fields: temperature=32.5, humidity=65 (ค่าที่วัดได้)
- Timestamp: 1719134400000 (milliseconds since epoch)
Elasticsearch/SQL database ไม่เหมาะสำหรับข้อมูลลักษณะนี้ — ทำการค้นหา, aggregation, time-based query ช้า InfluxDB ออกแบบมาเพื่อ read/write metrics นี้อย่างปลอดภัยและได้โดยใช้ resource น้อย
ติดตั้ง InfluxDB 2.x บน VPS
# สำหรับ Ubuntu/Debian
curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key | apt-key add -
echo "deb [signed-by=/usr/share/keyrings/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" | tee /etc/apt/sources.list.d/influxdata.list
apt update && apt install -y influxdb2 influxdb2-cli
# สำหรับ CentOS/RHEL
cat > /etc/yum.repos.d/influxdata.repo << 'EOF'
[influxdata]
name = InfluxData Repository
baseurl = https://repos.influxdata.com/rhel/\$releasever/\$basearch/stable
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdata-archive.key
EOF
yum install -y influxdb2
# เปิด service
systemctl start influxdb
systemctl enable influxdb
สร้าง Organization และ Bucket
InfluxDB ใช้เทอร์มินโลยี bucket แทน database แต่งาน purpose เดียวกัน Bucket คือการจัดเก็บข้อมูล time series ที่แยก namespace
# สร้าง token สำหรับ CLI
export INFLUX_HOST=http://localhost:8086
export INFLUX_ORG=my-org
export INFLUX_BUCKET=metrics
# ถ้า influxdb ใหม่ เปิด web UI ที่ http://localhost:8086 แล้ว setup
# ใส่ org name, bucket name, username, password
# หรือใช้ CLI setup
influx setup \
--org my-org \
--bucket metrics \
--retention 30d \
--username admin \
--password MySecurePass123! \
--force
# สร้าง API token สำหรับ Telegraf/Grafana
influx auth create \
--org my-org \
--description "Telegraf token" \
--read-bucket metrics \
--write-bucket metrics
ติดตั้ง Telegraf Agent บน VPS
Telegraf คือ agent ที่รัน บน VPS และสำหรับส่ง metrics (CPU, memory, disk, network) ไปยัง InfluxDB ทำให้เราไม่ต้อง manual write data ลงฐานข้อมูล
# ติดตั้ง Telegraf
apt install -y telegraf
# สร้าง config
cat > /etc/telegraf/telegraf.conf << 'EOF'
[global_tags]
host = "vps-01"
environment = "production"
[agent]
interval = "10s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "0s"
flush_interval = "10s"
flush_jitter = "0s"
precision = "ns"
logfile = ""
hostname = ""
omit_hostname = false
[[outputs.influxdb_v2]]
urls = ["http://localhost:8086"]
token = "YOUR_INFLUX_TOKEN"
organization = "my-org"
bucket = "metrics"
[[inputs.system]]
# CPU, memory, disk, network
[[inputs.disk]]
ignore_fs = ["tmpfs", "devtmpfs"]
[[inputs.mem]]
[[inputs.net]]
[[inputs.cpu]]
collect_cpu_time = true
report_by_cpu = true
[[inputs.processes]]
[[inputs.docker]]
endpoint = "unix:///var/run/docker.sock"
container_names = []
timeout = "5s"
EOF
# replace YOUR_INFLUX_TOKEN ด้วย token ที่สร้างจากขั้นตอนก่อนหน้า
# เปิด Telegraf
systemctl start telegraf
systemctl enable telegraf
# ตรวจ log
systemctl status telegraf
ตั้ง Retention Policy และ Downsampling
Retention policy คือ rule ที่บอก InfluxDB ว่าต้องเก็บข้อมูลกี่วัน การเลือก retention ที่เหมาะสมช่วยลด disk usage อย่างมาก
# ตั้ง retention policy สำหรับ bucket metrics — เก็บ 30 วัน
influx bucket update \
--org my-org \
--name metrics \
--retention 720h
# ดู buckets ทั้งหมด
influx bucket list --org my-org
# Downsampling — compress ข้อมูลเก่า (เก่ากว่า 7 วัน) ให้มี interval นาน 1 ชั่วโมง
# ใน Flux (InfluxDB query language):
# aggregateWindow() — ใช้ใน query ตัวอย่าง:
# from(bucket:"metrics")
# |> range(start: -30d)
# |> aggregateWindow(every: 1h, fn: mean)
# |> to(bucket: "metrics-downsampled")
เชื่อมต่อ Grafana กับ InfluxDB
Grafana ใช้ Flux query language เพื่อดึงข้อมูล metrics จาก InfluxDB สร้าง dashboard visualize metrics real-time
# สมมติว่า Grafana รันอยู่ที่ http://localhost:3000
# login แล้วไปที่ Home → Connections → Data sources → Add data source
# เลือก InfluxDB
# Query language: Flux (หรือ SQL ถ้าใช้ InfluxDB 3.0)
# URL: http://localhost:8086
# Organization: my-org
# Token: YOUR_INFLUX_TOKEN
# Bucket: metrics
# Save & test → ต้องได้ "Successfully queried the InfluxDB API"
# สร้าง Simple Dashboard:
# กด + → Panel → Choose InfluxDB data source
# ใส่ Flux query:
# from(bucket: "metrics")
# |> range(start: -24h)
# |> filter(fn: (r) => r._measurement == "cpu")
# |> filter(fn: (r) => r._field == "usage_system")
# |> aggregateWindow(every: 1m, fn: mean)
Flux Query Language พื้นฐาน
Flux เป็น functional query language ของ InfluxDB — คล้ายกับ SQL แต่อำนาจการ process data มากกว่า
# อ่านข้อมูลจาก bucket metrics ย้อนหลัง 24 ชั่วโมง
from(bucket: "metrics")
|> range(start: -24h)
# filter measurement
from(bucket: "metrics")
|> range(start: -24h)
|> filter(fn: (r) => r._measurement == "cpu")
# filter field ที่เป็น usage_system
from(bucket: "metrics")
|> range(start: -24h)
|> filter(fn: (r) => r._measurement == "cpu")
|> filter(fn: (r) => r._field == "usage_system")
# aggregate เป็น mean ทุก 1 นาที
from(bucket: "metrics")
|> range(start: -24h)
|> filter(fn: (r) => r._measurement == "cpu")
|> aggregateWindow(every: 1m, fn: mean)
# group by host
from(bucket: "metrics")
|> range(start: -24h)
|> filter(fn: (r) => r._measurement == "mem")
|> group(columns: ["host"])
|> aggregateWindow(every: 5m, fn: mean)
# คำนวณ 95th percentile ของ response time
from(bucket: "metrics")
|> range(start: -7d)
|> filter(fn: (r) => r._measurement == "http_request")
|> filter(fn: (r) => r._field == "response_time_ms")
|> quantile(q: 0.95)
ตั้ง Alert ใน InfluxDB
# สร้าง Notification Endpoint (เช่น Email, Slack, Webhook)
# ใน Web UI: Alerting → Notification Endpoints → Create
# สร้าง Alert Rule:
# Alerting → Alert Rules → Create
# ตัวอย่าง Flux query สำหรับ alert เมื่อ CPU > 80% เป็นระยะ 5 นาที:
# option task = {name: "High CPU Alert", every: 5m, offset: 0s}
# from(bucket: "metrics")
# |> range(start: -5m)
# |> filter(fn: (r) => r._measurement == "cpu")
# |> filter(fn: (r) => r._field == "usage_system")
# |> aggregateWindow(every: 1m, fn: mean)
# |> map(fn: (r) => ({r with _value: r._value / 100.0}))
# |> filter(fn: (r) => r._value > 0.8)
# |> group(columns: ["host"])
# ตั้ง threshold: If count() > 0 for 1 minute then Fire
# Then: Send notification ไปยัง notification endpoint ที่สร้างไว้
ตรวจสอบว่า InfluxDB ทำงานถูกต้อง
# ตรวจ InfluxDB API health
curl -s -i http://localhost:8086/health
# เข้า InfluxDB shell
influx
# ดูรายชื่อ buckets
buckets
# ดูข้อมูลล่าสุดใน metrics bucket (ใช้ Flux)
from(bucket: "metrics") |> range(start: -1h) |> limit(n: 5)
# ดูรายชื่อ measurement ใน metrics
from(bucket: "metrics") |> range(start: -1h) |> group(columns: ["_measurement"]) |> distinct(column: "_measurement")
# ตรวจว่า Telegraf ส่ง data มาแล้ว
from(bucket: "metrics") |> range(start: -5m) |> filter(fn: (r) => r._measurement == "cpu")
# ออก influx shell
exit
influx query สำหรับ run Flux query จาก command line แทนการเข้า interactive shell — เช่น influx query 'from(bucket:"metrics") |> range(start: -24h) |> limit(n: 10)' --org my-orgแก้ปัญหาที่พบบ่อย
Error: "bucket not found" เมื่อ query
bucket ที่ตั้งไว้ใน Telegraf หรือ Grafana ไม่มีอยู่ หรือชื่อผิด
# ดูรายชื่อ buckets ที่มีอยู่
influx bucket list --org my-org
# ถ้าไม่มี สร้างมันใหม่
influx bucket create --org my-org --name metrics --retention 720h
# ตรวจเบิก bucket name ใน config (Telegraf/Grafana) ให้ตรงกัน
Telegraf ส่งข้อมูลไม่มา ในขณะที่ service running
Token หมดอายุ หรือ config ไม่ถูกต้อง — ตรวจ log Telegraf
# ดู log ของ Telegraf
journalctl -u telegraf -n 50 -f
# ถ้าเห็น "401 Unauthorized" = token expire ให้สร้าง token ใหม่
influx auth create --org my-org --description "Telegraf" --read-bucket metrics --write-bucket metrics
# copy token ใหม่ ใส่ใน /etc/telegraf/telegraf.conf และ reload
systemctl reload telegraf
InfluxDB กิน memory เยอะเกิน
InfluxDB cache data ใน memory — ตั้ง cache limit ลด retention ให้สั้นลง
# ใน /etc/default/influxdb (Debian/Ubuntu):
INFLUXDB_HEAP_SIZE=2gb
# restart InfluxDB
systemctl restart influxdb
# ตรวจ memory ที่ใช้ (ในหลาย ระบบ):
free -h
systemctl status influxdb | grep Memory
Grafana ไม่เห็นข้อมูล แม้ว่า InfluxDB มีข้อมูล
Bucket name ใน data source ผิด หรือ time range ไม่ตรง
# ใน Grafana: Configuration → Data sources → InfluxDB
# ตรวจค่า "Bucket" ให้ตรงกับชื่อจริง
# หรือ query ช่วง time ที่มี data เช่น "Last 24 hours" ไม่ใช่ "Last 7 days"
# ใน Explore tab สามารถ test query และ time range ได้เลย
Query Flux ช้า หรือ timeout
query เกี่ยวข้องกับข้อมูลจำนวนมาก ต้อง optimize Flux query
# ใช้ aggregateWindow() ลด resolution
from(bucket: "metrics")
|> range(start: -30d)
|> filter(fn: (r) => r._measurement == "cpu")
|> aggregateWindow(every: 1h, fn: mean)
# ใช้ limit() ลดจำนวน records
from(bucket: "metrics")
|> range(start: -24h)
|> limit(n: 1000)
# ใช้ sample() สุ่มตัวอย่างข้อมูล
from(bucket: "metrics")
|> range(start: -7d)
|> sample(n: 100)
คำถามที่พบบ่อย
InfluxDB ต่างจาก Prometheus อย่างไร?
Prometheus ใช้ pull model — Prometheus server pull metrics จาก exporter (node_exporter เป็นต้น) ส่วน InfluxDB ใช้ push model — Telegraf/app push metrics ไปยัง InfluxDB Prometheus นิยมใช้ alert + short-term metrics (โดย default เก็บ 15 วัน) InfluxDB นิยมใช้ long-term storage + historical data analysis เพราะ compression ดีมาก ทั้งสองสามารถใช้ Grafana เพื่อ visualize ได้
InfluxDB ใช้ clustering/replication ได้ไหม?
InfluxDB Open Source Edition ไม่มี clustering — replica ต้องใช้ InfluxDB Enterprise (ชำระสมาชิก) สำหรับ high availability บน VPS ทั่วไป วิธีแก้คือ backup regular ด้วย influx backup หรือ setup secondary InfluxDB ตัวเดียวแล้ว Telegraf ส่งไปทั้ง primary และ secondary (dual write)
ชิ้นข้อมูลไหน InfluxDB รับ (tag vs field vs timestamp)?
InfluxDB ต้องการ: measurement (ชื่อ), timestamp (เวลา), fields (ค่าตัวเลข), optional tags (metadata string) — tags ใช้สำหรับ index/filter ต้องเป็น string ถ้า ใช้ tags เยอะเกิน cardinality สูง → memory ใช้มาก ส่วน fields ใช้สำหรับค่าตัวเลขที่ต้อง aggregate (mean, sum, max ฯลฯ) ไม่ indexing ลด memory ใช้ได้ดี