Qu'est-ce que le théorème CAP ?
Introduit par Eric Brewer en 2000, le théorème CAP (ou théorème de Brewer) est l'un des principes fondamentaux de la conception des systèmes distribués. Il stipule qu'il est impossible de satisfaire simultanément les trois propriétés suivantes : Cohérence (Consistency), Disponibilité (Availability) et Tolérance au partitionnement (Partition tolerance). Au mieux, un système peut en garantir deux à la fois.
Analyse approfondie des trois piliers du CAP
1. Cohérence (C)
La cohérence exige que tous les nœuds d'un système distribué voient les mêmes données au même moment. En pratique :
- Toute lecture renvoie la dernière écriture effectuée.
- Toutes les répliques sont synchronisées.
- Le client observe une vue cohérente indépendamment du nœud contacté.
// Exemple de cohérence forte via verrou distribué
public class ServiceCoherent {
private final VerrouDistribue verrou;
private final BaseDeDonnees bdd;
public void mettreAJour(String cle, String valeur) {
verrou.acquerir(cle);
try {
bdd.ecrire(cle, valeur);
attendreSynchronisation();
} finally {
verrou.liberer(cle);
}
}
public String lire(String cle) {
return bdd.lire(cle); // toujours la valeur la plus récente
}
}
2. Disponibilité (A)
La disponibilité garantit que le système répond à toute requête, même en cas de panne de certains nœuds. Cela implique :
- Les opérations de lecture/écriture sont toujours traitées.
- Les temps de réponse restent acceptables.
- Aucun refus de service dû à une indisponibilité.
// Exemple de haute disponibilité avec redondance
public class ServiceHautementDisponible {
private final Liste<Serveur> serveurs;
public Reponse traiterRequete(Requete requete) {
for (Serveur s : serveurs) {
try {
if (s.estEnSante()) {
return s.executer(requete);
}
} catch (Exception e) {
// journalisation et passage au suivant
continue;
}
}
throw new ServiceIndisponibleException("Aucun serveur disponible");
}
}
3. Tolérance au partitionnement (P)
La tolérance au partitionnement permet au système de continuer à fonctionner malgré une interruption de communication entre nœuds (partition réseau).
// Exemple de gestion d'une partition réseau
public class SystemeTolerantAuxPartitions {
public void gererPartition(PartitionReseau partition) {
if (partition.detectee()) {
activerModeDegrade();
continuerLeService();
} else {
fonctionnerNormalement();
}
}
}
Applications concrètes du théorème CAP
Systèmes CP (Cohérence + Tolérance au partitionnement)
Exemples : ZooKeeper, etcd, Consul
- Cohérence forte assurée.
- En cas de partition, la disponibilité peut être sacrifiée.
- Adapté à la gestion de configuration, la découevrte de services.
Systèmes AP (Disponibilité + Tolérance au partitionnement)
Exemples : Cassandra, DynamoDB, Riak
- Haute disponibilité garantie.
- Cohérence éventuelle plutôt que forte.
- Idéal pour les applications à fort débit.
// Exemple de cohérence éventuelle
public class MagasinCohérenceEventuelle {
private final Map<String, String> stock = new HashMap<>();
private final Liste<Replique> repliques;
public void ecrire(String cle, String valeur) {
stock.put(cle, valeur);
repliques.forEach(r -> r.repliquerAsync(cle, valeur));
}
public String lire(String cle) {
return stock.get(cle); // peut ne pas être la donnée la plus récente
}
}
Systèmes CA (Cohérence + Disponibilité)
Théoriquement possibles, mais irréalistes en pratique car tout système distribué doit gérer les partitions réseau.
Idées reçues sur le théorème CAP
Idée reçue 1 : « Il faut choisir deux propriétés sur trois »
En réalité, le théorème s'applique lorsqu'une partition réseau survient. En l'absence de partition, les trois propriétés peuvent coexister.
Idée reçue 2 : « Les partitions sont rares »
Dans les environnements cloud et les déploiements multi-régions, les partitions réseau sont bien plus fréquentes qu'on ne le pense.
Idée reçue 3 : « Le choix est binaire »
La plupart des systèmes offrent des niveaux de compromis nuancés entre cohérence et disponibilité.
Compromis CAP dans l'ingénierie réelle
Compromis temporels
Compromis selon le modèle de données
| Niveau de cohérence | Latence | Disponibilité | Cas d'usage |
|---|---|---|---|
| Cohérence forte | Élevée | Faible | Transactions financières |
| Cohérence éventuelle | Faible | Élevée | Réseaux sociaux |
| Cohérence causale | Moyenne | Moyenne | Édition collaborative |
Stratégies intelligentes de gestion des pannes
// Gestion adaptative selon le type d'opération
public class GestionnaireCAPIntelligent {
public Reponse traiter(Requete req) {
try {
if (estOperationCritique(req)) {
return traiterAvecCohérence(req);
} else {
return traiterAvecDisponibilité(req);
}
} catch (PartitionException e) {
return gererPartition(req, e);
}
}
private boolean estOperationCritique(Requete req) {
return req.getType().equals("financier") || req.getType().equals("configuration");
}
}
Pratiques modernes autour du CAP
Bases de données multi-modèles
Beaucoup de systèmes modernes offrent plusieurs niveaux de cohérence configurables :
# Exemple de configuration
cohérence:
défaut: éventuelle
surcharges:
- motif: "financier/*"
niveau: forte
- motif: "social/*"
niveau: éventuelle
- motif: "config/*"
niveau: linéarisable
Architectures hybrides
Combinaison de stratégies CAP selon les scénarios.
Systèmes adaptatifs
// Ajustement dynamique du niveau de cohérence
public class SystèmeAdaptatifCAP {
private NiveauCohérence niveauActuel = NiveauCohérence.FORTE;
public void ajusterCohérence(MétriquesRéseau métriques) {
if (métriques.getProbabilitéPartition() > 0.3) {
niveauActuel = NiveauCohérence.ÉVENTUELLE;
} else if (métriques.getLatence() > 100) {
niveauActuel = NiveauCohérence.FAIBLE;
} else {
niveauActuel = NiveauCohérence.FORTE;
}
}
public Reponse traiter(Requete req) {
return niveauActuel.exécuter(req);
}
}
Évolution du théorème CAP et perspectives
Théorème PACELC
Extension du CAP qui ajoute un compromis entre Latence (L) et Cohérence (C) en l'absence de partition :
- En cas de partition (P) → choix entre Disponibilité (A) et Cohérence (C).
- Sinon (Else) → choix entre Latence (L) et Cohérance (C).
Nouveaux modèles de cohérence
- Linéarisabilité
- Cohérence séquentielle
- Cohérence causale
Décisions CAP assistées par apprentissage automatique
# Optimisation par machine learning
class OptimiseurCAP_ML:
def __init__(self):
self.modele = charger_modele_cap()
def prédire_meilleure_stratégie(self, caractéristiques_requête):
prédiction = self.modele.prédire(caractéristiques_requête)
return self.stratégie_depuis_prédiction(prédiction)
Bonnes pratiques et recommandations
- Comprendre les besoins métier : chaque scénario impose des exigences CAP différentes.
- Conception par couches : appliquer des stratégies CAP distinctes à chaque niveau.
- Surveillance et adaptation : instrumenter le système et ajuster dynamiquement la configuration.
- Exercices de résilience : simuler régulièrement des partitions réseau.
| Type de scénario | Stratégie recommandée | Choix techniques |
|---|---|---|
| Transactions financières | CP | ZooKeeper, etcd |
| Réseaux sociaux | AP | Cassandra, DynamoDB |
| E‑commerce | Mixte | Redis + MySQL |
| Données IoT | AP | Kafka, InfluxDB |
Le théorème CAP n'est pas une contrainte, mais un guide. Un bon architecte de systèmes distribués sait :
- Quand rester rigoureux : cohérence forte pour les opérations critiques.
- Quand assouplir : cohérence éventuelle pour les usages non critiques.
- Comment assurer une transition fluide entre différents niveaux de cohérence.