Aller au contenu

Stratégies de mise à l'échelle

KanjiIQ est conçu pour évoluer de son déploiement actuel sur un seul noeud vers une architecture multi-noeuds et multi-régions à mesure que le trafic augmente.

État actuel

Métrique Valeur
Noeuds du cluster 1 (serveur dédié Hetzner)
Réplicas applicatifs 2
Base de données Instance PostgreSQL unique
Gestion du trafic ~100 req/min par IP (limitation de débit)

Cela gère confortablement le trafic actuel. Les sections ci-dessous décrivent le chemin de mise à l'échelle à mesure que la demande augmente.

Horizontal Pod Autoscaling (HPA)

La première étape de mise à l'échelle consiste à ajouter un HPA pour ajuster automatiquement le nombre de réplicas en fonction de la charge :

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

Prérequis : Le Metrics Server doit être installé (inclus par défaut dans k3s).

Impact : L'application s'adapte automatiquement entre 2 et 10 réplicas en fonction de la pression CPU/mémoire, sans modification du code.

Cluster multi-noeuds

Lorsqu'un seul noeud atteint ses limites de ressources, ajoutez des noeuds worker au cluster k3s :

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

Kubernetes planifie automatiquement les pods sur tous les noeuds disponibles. L'application ne nécessite aucune modification — elle est déjà sans état.

Affinité de noeud (optionnel)

Pour contrôler le placement des pods :

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

Cela répartit les réplicas sur différents noeuds pour une meilleure tolérance aux pannes.

Mise à l'échelle de la base de données

Pool de connexions

Ajoutez PgBouncer comme conteneur sidecar pour mutualiser les connexions à la base de données :

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

Le backend se connecte à PgBouncer sur :6432 au lieu de PostgreSQL directement, réduisant la surcharge des connexions.

Réplicas en lecture

Pour les charges de travail intensives en lecture (requêtes de flashcards), ajoutez la réplication en streaming PostgreSQL :

  1. L'instance principale gère les écritures (sessions d'étude, résultats de quiz)
  2. Les réplicas en lecture gèrent les lectures (requêtes kanji/vocabulaire)
  3. Le backend route les requêtes en fonction du type d'opération

Base de données managée

Le chemin de mise à l'échelle le plus simple pour la base de données est la migration vers un service managé :

  • AWS RDS : Multi-AZ, sauvegardes automatisées, réplicas en lecture
  • GCP Cloud SQL : Configuration HA, basculement automatique
  • Hetzner Managed PostgreSQL : Lorsqu'il sera disponible

Voir Portabilité pour les détails de migration.

Couche CDN

Les assets statiques du frontend peuvent être servis via un CDN pour des performances globales :

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

Puisque le frontend Flutter Web produit des fichiers statiques (JS, CSS, images), ce sont des candidats idéaux pour le CDN :

  • Politique de cache : 1 an pour les assets hashés, pas de cache pour index.html
  • PoP mondiaux : Contenu servi depuis le point de présence le plus proche
  • Protection DDoS : Le CDN absorbe les attaques volumétriques

Cloudflare DNS est déjà en place — l'activation du mode proxy active la couche CDN.

Feuille de route de la mise à l'échelle

Niveau de trafic Infrastructure Modifications clés
Actuel (faible) 1 noeud, 2 réplicas, PG unique Aucune nécessaire
Croissant (modéré) 1 noeud, HPA (2-10 réplicas) Ajouter le manifeste HPA
Élevé 2-3 noeuds, HPA, PgBouncer Ajouter des noeuds worker + pool de connexions
Très élevé Multi-noeuds, DB managée, CDN Migrer la DB vers RDS/Cloud SQL, activer le CDN
Mondial Clusters multi-régions, réplicas en lecture Évolution architecturale significative

Chaque étape est incrémentale — aucune réécriture n'est nécessaire. Le code applicatif reste inchangé à tous les niveaux de mise à l'échelle.