Arquitectura de Métricas para SaaS - CreaRack Pro
Fecha: 04-02-2026 Estado: Referencia arquitectónica Autor: Claude (Anthropic) + Edu
1. Resumen Ejecutivo
Este documento describe la arquitectura de métricas y caché para CreaRack Pro como SaaS, explicando el rol de cada tecnología y cómo trabajan juntas.
Valkey es para “ahora mismo”, VictoriaMetrics es para “qué pasó en el tiempo”
Stack de datos
| Tecnología | Rol | Retención | Velocidad |
|---|---|---|---|
| Valkey | Cache, sesiones, pub/sub | Segundos a horas | Milisegundos |
| VictoriaMetrics | Series temporales | Días a años | ~100ms |
| PostgreSQL | Datos de negocio | Permanente | ~10-50ms |
Conclusión clave: No son excluyentes, son complementarios. Cada uno resuelve un problema diferente.
2. Diagrama de Arquitectura
┌─────────────────────────────────────────────────────────────────────┐
│ CreaRack SaaS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ MÉTRICAS SAAS │ │ MÉTRICAS CLIENTES │ │
│ │ (Infraestructura) │ │ (Observatory) │ │
│ │ │ │ │ │
│ │ - CPU/RAM servers │ │ - Ping latency │ │
│ │ - Request latency │ │ - SNMP bandwidth │ │
│ │ - Error rates │ │ - HTTP checks │ │
│ │ - DB connections │ │ - Alertas red │ │
│ │ │ │ │ │
│ │ Visualización: │ │ Visualización: │ │
│ │ VM UI / PromQL │ │ UI CreaRack │ │
│ └──────────┬───────────┘ └──────────┬───────────┘ │
│ │ │ │
│ └──────────┬──────────────────┘ │
│ ▼ │
│ ┌──────────────────────┐ │
│ │ VictoriaMetrics │ │
│ │ (instancia única) │ │
│ │ │ │
│ │ Separación por │ │
│ │ labels (tenant_id) │ │
│ └──────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
3. Rol de Cada Tecnología
3.1 Valkey (Redis-compatible)
Propósito: Datos efímeros de alta velocidad.
Casos de uso en CreaRack:
# Cache de respuestas API (evitar queries repetidas)
cache.set(f"rack:{rack_id}:devices", devices, timeout=60)
devices = cache.get(f"rack:{rack_id}:devices")
# Sesiones de usuario
session_store = ValkeySessionStore()
# Rate limiting (protección API)
requests = cache.incr(f"api:{user_id}:requests", timeout=60)
if requests > 100:
raise RateLimitExceeded()
# Pub/Sub para WebSockets (Django Channels)
await channel_layer.group_send("terminal_123", {
"type": "terminal.output",
"data": "comando ejecutado"
})
# Bloqueos distribuidos (evitar edición simultánea)
with cache.lock(f"rack:{rack_id}:editing", timeout=30):
save_rack(data)
Características:
- Almacenamiento en memoria (muy rápido)
- Datos volátiles (se pueden perder en restart)
- Ideal para datos que cambian constantemente
- No apto para históricos
3.2 VictoriaMetrics
Propósito: Almacenamiento de métricas históricas (series temporales).
Casos de uso en CreaRack:
# Métricas Observatory (datos de clientes)
MetricsWriter.write_ping(
tenant_id=1,
target_id=123,
latency_ms=45.2,
packet_loss=0.0
)
# Métricas SaaS (infraestructura propia)
MetricsWriter.write_infra(
metric="http_request_duration_ms",
value=23.5,
endpoint="/api/racks",
method="GET"
)
# Consultas históricas con PromQL
avg_latency = MetricsReader.query(
'avg(ping_latency_ms{tenant_id="1"})[24h]'
)
Características:
- Optimizado para series temporales
- Compresión 10x mejor que PostgreSQL
- Consultas PromQL (agregaciones, rangos, funciones)
- Retención configurable (30 días, 90 días, etc.)
3.3 PostgreSQL
Propósito: Datos de negocio persistentes.
Almacena:
- Usuarios, tenants, permisos
- Racks, dispositivos, conexiones
- Configuración de monitoreo (targets, alertas)
- Facturas, suscripciones
- Auditoría y logs de negocio
No debe almacenar:
- Métricas de series temporales (usar VictoriaMetrics)
- Cache de sesiones (usar Valkey)
- Datos temporales de alta frecuencia
4. Comparación Detallada
4.1 Valkey vs VictoriaMetrics
| Aspecto | Valkey | VictoriaMetrics |
|---|---|---|
| Tipo de dato | Key-Value genérico | Series temporales |
| Pregunta que responde | “¿Qué valor tiene X ahora?” | “¿Cómo evolucionó X en el tiempo?” |
| Retención | Segundos a horas | Días a años |
| Consultas | GET/SET simples | PromQL (avg, sum, rate, etc.) |
| Persistencia | Opcional (efímero por defecto) | Siempre persistente |
| Uso de disco | Mínimo (en memoria) | Optimizado (compresión) |
4.2 VictoriaMetrics vs PostgreSQL para métricas
| Aspecto | PostgreSQL | VictoriaMetrics |
|---|---|---|
| Compresión | ~100 bytes/punto | ~10 bytes/punto |
| 500 dispositivos × 30 días | ~4GB | ~400MB |
| Consulta “avg últimas 24h” | 2-5 segundos | 100-500ms |
| Agregaciones temporales | SQL complejo | PromQL nativo |
| Diseñado para | Datos relacionales | Series temporales |
5. Recursos y Escalabilidad
5.1 Estimación de recursos VictoriaMetrics
| Escenario | Dispositivos | Disco (30 días) | RAM |
|---|---|---|---|
| Startup | 10 clientes × 50 | ~80MB | ~200MB |
| Crecimiento | 50 clientes × 100 | ~800MB | ~500MB |
| Escala | 100 clientes × 200 | ~3GB | ~1GB |
Nota: VictoriaMetrics es extremadamente eficiente en consumo de recursos. En un deployment típico, Django y PostgreSQL consumirán más RAM/CPU que VictoriaMetrics. No te preocupes por los recursos de VM; es el componente más ligero del stack.
5.2 Comparación con alternativas
| Sistema | Disco (relativo) | RAM (relativo) |
|---|---|---|
| VictoriaMetrics | 1x | 1x |
| Prometheus | 10x | 3x |
| InfluxDB | 5x | 2x |
| TimescaleDB | 3x | 2x |
6. Multi-tenancy para SaaS
6.1 Estrategia recomendada: Labels por tenant
# Cada métrica incluye tenant_id como label
{
"metric": {
"__name__": "ping_latency_ms",
"tenant_id": "cliente_1", # <-- Separación
"target_id": "123",
"target_ip": "192.168.1.1"
},
"values": [45.2],
"timestamps": [1707000000000]
}
6.2 Seguridad en la API
# SIEMPRE filtrar por tenant_id del usuario autenticado
@router.get("/targets/{target_id}/metrics/ping")
async def get_ping_metrics(request, target_id: int, hours: int = 1):
# Obtener tenant del usuario autenticado
tenant_id = request.auth.user.tenant_id
# La query SIEMPRE incluye tenant_id
query = f'ping_latency_ms{{tenant_id="{tenant_id}", target_id="{target_id}"}}'
return await MetricsReader.query_range(query, hours)
6.3 Alternativa futura: Instancia por tenant
Para clientes enterprise que requieran aislamiento total:
# Instancia dedicada por cliente premium
victoriametrics_enterprise_client:
image: victoriametrics/victoria-metrics
command:
- "--retentionPeriod=90d"
volumes:
- vm_enterprise_client:/data
Recomendación: Empezar con labels, ofrecer instancia dedicada como upgrade premium.
7. Flujo de Datos en Producción
┌─────────────────────────────────────────────────────────────────────┐
│ Request de Usuario │
└─────────────────────────┬───────────────────────────────────────────┘
│
▼
┌─────────────────┐
│ Django │
│ (API/Views) │
└────────┬────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Valkey │ │ PostgreSQL │ │VictoriaMetrics│
│ │ │ │ │ │
│ "¿Cache?" │ │ "Dame datos" │ │ "Log métrica" │
│ "¿Rate limit?"│ │ "Guarda X" │ │ "Query hist." │
└───────────────┘ └───────────────┘ └───────────────┘
│
┌─────────────────┘
▼
┌─────────────────┐
│ Observatory UI │
│ (ECharts) │
│ │
│ "Charts de │
│ infraestructura│
└─────────────────┘
7.1 Ejemplo: Usuario consulta métricas de ping
1. Usuario abre Observatory en UI
2. Frontend llama: GET /api/monitoring/targets/123/vm/ping?hours=24
3. Django verifica autenticación y obtiene tenant_id
4. Django consulta VictoriaMetrics:
query = 'ping_latency_ms{tenant_id="5", target_id="123"}'
5. VictoriaMetrics devuelve datos agregados
6. Django formatea para ApexCharts
7. Frontend renderiza gráfica
Nota v1.68.1: los endpoints PostgreSQL
/metrics,/history,/statsy/bandwidthquedaron retirados (ver §7.2) — el histórico se sirve siempre por/vm/*.
7.2 Ejemplo: Sistema registra métrica
1. PingService hace ping a target
2. PingService escribe a VictoriaMetrics (MetricsWriter)
Actualizado v1.68.1 (17-08-2026, task #230, PR #395): la escritura a PostgreSQL (
MetricSample) para ping, TCP y HTTP quedó retirada — sin lectores desde que Observatory pasó a VictoriaMetrics vía Agente. Los 4 endpoints GET que leían ese histórico (/metrics,/history,/stats,/bandwidth) también se retiraron:/statsfabricaba unuptime_pctde 0% en equipos sanos por leer una tabla vacía.MetricSamplesigue en pie solo como caché de contadores SNMP (bandwidth_in/bandwidth_out) para el cálculo de caudal; las tablasMetricSample/AggregatedMetricquedan en pie (elDROPes un ciclo de migración propio — footgun RLS/DROP POLICY). Test que fija la retirada:tests/monitoring/test_pg_metrics_retired.py.
8. Evolución hacia Kubernetes
8.1 Cuándo NO necesitas Kubernetes
- < 50 clientes simultáneos
- 1-3 servidores son suficientes
- Equipo pequeño (1-3 personas)
- No necesitas auto-scaling agresivo
- Presupuesto limitado para DevOps
8.2 Cuándo SÍ considerar Kubernetes
-
100 clientes con picos impredecibles
- Despliegue multi-región requerido
- Equipo DevOps dedicado disponible
- Clientes enterprise con SLAs de 99.9%+
- Necesidad de zero-downtime deployments
8.3 Evolución recomendada
┌─────────────────────────────────────────────────────────────────────┐
│ FASE 1: MVP/Early Stage │
│ │
│ Docker Compose en 1 servidor (Hetzner CX31 o similar) │
│ - Django + Valkey + PostgreSQL + VictoriaMetrics │
│ - Capacidad: ~10-30 clientes │
│ - Costo: ~€15-30/mes │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ FASE 2: Crecimiento │
│ │
│ Docker Compose + Load Balancer (2-3 servidores) │
│ - Separar: Web | DB + Cache | Métricas │
│ - Capacidad: ~30-100 clientes │
│ - Costo: ~€50-100/mes │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ FASE 3: Escala │
│ │
│ Kubernetes (managed: GKE, EKS, Hetzner K8s) │
│ - Auto-scaling, multi-región │
│ - Capacidad: 100+ clientes │
│ - Costo: ~€200-500/mes + DevOps │
└─────────────────────────────────────────────────────────────────────┘
8.4 Kubernetes y VictoriaMetrics
Cuando llegue el momento, VictoriaMetrics tiene operadores oficiales para K8s:
# victoria-metrics-operator
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMSingle
metadata:
name: crearack-metrics
spec:
retentionPeriod: "30d"
storage:
volumeClaimTemplate:
spec:
resources:
requests:
storage: 10Gi
9. Resumen de Decisiones
| Decisión | Elección | Razón |
|---|---|---|
| Métricas Observatory | VictoriaMetrics | Eficiencia, PromQL, compresión |
| Métricas SaaS infra | VictoriaMetrics (misma instancia) | Simplicidad |
| Cache/Sesiones | Valkey | Ya configurado, eficiente |
| Datos de negocio | PostgreSQL | Relacional, ACID |
| Visualización | Observatory UI (ECharts) | Integrado, branded |
| Multi-tenancy | Labels (tenant_id) | Simple, escalable |
| Infraestructura inicial | Docker Compose | Suficiente para MVP |
| Kubernetes | Futuro (50+ clientes) | Cuando sea necesario |
| Vía PostgreSQL de métricas (histórico) | Retirada (v1.68.1) | Tablas vacías en PROD, /stats fabricaba datos falsos |
10. Próximos Pasos
-
Implementar integración VictoriaMetrics + Observatory— hecho. Su continuación natural también está hecha: en v1.68.1 (17-08-2026, task #230, PR #395) se retiró la vía PostgreSQL de métricas (4 endpoints GET + escrituras deMetricSamplesin lector + el commandaggregate_metricscompleto). -
Añadir métricas de infraestructura SaaS
- Request latency, error rates, DB connections
-
Documentar procedimientos de backup
- VictoriaMetrics snapshots
- PostgreSQL dumps
-
Pendiente:
DROPde las tablasMetricSample/AggregatedMetric— requiere su propio ciclo de migración (footgun RLS/DROP POLICY conocido del proyecto), fuera del alcance de v1.68.1.
11. Referencias
- VictoriaMetrics Docs
- VictoriaMetrics vs Prometheus
- Multi-tenancy en VictoriaMetrics
- Valkey Documentation
- Django Channels + Redis/Valkey
Documento preparado para: Edu (CreaRack Pro) Última actualización: 17-08-2026 (retirada vía PostgreSQL de métricas, task #230)
Véase también
- [[crearack-tech—architecture—saas-strategy-2026]] — estrategia SaaS 2026
- [[crearack-tech—architecture—saas-roadmap-2026]] — roadmap SaaS 2026
- [[crearack-tech—architecture—realtime-monitoring-plan]] — plan de monitorización en tiempo real
- [[crearack-tech—admin—monitoring-tools]] — herramientas admin de monitorización
- [[concept—saas—multi-tenancy]] — multi-tenancy SaaS (orgs + RLS)
- [[concept—saas—module-gating]] — gating por módulo/plan en el SaaS