Consistency eventual dans la pratique
Eventual consistency (EC) est un modèle dans lequel les copies de données peuvent diverger temporairement, mais convergent au fil du temps sans coordination globale. C'est la clé de la haute disponibilité (AP par CAP) et de la faible latence (PACELC) si vous définissez correctement les invariants, les règles de merge et les garanties client.
1) Quand choisir l'EC (et quand - non)
Convient :- Fids, profils, likes/compteurs, répertoires/recherches, vues cachées.
- Systèmes globaux avec enregistrements locaux et invariants souples.
- Les projections (CQRS), où la source de la vérité est un noyau strict et les lectures sont asynchrones.
- Invariants durs : argent, singularité, limites, inventaire « ne pas aller dans le négatif ». C'est CR/plus fort que CE, saga/TSS.
2) Conception des données sous CE : conflits et leur résolution
Principe : chaque enregistrement porte des métadonnées de version et une fonction de fusion déterministe.
Horodatages/versioning : 'version', 't',' actor '.
L'horloge vectorielle : enregistre la causalité, permet de comprendre les « parallèles conflictuels ».
- LWW (Last-Write-Wins) : simple et rapide, mais peut perdre du « sens ».
- CRDT : structures commutatives/idempotentes, garantissent la convergence.
- Merge de domaine : une fonction d'entreprise (par exemple, combiner des listes sans doublons, résumer des compteurs, « le plus récent email + combiner des étiquettes »).
- Compteurs de → G-Counter/PN-Counter.
- Une pluralité de → OR-Set (suppression sans « bouffée »).
- Registres de → LWW-Register (attention aux « pertes »).
- Cartes/documents → Carte du CRDT.
- Édition conjointe → texte CRDT/OT.
3) Réplication et anti-entropie
Gossip/anti-entropy : échange périodique d'états/hachages entre nœuds.
Hinted handoff : « dépôt » temporaire d'un enregistrement pour un nœud inaccessible.
Read repair : à la lecture trouvé un désaccord - serré versions fraîches.
Paquets de changement (deltas) : nous chassons les deltas, pas les images complètes.
Quorums R/W : ajuster « R », « W », « N'à un compromis de vitesse et de fraîcheur (par exemple, » R + W> N'est plus proche de strong sur « dernier enregistrement »).
4) Garantie client au-dessus de la CE
Read-Your-Writes (RYW) : l'auteur, après son enregistrement, la voit (sticky-session/marquage version).
Monotonic Reads : Ne pas « reculer » le client sur une valeur plus ancienne (stocker le watermark de la dernière version).
Consistance causale : nous gardons la causalité dans la session/le flux d'actions (étiquettes vectorielles dans les titres/tokens).
Bounded Staleness : Garantie « pas plus de Δ t/N versions » pour les écrans critiques UX.
5) modèles UX pour EC
Apdates optimistes : nous reflétons instantanément l'action en marquant la « synchronisation ».
Marque de fraîcheur : badge « mis à jour X sec », bouton « Actualiser ».
Conflit-UI : pour les conflits rares - « afficher les deux versions et sélectionner/combiner ».
Squelette/placeholder + soft refresh : ne pas bloquer l'UI en attendant les quorums globaux.
6) Modèles architecturaux
6. 1 projections CQRS +
Write-core (CP) : invariants stricts.
Plan de lecture (EC) : projections asynchrones, index, caches ; lag est acceptable.
6. 2 Multi-région AP
Les enregistrements sont localement rapides, la réplication est asynchrone.
Géo-partitioning : les données « vivent » plus près de l'utilisateur ; les cross-region sont des agrégats.
Les fonctions CRDT/merge soulagent la douleur des conflits.
6. 3 Configuration de quorum
yaml consistency:
replicas: 3 # N write_quorum: 2 # W read_quorum: 2 # R => R + W> N, closer to freshness on "last record"
read_repair: true hinted_handoff: true
7) Politiques de versification et merge (exemple)
yaml entity: "profile"
versioning:
clock: "vector" # или "hybrid_time"
fields:
name: { merge: "lww" }
emails: { merge: "set_union" } # OR-Set tags: { merge: "or_set" }
likes: { merge: "pn_counter" }
conflict_ui:
enabled: true show_diff_for: ["name"]
auto_merge_for: ["emails","tags","likes"]
8) Observabilité CE : que mesurer
Staleness Age (p50/p95/p99) : 'now − data_version_ts' ou « nombre de versions en retard ».
Replication Lag : retard de livraison entre les régions/nœuds.
Taux conflict : proportion d'updates parallèles, répartition par type.
Taux de lecture/de réparation : à quelle fréquence et à quelle vitesse on « soigne » en lisant.
Temps de convergence : Temps avant la convergence après l'éclatement des enregistrements/défaillance du nœud.
SLO sémantique : « 95 % des profils ne dépassent pas 2c », « 99 % des fides convergent <10c ».
9) Runbook 'et les incidents
Scripts :1. Croissance lag interrégionale : réduire le 'write fan-out', inclure la lecture-réparation agressive, gâcher les écrivains lourds.
2. L'éclatement des conflits : inclure temporairement une règle plus « stricte » (par exemple, causal/RYW), limiter les mises à jour compétitives sur les clés chaudes.
3. Retard de projection : hiérarchiser les files d'attente de réplication, réduire temporairement la fréquence des updates non critiques.
4. Les données ont été « collées » sur une partie des nœuds : force-anti-entropie, réalance des lots, audit hinted handoff.
5. Analyse manuelle : déchargement des clés de conflit, outil « merge-preview », fix de batterie.
10) EC Test
Tests de type Jepsen : fractionnement du réseau, clock-skew, entrées répétées.
Property-based : invariants des fonctions merge (commutation, idempotence, associative).
Fuzz-conflits : updates parallèles par clé avec ordre de livraison variatif.
« Scies » de charge : alternance de tempêtes/calmes pour évaluer le temps de convergence.
Simulation UX : visibilité RYW/monotonic dans des scénarios typiques.
11) Multi-tenant et plans
Les balises 'tenant _ id/plan/region' dans les événements/enregistrements.
Fairness : limites de réplication/repair per tenant afin que le client « bruyant » n'augmente pas le staleness total.
Résidence : données et leurs répliques dans la juridiction ; les représentations croisées régionales ne sont que des agrégats.
12) Erreurs typiques
LWW « pour tout ». Perd les changements parallèles de sens ; utilisez CRDT/domaine merge.
Aucune garantie client. L'utilisateur « ne voit pas » son propre enregistrement → perte de confiance.
L'absence d'observation de l'obsolescence. Pas de métriques staleness/lag → « dégradation latente ».
Dual-write dans différents systèmes sans merge. Les fantômes et les divergences sont infinis.
L'ordre mondial à tout prix. Les quorums supplémentaires tuent p95 et les entreprises ont assez d'ordre local.
13) Recettes rapides
Feed/ruban : EC + causal/RYW pour l'auteur, CRDT pour les réactions, staleness p95 ≤ 2-5c.
Profils/paramètres : staleness bounded (≤1 -2c), RYW, merge de domaine (union d'ensembles).
Répertoire global : géo-partition, réplication asynchrone, lecture-réparation à la demande, conflits via OR-Set.
Métriques/compteurs : PN-Counter, consolidation en arrière-plan ; Afficher les valeurs « approximatives » marquées.
14) Mini-repère (schéma verbal)
Write-edge : enregistrement local avec version ('vector/hybride'), journal des événements.
Replication: очереди + gossip/anti-entropy, hinted handoff.
Stockage : lot par clé, fonction CRDT/merge au niveau de l'enregistrement.
Read-plane : caches avec read-repair, tokens RYW/monotonic, staleness bounded pour les écrans critiques.
Observability : Lags/obsolescence/conflits, alertes de dépassement de SLO Stailness.
15) Chèque-liste avant la vente
- Les invariants sont clairement décrits et où la CE est autorisée.
- Le versioning (vecteur/hybride) et les fonctions déterministes merge/CRDT sont sélectionnés.
- Des garanties client (RYW/monotonic/causal) ont été mises en œuvre pour les UX critiques.
- La réplication, read-repair, hinted handoff sont configurés ; les quorums R/W sont documentés.
- Métriques staleness/lag/convergence et alertes aux seuils p95/p99.
- Runbook "et sur l'augmentation des conflits/lenteurs ; outils de sécurité de merge manuel.
- Tests de séparation réseau, updates parallèles et propriété de convergence.
- Les limites multi-tenants et les politiques de résidence sont prises en compte.
- Les indicateurs UX de fraîcheur et de comportement fallback sont alignés avec le produit.
Conclusion
Eventual consistency n'est pas un « compromis de compromis », mais un outil d'évolutivité et de disponibilité. Si vous formalisez les invariants, choisissez des fonctions de merge correctes (de préférence CRDT le cas échéant), donnez des garanties client et mesurez la stailness et le temps de convergence, le système sera rapide, durable et honnête - pour les utilisateurs et les entreprises.