GH GambleHub

Réplication et consistance eventuelle

Réplication et consistance eventuelle

1) Pourquoi la consistance eventual

Lorsque le système est réparti entre les zones/régions, l'écriture synchrone donne partout une latence élevée et une faible disponibilité en cas de défaillance du réseau. Eventual consistency (EC) permet la dissynchronisation temporaire des répliques pour :
  • un retard d'écriture faible (réception locale),
  • une meilleure disponibilité dans les divisions du réseau,
  • mise à l'échelle horizontale.

La tâche clé est la cohérence non rigoureuse contrôlée : l'utilisateur voit des données « assez récentes », les invariants du domaine sont conservés, les conflits sont détectés et résolus de manière prévisible.


2) Modèles de cohérence - ce que nous promettons au client

Strong : la lecture voit immédiatement la dernière entrée.
Bounded stale/read-not-older-than (RNOT) : lecture qui ne vieillit pas (LSN/version/heure).
Causal : les relations « causales » (A à B) sont maintenues.
Read-Your-Writes : le client voit ses enregistrements récents.
Monotonic Reads : chaque lecture suivante ne « recule » pas.
Session : ensemble de garanties en une seule session.
Eventual : En l'absence de nouveaux enregistrements, toutes les répliques convergent.

Pratique : combiner Session + RNOT sur les chemins critiques et Eventual sur les vitrines/caches.


3) Réplication : Mécanique et anti-entropy

Synchrone (quorum/RAFT) : l'enregistrement est considéré comme réussi après confirmation par N noeuds ; RPO minimum, supérieur à p99.
Asynchrone : le leader du commit localement, distribue le journal plus tard ; faible latence, RPO> 0.
Physique (WAL/binlog) : rapide, homogène.
Logique/CDC : flux de changements au niveau des lignes/événements, routage flexible, filtres.
Anti-entropy : rapprochements périodiques et réparations (Merkle-arbres, comparaison des hachages, re-sync de fond).


4) Identifiants de version et ordres de causalité

Versions monotones : incret/LSN/epoch ; c'est simple, mais ils ne codent pas le parallélisme.
Lamport timestamp : ordre partiel par horloge logique.
Vector clock : fixe les branches parallèles et permet de détecter les updates de conflit (concurrent).
Hybrid/TrueTime/Clock-SI : logique « pas avant T » pour l'ordre global.

Recommandation : pour le CRDT/les Updates de conflit - clock vecteur ; pour « ne pas vieillir » - LSN/GTID.


5) Conflits : Détection et résolution

Situations types : entrée de deux régions à un même objet.

Stratégies :

1. Last-Write-Wins (LWW) par timbre horaire/logique - simple, mais peut « perdre » les updates.

2. Fonction merge par logique de domaine :
  • les champs compteurs sont pliés (G-Counter/PN-Counter),
  • les ensembles sont combinés avec « add-wins/remove-wins »,
  • montants/soldes - seulement par le biais de journaux transactionnels, pas par le biais d'un simple LWW.
  • 3. CRDT (types convergents) : G-Counter, OR-Set, LWW-Register, RGA pour les listes.
  • 4. Transformations opérationnelles (rarement pour les OBD, plus souvent pour les éditeurs).
  • 5. Manual resolution : conflit dans « inbox », l'utilisateur sélectionne la version correcte.

Règle : les invariants du domaine dictent la stratégie. Pour l'argent/les soldes - éviter LWW ; utiliser les transactions/événements rémunérés.


6) Garanties d'enregistrement et d'idempotence

Les clés idempotent sur les commandes (payment, withdraw, create) → la répétition sont sécurisées.
Déduplication sur « inbox » et « outbox » par clé d'idempotence/numéro de série.
Exactly-once est impossible à atteindre sans conditions préalables solides ; pratiquez l'at-least-once + idempotence.
Outbox/Inbox-pattern : l'enregistrement dans la base de données et la publication de l'événement est atomique (transaction locale), le destinataire traite par idempotency-key.


7) Lectures « pas vieux X » (RNOT)

Techniques :
  • Gate LSN/GTID : le client transmet la version minimale (de la réponse d'enregistrement), le routeur/proxy dirige vers la réplique qui a rattrapé LSN ≥ X, sinon vers le leader.
  • Time-bound : « ne vieillit pas 2 secondes » est un SLA simple sans versions.
  • Session pinning : après avoir enregistré N secondes, nous ne lisons que le leader (Read-Your-Writes).

8) Flux de changement et harmonisation des caches

CDC → bus d'événements (Kafka/Pulsar) → consommateurs (caches, indices, vitrines).
Invalidation des caches : « invalidate : {ns} : {id} » ; traitement idempotent.
Rebuild/Backfill : si vous êtes dissynchrone, recréez les projections du journal des événements.


9) Sagas et compensations (transactions interservices)

Dans le monde EC, les opérations à longue durée de vie se décomposent en étapes avec des actions compensatoires :
  • Orchestration : le coordinateur évoque les étapes et leur compensation.
  • Chorégraphie : les étapes réagissent aux événements et publient elles-mêmes les suivantes.

Invariants (exemple) : « Balance ≥ 0 » - vérification aux frontières de l'étape + compensation en cas de déviation.


10) Multi-région et les divisions de réseau

Local-write, async-replicate : entrée dans la région locale + livraison à d'autres (EC).
Géo-fencing : les données sont « collées » à la région (faible latence, moins de conflits).
OBD quorum (Raft) pour les données CP ; caches/vitrines - AP/CE.
Plan split-brain : en cas de perte de connectivité, les régions continuent de fonctionner dans les limites du domaine (write fencing, quotas), puis reconcile.


11) Observabilité et SLO

Métriques :
  • Replica lag : temps/distance LSN/offset (p50/p95/p99).
  • Staleness : taux de réponse supérieur au seuil (par exemple> 2s ou LSN
  • Conflict rate : fréquence des conflits et du succès merge.
  • Temps de convergence : temps de convergence des répliques après le pic.
  • Backlog reconcile : volume/temps des lots en retard.
  • RPO/RTO par catégorie de données (CP/AP).
Alert :
  • Lag> cible, augmentation des conflits, fenêtres « longues » de l'impossibilité.

12) Conception d'un schéma de données sous CE

Version explicite/vecteur dans chaque entrée (colonnes 'version', 'vc').
Revues Append-only pour les invariants critiques (bilans, charges).
ID d'événement (snowflake/ULID) pour ordre et déduplication.
Les champs à nature commutative (compteurs, multiples) → les candidats au CRDT.
Conception de l'API : PUT avec if-match/etag, PATCH avec precondition.


13) Modèles de stockage et de lecture

Modèle de lecture/CQRS : écriture dans « source », lecture à partir des projections (peut être en retard → afficher « mise à jour »...).
Stale-OK itinéraires (catalogue/ruban) vs Strict (portefeuille/limites).
Sticky/Bounded-stale drapeaux dans la requête (en-tête « x-read-consistency »).


14) Chèque de mise en œuvre (0-45 jours)

0-10 jours

Catégoriser les données : CP-critiques (argent, commandes) vs EU/stale-OK (catalogues, indices de recherche).
Définissez les SLO du steel (p. ex., « ne pas vieillir 2s »), les taux cibles.
Activer le versioning des objets et des clés idempotency dans l'API.

11-25 jours

Mettre en œuvre CDC et outbox/inbox, itinéraires de cache handicapé.
Ajouter RNOT (LSN-gate) et session pinning à l'enregistrement des chemins critiques.
Mettre en œuvre au moins une stratégie merge (LWW/CRDT/domaine) et un journal des conflits.

26-45 jours

Automatiser les rapports anti-entropy (rapprochements/réparations) et steel.
Passer la journée de jeu : fractionnement du réseau, éclatement des conflits, récupération.
Visualiser sur dashboards : lag, staleness, conflict rate, convergence.


15) Anti-modèles

LWW aveugle pour les invariants critiques (perte d'argent/points).
L'absence d'idempotentialité → la prise des opérations de rétractation.
Le modèle « fort » sur tout → les queues excessives p99 et la fragilité en cas de défaillance.
Il n'y a pas de garantie RNOT/Session → UX « clignote », les utilisateurs « ne voient pas » leurs changements.
Dissynchronisation latente du cache et de la source (pas de CDC/invalidation).
L'absence d'outil reconcile/anti-entropy - les données « depuis des siècles » divergent.


16) Métriques de maturité

Replica lag p95 ≤ cible (par exemple, ≤ 500 ms à l'intérieur de la région, ≤ 2 s interregions).
Staleness SLO exécute ≥ 99 % des demandes sur des itinéraires « stricts ».
Conflict resolution success ≥ 99. 9 %, temps de résolution moyen ≤ 1 min.
Temps de convergence après les pics - minutes, pas heures.
100 % des transactions « monétaires » sont couvertes par des clés d'identité et outbox/inbox.


17) Recettes (extraits)

If-Match/ETag (HTTP)


PUT /profile/42
If-Match: "v17"
Body: { "email": "new@example.com" }

Si la version a changé - '412 Precondition Failed' → le client résout le conflit.

Demande « pas vieux LSN » (pseudo)


x-min-lsn: 16/B373F8D8

Rowther sélectionne une réplique avec 'replay _ lsn ≥ x-min-lsn', sinon le leader.

CRDT G-Counter (idée)

Chaque région conserve son compteur ; le total est la somme de tous les éléments ; réplication - opération commutative.


18) Conclusion

Eventual consistency n'est pas un compromis de qualité, mais un contrat éclairé : quelque part, nous payons la fraîcheur pour la rapidité et l'accessibilité, mais nous protégeons les invariants critiques avec des stratégies et des outils de domaine. Entrez les versions, idempotency, RNOT/Session garantie, CDC et anti-entropy, mesurer lag/staleness/conflicts - et votre système distribué sera rapide, durable et prévisible convergent même sous les pannes et les charges de pointe.

Contact

Prendre contact

Contactez-nous pour toute question ou demande d’assistance.Nous sommes toujours prêts à vous aider !

Commencer l’intégration

L’Email est obligatoire. Telegram ou WhatsApp — optionnels.

Votre nom optionnel
Email optionnel
Objet optionnel
Message optionnel
Telegram optionnel
@
Si vous indiquez Telegram — nous vous répondrons aussi là-bas.
WhatsApp optionnel
Format : +code pays et numéro (ex. +33XXXXXXXXX).

En cliquant sur ce bouton, vous acceptez le traitement de vos données.