Kodeloka
  1. Kodeloka
  2. Kelas Grafana
  3. Materi

Modul 14 · Modul 14 dari 15

Performa & Skala: Dashboard Cepat, Grafana Tahan Beban

Mendiagnosis dashboard lambat secara sistematis, lalu menjalankan Grafana secara high-availability tanpa alert ganda.

Diagnosis Sebelum Optimasi

"Grafana lambat" hampir selalu berarti salah satu dari empat hal yang berbeda. Panel Inspect → Stats memberi angka yang memisahkannya.

Gejala di StatsPenyebabPerbaikan
Data source duration tinggiKueri berat di data sourceRecording rule, kurangi kardinalitas
Number of fields ratusanTerlalu banyak seriesAgregasi, topk
Number of rows puluhan ribuTerlalu banyak titikMax data points, min interval
Semua cepat tapi UI tersendatTerlalu banyak panel / transformationRow tertutup, pecah dashboard

Recording Rule: Pindahkan Biaya ke Waktu Tulis

Kueri yang sama dijalankan berulang oleh puluhan panel dan alert. Hitung sekali di Prometheus, simpan hasilnya, dan panel hanya membaca metrik yang sudah jadi.

rules/recording.ymlyaml
groups:
  - name: slo-recording
    interval: 30s
    rules:
      - record: layanan:latency_p95:5m
        expr: |
          histogram_quantile(0.95,
            sum by (layanan, le) (
              rate(http_request_duration_seconds_bucket[5m])
            )
          )

      - record: layanan:error_rate:5m
        expr: |
          sum by (layanan) (rate(http_requests_total{status=~"5.."}[5m]))
            /
          sum by (layanan) (rate(http_requests_total[5m]))
panel menjadi sederhanapromql
// sebelum: dihitung ulang tiap refresh, tiap pengguna
histogram_quantile(0.95, sum by (layanan, le) (rate(http_request_duration_seconds_bucket[$__rate_interval])))

// sesudah: satu series yang sudah dihitung
layanan:latency_p95:5m

Panel yang tadinya memakan 4 detik bisa turun ke bawah 100 ms. Untuk dashboard yang dibuka banyak orang, ini perbaikan terbesar yang tersedia.

Query Caching

grafana.iniini
[caching]
enabled = true

[caching.memory]
gc_interval    = 1m
max_size_bytes = 26214400        # 25 MB

# untuk instalasi HA, pakai Redis agar cache dibagi antar replika
[caching.redis]
url        = redis://redis:6379
prefix     = grafana-cache
cluster    = false

Caching per data source diatur di halaman data source (TTL). Ia sangat efektif untuk dashboard TV yang dibuka banyak orang dengan rentang waktu identik, dan tidak berguna untuk Explore di mana setiap kueri berbeda.

⚠️ Cache membuat data tertinggal

TTL 60 detik berarti dashboard bisa menampilkan angka satu menit lalu. Untuk ikhtisar itu tidak masalah; untuk panel yang dipakai memutuskan tindakan saat insiden, itu bisa menyesatkan. Set TTL pendek atau nonaktifkan cache pada dashboard insiden.

Checklist Optimasi Dashboard

  1. Instant query untuk semua panel Stat, Gauge, Bar gauge, dan Table ringkasan.
  2. Max data points 300–500 untuk panel di dashboard kios.
  3. Min interval minimal sebesar scrape interval.
  4. Agregasi di kueri: sum by (layanan), bukan per-instance, kecuali memang perlu.
  5. topk untuk membatasi jumlah series yang digambar.
  6. Row tertutup untuk semua panel detail.
  7. Recording rule untuk kueri yang muncul di lebih dari satu panel.
  8. Hapus panel yang tidak pernah dilihat siapa pun.
  9. min_refresh_interval ditegakkan di sisi server.
  10. Repeat dibatasi, tanpa opsi All.

High Availability

arsitektur HAtext
              ┌─────────────┐
              │ Load        │
              │ Balancer    │
              └──┬───────┬──┘
                 │       │
        ┌────────▼─┐  ┌──▼───────┐
        │ Grafana  │  │ Grafana  │   replika stateless
        │   #1     │  │   #2     │
        └────┬─────┘  └─────┬────┘
             │              │
     ┌───────▼──────────────▼───────┐
     │ PostgreSQL (dashboard, user, │  WAJIB dibagi
     │ alert rule, state alert)     │
     └──────────────────────────────┘
             │              │
     ┌───────▼──────────────▼───────┐
     │ Redis (session, cache)       │  opsional
     └──────────────────────────────┘
grafana.ini — HAini
[database]
type = postgres
host = pg.internal:5432
name = grafana

[unified_alerting]
enabled = true
ha_peers          = grafana-1:9094,grafana-2:9094
ha_listen_address = ${POD_IP}:9094
ha_advertise_address = ${POD_IP}:9094
ha_peer_timeout   = 15s

[remote_cache]
type    = redis
connstr = addr=redis:6379,pool_size=100,db=0
⛔ HA tanpa ha_peers = notifikasi ganda

Dua replika Grafana tanpa konfigurasi gosip alerting akan mengevaluasi rule yang sama secara independen dan masing-masing mengirim notifikasi. Setiap alert datang dua kali, dan tim mulai mengabaikannya.

ha_peers membuat replika membentuk klaster Alertmanager: mereka berbagi state, melakukan deduplikasi notifikasi, dan menyinkronkan silence. Tanpa ini, silence yang dibuat di replika #1 tidak dikenali replika #2.

Batas Wajar Satu Instansi

DimensiNyamanPerlu perhatian
Dashboard< 2.000> 5.000 (pencarian melambat)
Pengguna aktif bersamaan< 200> 500 (tambah replika)
Alert rule< 1.000> 5.000 (evaluasi tertinggal)
Panel per dashboard< 20> 50 (browser tersendat)
Series per panel< 50> 200 (tidak terbaca dan berat)

Memantau Grafana Itu Sendiri

Grafana mengekspos metrik Prometheus di /metrics. Metrik yang layak dipantau:

metrik Grafanapromql
// latency HTTP Grafana
histogram_quantile(0.95, sum by (le) (
  rate(grafana_http_request_duration_seconds_bucket[$__rate_interval])))

// kueri data source yang gagal
sum by (datasource) (rate(grafana_datasource_request_total{code!~"2.."}[$__rate_interval]))

// evaluasi alert yang tertinggal dari jadwal — indikator kelebihan beban
grafana_alerting_schedule_delay_seconds

// pengguna aktif
grafana_stat_active_users

// koneksi basis data
grafana_database_conn_in_use
💡 grafana_alerting_schedule_delay_seconds adalah alarm dini

Bila nilainya tumbuh, evaluasi alert Anda tidak lagi mengejar jadwal — artinya alert bisa terlambat berbunyi tanpa ada indikasi lain. Ini metrik pertama yang perlu di-alert pada Grafana produksi.