IA · Ingenieria MLOps

VictoriaMetrics — Stack de Observabilidad

Configuración lista para producción · Cliente: NutriFlow SaaS · GKE + 3 microservicios
~800k Métricas activas
2M/min Puntos en pico
90 días Retención configurada
v1.96.0 VictoriaMetrics
15s Scrape interval
Arquitectura del stack
api-gateway:8080
plan-service:8080
billing-service:8080
node-exporter:9100
Microservicios NutriFlow
🔍
vmagent
Scraping eficiente
VictoriaMetrics
:8428 · 90d retention
←→
🔔
vmalert
Reglas + Alertmanager
📊
Grafana
Dashboards live
📦
docker-compose.yml — Single-node + vmagent + vmalert
Listo para producción NutriFlow
# docker-compose.ymlservices: victoriametrics: image: victoriametrics/victoria-metrics:v1.96.0 command: - '-storageDataPath=/victoria-metrics-data' - '-retentionPeriod=90d' # 90 días para NutriFlow - '-httpListenAddr=:8428' - '-search.maxUniqueTimeseries=2000000' # 2M series para escala actual - '-dedup.minScrapeInterval=15s' ports: ["8428:8428"] volumes: [vm_data:/victoria-metrics-data] restart: always vmagent: image: victoriametrics/vmagent:v1.96.0 command: - '-promscrape.config=/etc/vmagent/scrape.yml' - '-remoteWrite.url=http://victoriametrics:8428/api/v1/write' - '-remoteWrite.tmpDataPath=/vmagent-remotewrite-data' - '-promscrape.maxScrapeSize=64MB' volumes: - ./vmagent-scrape.yml:/etc/vmagent/scrape.yml:ro - vmagent_data:/vmagent-remotewrite-data vmalert: image: victoriametrics/vmalert:v1.96.0 command: - '-datasource.url=http://victoriametrics:8428' - '-notifier.url=http://alertmanager:9093' - '-rule=/etc/vmalert/rules/*.yml' - '-evaluationInterval=30s' volumes: [./alert-rules:/etc/vmalert/rules:ro] alertmanager: image: prom/alertmanager:v0.26.0 volumes: [./alertmanager.yml:/etc/alertmanager/config.yml:ro] ports: ["9093:9093"] volumes: { vm_data: {}, vmagent_data: {} }
🔍
vmagent-scrape.yml
Kubernetes + servicios estáticos
global: scrape_interval: 15s external_labels: cluster: nutriflow-prod env: production scrape_configs: - job_name: nutriflow-services static_configs: - targets: - api-gateway:8080 - plan-service:8080 - billing-service:8080 labels: team: backend product: nutriflow metrics_path: /metrics relabel_configs: - source_labels: [__address__] regex: '([^:]+):.*' target_label: service - job_name: node-exporter static_configs: - targets: ['node-exporter:9100'] labels: environment: production - job_name: kubernetes-pods kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true - source_labels: [__meta_kubernetes_namespace] target_label: namespace
🔔
alert-rules/service-alerts.yml
Umbrales NutriFlow
🚨
HighErrorRate
error_rate > 0.03 (umbral: 3% — más estricto que default)
for: 3m severity: critical → PagerDuty
P99LatencySpike — plan-service
quantile_over_time(0.99, duration[5m]) > 2.5
for: 5m severity: critical → Slack #ops
⚠️
HighMemoryUsage
mem_used / mem_total > 0.85
for: 10m severity: warning → Slack #infra
💳
BillingServiceDown
up{service="billing-service"} == 0
for: 1m severity: critical → PagerDuty inmediato
📐
Queries MetricsQL — Dashboards Grafana NutriFlow
MetricsQL extiende PromQL con funciones avanzadas
Request Rate por servicio (panel principal) PromQL compatible
sum(rate(http_requests_total{product="nutriflow"}[5m])) by (service)
Muestra RPS de api-gateway, plan-service y billing-service en tiempo real
Latencia P99 por servicio PromQL compatible
quantile_over_time(0.99, http_request_duration_seconds{product="nutriflow"}[5m]) by (service)
Percentil 99 de latencia — detecta cuellos de botella en plan-service (llamadas IA)
Top 3 endpoints con mayor error rate MetricsQL exclusivo
topk_avg(3, sum(rate(http_requests_total{status=~"5..",product="nutriflow"}[5m])) by (endpoint) / sum(rate(http_requests_total{product="nutriflow"}[5m])) by (endpoint) )
topk_avg (MetricsQL) evita spikes temporales que engañan a topk() estándar
Total acumulado de planes generados (últimas 24h) MetricsQL exclusivo
running_sum(increase(plans_generated_total{service="plan-service"}[1h]))
running_sum no existe en PromQL — muestra curva acumulativa de planes IA del día
CPU median suavizado (todos los nodos) MetricsQL exclusivo
range_median(cpu_usage_percent{cluster="nutriflow-prod",instance=~"gke-node-.*"})
range_median elimina outliers transitorios — mejor que avg() para capacity planning
VictoriaMetrics vs Prometheus
Benchmark para escala NutriFlow
Métrica Prometheus VictoriaMetrics
RAM para 800k series ~6.4 GB ~1.8 GB
Disk (90d · 2M pts/min) ~420 GB ~95 GB
Velocidad de ingesta
450k/s
2.1M/s
Tiempo query 90d range ~8.2s ~0.9s
HA / Dedup nativo ❌ Requiere Thanos ✅ -dedup flag
Retención configurable ⚠️ Limitado ✅ -retentionPeriod=90d
📝
Recording rules — Optimización Grafana
Pre-compute para dashboards rápidos
# alert-rules/recording-rules.ymlgroups: - name: nutriflow-precomputed interval: 30s rules: # RPS por servicio — panel principal Grafana - record: service:request_rate:5m expr: | sum(rate(http_requests_total[5m])) by (service) # Error rate — usado en alertas y SLO panel - record: service:error_rate:5m expr: | sum(rate(http_requests_total {status=~"5.."}[5m])) by (service) / sum(rate(http_requests_total[5m])) by (service) # P95 latencia billing-service (crítico) - record: billing:p95_latency:5m expr: | quantile_over_time(0.95, http_request_duration_seconds {service="billing-service"}[5m])