Cohérence, disponibilité, partition
Ce que ce chapitre apporte
- Énoncer les propriétés ACID et dire ce que chacune garantit.
- Définir une partition réseau et la distinguer d'une panne.
- Énoncer correctement le théorème CAP, et repérer les formulations fautives.
- Décrire les propriétés BASE et la cohérence à terme.
- Calculer si un réglage de quorum garantit ou non la lecture de la dernière écriture.
- Choisir un compromis à partir du besoin métier plutôt que de la mode technique.
Une base sur une seule machine tient une promesse simple : ce qui vient d'être écrit sera lu. Répartir les données sur plusieurs machines rend cette promesse coûteuse, et un jour impossible. Le théorème CAP dit exactement quand, et il est presque toujours cité de travers. Il n'oblige à renoncer à rien tant que le réseau fonctionne ; il impose un choix pendant les quelques secondes où il ne fonctionne plus.
Le chapitre précédent a réparti les données sur des machines qui tombent en panne, et a réglé la question de la durabilité : avec trois copies, rien n'est perdu. Il a laissé de côté une question plus difficile. Quand une donnée existe en trois exemplaires et qu'une écriture arrive, que lit celui qui interroge la deuxième copie avant qu'elle ne soit à jour ?
Cette question n'a pas de bonne réponse universelle. Elle a des réponses, chacune payée d'un prix connu, et le rôle du concepteur est de choisir lequel.
Ce que garantit une transaction
Atomicité. Une transaction s'applique en entier ou pas du tout. Un virement ne peut pas débiter sans créditer.
Cohérence. Une transaction fait passer la base d'un état valide à un autre état valide, au sens des contraintes déclarées : clés étrangères, unicité, vérifications.
Isolation. Deux transactions simultanées produisent le même résultat que si elles s'étaient exécutées l'une après l'autre.
Durabilité. Une transaction validée survit à une coupure de courant.
Ces quatre propriétés sont l'acquis du parcours sur les bases de données, et elles ont un coût qui ne se voit pas sur une machine unique : elles exigent une coordination. L'isolation impose des verrous ou un contrôle de version ; la durabilité impose une écriture réellement descendue sur le disque avant de répondre.
Le C d'ACID signifie que les contraintes déclarées sont respectées : pas de clé étrangère orpheline, pas de doublon sur une clé unique.
Le C de CAP signifie que toutes les copies répondent la même chose au même instant, c'est-à-dire que le système se comporte comme s'il n'en existait qu'une.
Un système peut respecter l'un sans l'autre. La confusion des deux est la source d'une bonne moitié des affirmations fausses sur le sujet.
Ce qu'est une partition
Il y a partition quand des machines du système ne peuvent plus communiquer entre elles, alors qu'elles fonctionnent toutes.
Ce n'est pas une panne : aucune machine ne s'est arrêtée, aucune donnée n'est perdue. Le groupe s'est simplement scindé en deux moitiés qui continuent chacune de travailler, sans savoir ce que fait l'autre.
Une machine qui ne répond pas peut être arrêtée, saturée, ou séparée par le réseau. De l'extérieur, les trois cas sont identiques : il ne se passe rien.
Le système doit pourtant décider, après un délai qu'il fixe lui-même, si l'autre est morte ou seulement injoignable. Attendre plus longtemps améliore la justesse de la décision et dégrade le temps de réponse pour tout le monde.
C'est pourquoi une partition n'est pas un événement rare et exceptionnel : à l'échelle d'un cluster, un délai d'attente dépassé est une partition, et cela arrive tous les jours.
Le théorème CAP, énoncé correctement
Dans un système réparti, en présence d'une partition réseau, il faut choisir entre :
la cohérence, en refusant de répondre du côté qui n'est pas sûr d'être à jour,
la disponibilité, en répondant quand même, au risque de rendre une donnée périmée.
La tolérance aux partitions n'est pas un troisième choix : elle est subie. Un réseau finit toujours par se couper.
La formule est commode et trompeuse, pour deux raisons.
D'abord, P ne se choisit pas. Renoncer à la tolérance aux partitions reviendrait à affirmer que le réseau ne se coupera jamais, ce qui n'est vrai d'aucun réseau. Un système réparti est donc toujours P, et le choix se réduit à deux options, pas à trois.
Ensuite, le choix ne s'applique que pendant la partition. Hors partition, un système peut parfaitement être cohérent et disponible en même temps, et c'est ce qu'il fait 99,9 % du temps. Décrire une base comme « AP » ne dit donc rien de son comportement ordinaire, seulement de ce qu'elle fait pendant les quelques secondes où le réseau se coupe.
Un raffinement du théorème, appelé PACELC, complète l'énoncé : si une partition survient (P), choisir entre disponibilité (A) et cohérence (C) ; sinon (E, pour else), choisir entre latence (L) et cohérence (C).
La seconde moitié est celle qui compte au quotidien. Hors partition, garantir que toutes les copies répondent la même chose exige d'attendre qu'elles se soient parlé, donc d'ajouter de la latence à chaque opération. Le vrai arbitrage n'est pas « cohérence ou disponibilité » mais cohérence ou temps de réponse, et il se pose à chaque requête.
BASE, et la cohérence à terme
Basically Available : le système répond, y compris de façon dégradée, plutôt que de refuser.
Soft state : l'état peut changer sans écriture, simplement parce que les copies se synchronisent en arrière-plan.
Eventually consistent : en l'absence de nouvelle écriture, toutes les copies finissent par converger vers la même valeur.
L'acronyme est un jeu de mots, acide contre base, et il ne faut pas y voir un modèle rigoureux. Il désigne une famille de compromis, dont le plus important est la cohérence à terme.
La cohérence à terme garantit la convergence, pas sa rapidité. En pratique le délai se compte en millisecondes ; pendant une partition, il se compte en minutes, et rien dans la définition ne l'interdit.
Elle ne garantit pas non plus l'ordre dans lequel les lectures voient les valeurs. Sans précaution, un utilisateur peut lire une valeur récente, puis la valeur précédente, parce que ses deux lectures sont tombées sur des copies différentes. C'est déroutant, et c'est conforme.
Des garanties intermédiaires existent, et sont ce qu'il faut réclamer plutôt que la cohérence forte :
lire ses propres écritures, pour que celui qui vient de modifier voie sa modification ;
lectures monotones, pour ne jamais reculer dans le temps ;
écritures ordonnées, pour que deux modifications successives s'appliquent dans l'ordre.
Les quorums, ou comment acheter la cohérence
La cohérence n'est pas un interrupteur mais un réglage, et ce réglage se calcule. Une donnée est écrite sur N copies ; une écriture est confirmée quand W copies ont répondu ; une lecture interroge R copies et retient la plus récente.
Si le nombre de copies lues plus le nombre de copies écrites dépasse le nombre total de copies, alors les deux ensembles se recoupent forcément : la lecture touche au moins une copie à jour, et la reconnaît à son horodatage.
Sous cette condition, aucune coordination supplémentaire n'est nécessaire. Au-dessus, la garantie est acquise ; en dessous, elle ne l'est pas, et aucune configuration ne la rattrape.
Trois réglages méritent un nom, parce qu'ils correspondent à des choix courants.
| Réglage | R + W | Ce qu'on obtient | Ce qu'on paie |
|---|---|---|---|
| W = 1, R = 1 | 2 | écriture et lecture très rapides, disponibles tant qu'une copie répond | aucune garantie de fraîcheur |
| W = 2, R = 2 | 4 | dernière écriture garantie, tolère une panne des deux côtés | latence de deux réponses à chaque opération |
| W = 3, R = 1 | 4 | dernière écriture garantie, lecture minimale | l'écriture échoue dès qu'une copie est injoignable |
Rien n'oblige à retenir le même compromis partout. Dans une même application, l'enregistrement d'un paiement demande W = 3, l'incrément d'un compteur de vues se contente de W = 1, et l'affichage d'un catalogue tolère parfaitement une lecture périmée de quelques secondes.
La question à poser n'est donc jamais « cette base est-elle cohérente ? » mais « que coûte, pour cette opération précise, de lire une valeur vieille de deux secondes ? ». Sur un solde bancaire, cela coûte cher. Sur un nombre de vues, cela ne coûte rien.
Quand deux copies divergent
Un système qui accepte des écritures des deux côtés d'une partition se retrouve, à la réconciliation, avec deux versions d'une même donnée. Il faut trancher, et trois stratégies existent.
La dernière écriture gagne. On compare les horodatages et on garde le plus récent. Simple, et faux dès que les horloges des machines diffèrent, ce qui est toujours le cas. Une écriture est perdue silencieusement.
Le conflit est signalé. Le système conserve les deux versions et les rend toutes les deux à la lecture suivante, à charge pour l'application de choisir. Honnête, et exigeant.
La structure absorbe le conflit. Certaines structures de données sont conçues pour fusionner sans ambiguïté : un compteur qui ne fait qu'augmenter, un ensemble où l'on n'ajoute jamais qu'après avoir retiré. La fusion devient alors un calcul, et non une décision.
Le rapprochement avec le chapitre sur le découpage est direct. Une donnée qui se fusionne sans arbitrage est une donnée dont l'opération de fusion est associative et commutative, exactement comme une réduction qui se recolle. Ce n'est pas une coïncidence : dans les deux cas, il s'agit de recombiner des résultats partiels sans savoir dans quel ordre ils sont arrivés.
Exercices type
Exercice 1 : un système est décrit comme « CP ». Que fait-il quand le réseau se coupe, et que fait-il le reste du temps ?
Afficher la solution
Pendant la partition, il privilégie la cohérence : le côté qui n'est pas sûr d'être à jour refuse de répondre, et renvoie une erreur plutôt qu'une donnée périmée. Une partie des clients est donc sans service pendant la coupure.
Le reste du temps, l'étiquette ne dit rien. Un système CP peut être rapide ou lent hors partition, selon qu'il attend ou non la confirmation de toutes les copies avant de répondre. C'est le second arbitrage de PACELC, et c'est celui qui décide de la latence perçue au quotidien.
Décrire un système par deux lettres est donc insuffisant : il faut connaître les deux arbitrages, pas un seul.
Exercice 2 : cinq copies, écriture confirmée par trois, lecture sur deux. La dernière écriture est-elle garantie ?
Afficher la solution
R + W vaut 5, N vaut 5. La condition demande R + W strictement supérieur à N, donc 5 > 5 est faux : la garantie n'est pas acquise.
L'intuition le confirme. Les trois copies écrites et les deux copies lues peuvent être disjointes : il existe des ensembles de trois et de deux copies parmi cinq qui ne se recoupent pas. La lecture peut alors ne voir que des copies périmées.
Passer la lecture à trois copies donne R + W = 6 > 5 et rétablit la garantie, au prix d'une réponse de plus à attendre.
Exercice 3 : un compteur de vues est incrémenté sur deux copies pendant une partition, de 100 à 105 d'un côté et de 100 à 103 de l'autre. Que doit valoir le compteur après réconciliation, et que donne la stratégie de la dernière écriture ?
Afficher la solution
La bonne réponse est 108 : cinq vues d'un côté, trois de l'autre, huit en tout.
La stratégie de la dernière écriture donne 105 ou 103 selon les horloges, et perd donc entre trois et cinq incréments sans rien signaler.
Le remède est structurel et non procédural. Un compteur qui retient, par copie, le nombre d'incréments qu'elle a vus se fusionne en additionnant les contributions de chaque copie, et le résultat ne dépend ni de l'ordre ni des horloges. C'est précisément une opération associative et commutative, comme une réduction qui se recolle.
Exercice 4 : dans une application de réservation de places, quel compromis retenir pour la consultation du nombre de places restantes, et pour la réservation elle-même ?
Afficher la solution
Deux opérations, deux compromis, dans la même application.
La consultation tolère une valeur périmée de quelques secondes : afficher « 12 places » alors qu'il en reste 11 n'a aucune conséquence. Lecture sur une copie, réponse immédiate, disponibilité maximale.
La réservation ne tolère rien : deux clients ne doivent pas obtenir la même place. Elle exige une coordination réelle, donc un quorum satisfaisant R + W > N, et l'acceptation de refuser le service pendant une partition plutôt que de vendre deux fois le même siège.
C'est le cas général : une application n'a pas un compromis, elle en a un par opération, et les mélanger revient soit à payer une cohérence inutile, soit à vendre deux fois la même place.
1.Qu'est-ce qu'une partition réseau ?
2.Pourquoi « choisir deux propriétés sur trois » est-il une formulation fautive du théorème CAP ?
3.Le C d'ACID et le C de CAP désignent…
4.Cinq copies, écriture sur trois, lecture sur deux. La dernière écriture est-elle lue ?
5.Que garantit exactement la cohérence à terme ?
6.Deux copies ont incrémenté un compteur pendant une partition. Quelle stratégie de réconciliation conserve tous les incréments ?
La méthode
- Poser la question par opération, jamais par base : que coûte ici une valeur vieille de deux secondes ?
- Traiter la partition comme un événement ordinaire, pas comme un incident rare.
- Ne jamais décrire un système par deux lettres sans dire aussi ce qu'il fait hors partition.
- Calculer R + W > N plutôt que de faire confiance à un réglage par défaut.
- Réclamer les garanties intermédiaires utiles, « lire ses propres écritures » et « lectures monotones », plutôt que la cohérence forte.
- Se méfier des horodatages pour arbitrer : les horloges de deux machines ne coïncident jamais.
- Choisir une structure qui fusionne toute seule quand la donnée s'y prête, plutôt qu'une règle d'arbitrage.
Synthèse
- ACID garantit atomicité, cohérence des contraintes, isolation et durabilité, au prix d'une coordination.
- Une partition n'est pas une panne : les machines fonctionnent, elles ne se parlent plus.
- Une partition ne se distingue pas d'une lenteur : c'est le délai d'attente qui décide, et il se dépasse tous les jours.
- Le théorème CAP impose de choisir entre cohérence et disponibilité pendant la partition, et rien d'autre.
- P est subie, pas choisie : la formulation « deux sur trois » est fautive.
- PACELC ajoute l'arbitrage du quotidien : hors partition, cohérence contre latence.
- Le C d'ACID et le C de CAP ne désignent pas la même chose.
- BASE décrit une famille de compromis dont le principal est la cohérence à terme.
- La cohérence à terme ne borne ni le délai ni l'ordre des lectures.
- R + W > N garantit de lire la dernière écriture, et se calcule au lieu de se supposer.
- Le compromis se choisit par opération, pas par base : un solde et un compteur de vues n'ont pas les mêmes exigences.
- « La dernière écriture gagne » perd des données silencieusement, faute d'horloges communes.
- Une structure dont la fusion est associative et commutative se réconcilie sans arbitrage, comme une réduction se recolle.