Saltar a contenido

Estrategias de escalado

KanjiIQ está diseñado para escalar desde su despliegue actual de un solo nodo hasta una arquitectura multi-nodo y multi-región a medida que crece el tráfico.

Estado actual

Métrica Valor
Nodos del clúster 1 (dedicado Hetzner)
Réplicas de aplicación 2
Base de datos Instancia única de PostgreSQL
Manejo de tráfico ~100 req/min por IP (con límite de velocidad)

Esto maneja el tráfico actual cómodamente. Las secciones siguientes describen la ruta de escalado a medida que aumenta la demanda.

Horizontal Pod Autoscaling (HPA)

El primer paso de escalado es añadir HPA para ajustar automáticamente el número de réplicas según la carga:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: jlpt-kanji-hpa
  namespace: jlpt-kanji
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: jlpt-kanji
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

Requisitos: Metrics Server debe estar instalado (incluido en k3s por defecto).

Impacto: La aplicación escala automáticamente entre 2-10 réplicas según la presión de CPU/memoria, sin cambios de código.

Clúster multi-nodo

Cuando un solo nodo alcanza los límites de recursos, se añaden nodos worker al clúster k3s:

# On the new worker node
curl -sfL https://get.k3s.io | K3S_URL=https://master:6443 \
  K3S_TOKEN=<node-token> sh -

Kubernetes programa automáticamente los pods en todos los nodos disponibles. La aplicación no requiere cambios — ya es sin estado.

Afinidad de nodo (opcional)

Para controlar la ubicación de los pods:

spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: jlpt-kanji
            topologyKey: kubernetes.io/hostname

Esto distribuye las réplicas en diferentes nodos para mejor tolerancia a fallos.

Escalado de base de datos

Connection pooling

Añadir PgBouncer como contenedor sidecar para agrupar conexiones de base de datos:

containers:
  - name: pgbouncer
    image: edoburu/pgbouncer
    ports:
      - containerPort: 6432
    env:
      - name: DATABASE_URL
        valueFrom:
          secretKeyRef:
            name: jlpt-kanji-secrets
            key: database-url

El backend se conecta a PgBouncer en :6432 en lugar de directamente a PostgreSQL, reduciendo la sobrecarga de conexiones.

Réplicas de lectura

Para cargas de trabajo con muchas lecturas (consultas de tarjetas), añadir replicación por streaming de PostgreSQL:

  1. La instancia primaria gestiona las escrituras (sesiones de estudio, resultados de cuestionarios)
  2. Las réplicas de lectura gestionan las lecturas (consultas de kanji/vocabulario)
  3. El backend enruta las consultas según el tipo de operación

Base de datos gestionada

La ruta más simple de escalado de base de datos es migrar a un servicio gestionado:

  • AWS RDS: Multi-AZ, respaldos automatizados, réplicas de lectura
  • GCP Cloud SQL: Configuración HA, failover automático
  • Hetzner Managed PostgreSQL: Cuando esté disponible

Consulta Portabilidad para detalles de migración.

Capa CDN

Los assets estáticos del frontend pueden servirse a través de un CDN para rendimiento global:

graph LR
    U[User] --> CF[Cloudflare CDN]
    CF -->|Cache HIT| U
    CF -->|Cache MISS| N[Nginx Frontend]
    N --> CF

Dado que el frontend Flutter Web produce archivos estáticos (JS, CSS, imágenes), estos son candidatos ideales para CDN:

  • Política de caché: 1 año para assets con hash, sin caché para index.html
  • PoPs globales: Contenido servido desde la ubicación edge más cercana
  • Protección DDoS: El CDN absorbe ataques volumétricos

Cloudflare DNS ya está configurado — activar el modo proxy habilita la capa CDN.

Hoja de ruta de escalado

Nivel de tráfico Infraestructura Cambios clave
Actual (bajo) 1 nodo, 2 réplicas, PG único Ninguno necesario
Creciente (moderado) 1 nodo, HPA (2-10 réplicas) Añadir manifiesto HPA
Alto 2-3 nodos, HPA, PgBouncer Añadir nodos worker + connection pooling
Muy alto Multi-nodo, BD gestionada, CDN Migrar BD a RDS/Cloud SQL, habilitar CDN
Global Clústeres multi-región, réplicas de lectura Evolución significativa de la arquitectura

Cada paso es incremental — no se requieren reescrituras. El código de la aplicación permanece sin cambios en todos los niveles de escalado.