Histoire de la question
Les entreprises qui s'étendent à l'échelle mondiale sont confrontées à des lois strictes sur la résidence des données comme le RGPD et le CCPA. Les bases de données monolithiques traditionnelles centralisent les données dans une seule région, ce qui enfreint la souveraineté ou entraîne une latence élevée. Les premiers systèmes distribués utilisaient la réplication active-passive, mais cela crée des points de défaillance uniques et des problèmes de latence d'écriture. Les architectures modernes doivent prendre en charge des régions multi-actives où les utilisateurs en UE, États-Unis et APAC peuvent écrire localement tout en respectant les contraintes de localisation des données.
Le problème
Le défi principal réside dans les compromis du théorème CAP. Vous ne pouvez pas avoir une forte cohérence entre les régions avec une faible latitude et une tolérance aux partitions simultanément. De plus, les relations de clés étrangères s'étendant sur des régions deviennent impossibles lorsque les données ne peuvent pas traverser les frontières. Les transactions inter-régionales risquent de violer la conformité en cas de fuite de DPI pendant la coordination. Maintenir des lectures inférieures à 100 ms nécessite un cache, mais l'invalidation du cache à travers des frontières souveraines est complexe.
La solution
Mettez en œuvre une Architecture basée sur des cellules utilisant la geo-partition basée sur la base de données (par ex. CockroachDB ou Google Cloud Spanner). Partitionnez les tables par colonne région, en veillant à ce que le DPI ne quitte jamais sa cellule physique. Utilisez Change Data Capture (CDC) via Apache Kafka pour répliquer uniquement les métadonnées non sensibles à l'échelle mondiale. Pour les transactions inter-régionales, implémentez le modèle Saga avec des compensations locales pour éviter les verrous distribués. Déployez des clusters Redis aux bords avec le modèle Cache-Aside pour les charges de travail à forte lecture, en utilisant l'invalidation basée sur le TTL pour éviter la coordination du cache inter-régionale.
Le contexte
Un processeur de paiement mondial devait se lancer en Allemagne et Singapour tout en maintenant son centre de données aux États-Unis. Les exigences réglementaires exigeaient que les historiques de transactions des utilisateurs de l'UE restent physiquement à Francfort, tandis que les données de l'APAC restent à Singapour. Cependant, les transferts transfrontaliers nécessitaient de déduire des fonds d'un compte États-Unis et de créditer un compte UE dans la même transaction logique, tout en maintenant les recherches de solde en dessous de 100 ms.
Solution 1 : Base de données centralisée avec répliques de lecture régionales
Cette approche hébergerait la base de données principale aux États-Unis-Est avec des répliques de lecture en UE et APAC, offrant un modèle de cohérence simple et de simples garanties ACID sans synchronisation complexe. Cependant, cela viole les lois sur la souveraineté des données car le trafic d'écriture est acheminé vers l'États-Unis-Est, ce qui peut persister le DPI de l'UE sur le sol des États-Unis, tandis que les écritures de Singapour encourent plus de 200 ms de latence, ce qui ne répond pas aux exigences d'expérience utilisateur. L'architecture crée également un point de défaillance unique dans l'États-Unis-Est, ce qui la rend inacceptable pour une plateforme de paiement mondial nécessitant une autonomie régionale.
Solution 2 : Silos régionaux entièrement isolés avec ETL nocturne
Ce design fonctionne avec des clusters PostgreSQL indépendants dans chaque région, traitant les transferts inter-régionaux pendant les fenêtres de maintenance nocturnes pour garantir une isolation de conformité parfaite et une simple autonomie régionale. Cette approche ne prend pas en charge les paiements internationaux en temps réel, créant une mauvaise expérience utilisateur et rendant les erreurs de rapprochement difficiles à annuler pendant le traitement par lots. De plus, l'architecture ne peut pas gérer des agrégations de solde de compte global sans délai significatif, la rendant inadaptée pour une plateforme fintech moderne.
Solution 3 : Base de données geo-partitionnée avec orchestration de saga
Cette stratégie déploie CockroachDB avec des tables geo-partitionnées utilisant un mappage de partition_key vers les régions d'origine des utilisateurs, mettant en œuvre un flux de travail Temporal pour gérer les transferts inter-régionaux comme des transactions locales avec des actions compensatoires. Ce design impose une résidence des données native à travers des contraintes de partition tout en atteignant des lectures locales de moins de 50 ms grâce à des détenteurs de baux attachés à des nœuds régionaux, bien qu'il introduise une complexité opérationnelle nécessitant une expertise SQL distribuée. La solution gère la cohérence éventuelle pour les métadonnées inter-régionales via des flux Kafka CDC et gère l'incohérence temporaire pendant l'exécution de la saga grâce à une visibilité d'état en attente basée sur le TTL.
Approche choisie
L'équipe a sélectionné la Solution 3 car elle répondait de manière unique à la fois aux contraintes de conformité et de latence sans sacrifier les sémantiques transactionnelles ou nécessiter des migrations de données destructrices. Ils ont configuré des tables REGIONAL BY ROW de CockroachDB en pinçant les lignes de l'UE aux nœuds de Francfort, déployé un Cluster Redis aux emplacements de bord avec un TTL de 5 secondes pour le cache de métadonnées, et mis en œuvre des sagas Temporal pour orchestrer les transferts inter-régionaux avec des compensations automatiques en cas d'échec.
Résultat
Le système a réussi les audits RGPD avec zéro fuite de DPI transfrontalière tout en traitant 50 000 transactions inter-régionales par jour avec une latence de lecture au 99e percentile de 45 ms. Les équipes de support client pouvaient interroger les états de saga en attente via des points de terminaison API pour résoudre les incohérences transitoires lors des pannes régionales. L'architecture prend maintenant en charge l'expansion dans de nouveaux marchés simplement en ajoutant de nouvelles cellules au cluster CockroachDB sans changements d'application.
Comment maintenez-vous l'intégrité référentielle lorsqu'une relation de clé étrangère s'étend sur deux zones de souveraineté des données ?
Vous ne pouvez pas appliquer des contraintes de clé étrangère au niveau de la base de données entre les régions lorsque les données ne peuvent pas quitter physiquement leur zone. Implémentez l'intégrité référentielle au niveau de l'application en utilisant des références UUID et une validation asynchrone via le Outbox Pattern publiant sur Kafka ; les consommateurs vérifient les références et publient des accusés de réception, avec détection des orphelins après des délais d'attente. Cela sacrifie la cohérence immédiate pour la conformité mais garantit une intégrité éventuelle sans migration de données, utilisant des compensations Saga pour annuler les transactions faisant référence à des clés étrangères invalides.
Que se passe-t-il avec les transactions en cours lorsque une région échoue pendant une saga inter-régionale ?
Les modèles Saga ne gèrent pas automatiquement les échecs ; vous devez concevoir pour l'idempotence en utilisant des clés d'idempotence stockées dans Redis ou Etcd local à chaque région pour éviter un traitement en double lors des reprises. Si la région B échoue pendant une opération de crédit, les délais d'attente de l'orchestrateur déclenchent des transactions compensatoires dans la région A pour rembourser les montants déduits, utilisant des Verrous Consultatifs PostgreSQL ou des Verrous Distribués ZooKeeper pour prévenir les conditions de course pendant le basculement de l'orchestrateur. Le système doit exposer les états de transaction en attente via des points de terminaison API pour l'intervention du support client, garantissant que les états de défaillance partielle restent interrogeables et résolubles sans corruption des données.
Comment effectuez-vous des migrations de schéma sans temps d'arrêt à travers des cellules geo-partitionnées avec différentes fenêtres de maintenance ?
Employez le modèle Expand-Contract combiné avec des Feature Flags gérés par LaunchDarkly, déployant d'abord des changements DDL additifs (nouvelles colonnes, tables) dans toutes les régions pendant leurs fenêtres respectives en utilisant Flyway ou Liquibase tout en maintenant les applications compatibles en arrière. Migrez les données de manière asynchrone à l'aide de pipelines Debezium CDC, puis activez de nouvelles voies de code via des caractéristiques uniquement après avoir confirmé la propagation du schéma via des vérifications de santé, garantissant qu'aucune région ne diffuse des données obsolètes. N'effectuez jamais de DDL destructives (suppression de colonnes) jusqu'à ce que toutes les régions confirment l'achèvement de la migration, en utilisant des déploiements Blue-Green au sein de chaque cellule pour revenir immédiatement en arrière si le retard de réplication dépasse les seuils.