Clusters et parallélisme¶
Passer d'une machine a plusieurs — architectures, lois de scaling et calcul haute performance.
Pourquoi les clusters¶
Un serveur unique, même puissant, a des limites physiques : nombre de cœurs, quantite de RAM, débit I/O. Quand ces limites sont atteintes, deux options existent : acheter une machine plus grosse (scale-up) ou ajouter des machines (scale-out). Le cluster est la réponse scale-out.
Un cluster est un ensemble de machines indépendantes (nœuds) qui cooperent pour fournir un service. L'architecture interne du cluster — comment les nœuds partagent (ou non) les ressources — détermine ses propriétés de performance, de disponibilité et de complexité.
Shared-nothing vs shared-disk¶
Chevance (Serveurs multiprocesseurs, clusters et architectures parallèles) distingue deux grandes familles d'architectures de clusters.
Shared-nothing¶
Chaque nœud possédé son propre processeur, sa propre mémoire et son propre stockage. Les nœuds communiquent uniquement par messages réseau. Aucune ressource n'est partagee.
graph TB
subgraph "Noeud 1"
C1["CPU"] --> M1["RAM"]
M1 --> D1["Disque"]
end
subgraph "Noeud 2"
C2["CPU"] --> M2["RAM"]
M2 --> D2["Disque"]
end
subgraph "Noeud 3"
C3["CPU"] --> M3["RAM"]
M3 --> D3["Disque"]
end
D1 --reseau--> D2
D2 --reseau--> D3 Shared-disk¶
Tous les nœuds accedent a un stockage partage (SAN, NAS). Chaque nœud a son propre CPU et sa propre RAM, mais le disque est commun.
graph TB
subgraph "Noeud A"
CA["CPU"] --> MA["RAM"]
end
subgraph "Noeud B"
CB["CPU"] --> MB["RAM"]
end
subgraph "Noeud C"
CC["CPU"] --> MC["RAM"]
end
MA --> SAN["Stockage partage (SAN)"]
MB --> SAN
MC --> SAN Comparaison¶
| Critère | Shared-nothing | Shared-disk | Hybride |
|---|---|---|---|
| Scalabilité | Excellente (lineaire) | Limitee par le stockage | Variable |
| Complexité | Partitionnement des données | Gestion des locks distribués | Les deux |
| Disponibilité | Panne d'un nœud = perte partielle | Panne stockage = panne totale | Dépend |
| Exemples | Cassandra, Kafka, CockroachDB | Oracle RAC, GPFS | Ceph, HDFS |
| Performance I/O | Locale, rapide | Réseau, plus lent | Variable |
Note
Le modèle shared-nothing domine le cloud moderne. Quand on deploie sur AWS, GCP ou Azure, chaque instance est indépendante par défaut — il n'y a pas de SAN partage. Les architectures cloud-native (microservices, bases distribuées) sont fondamentalement shared-nothing. Le shared-disk subsiste dans les environnements on-premise ou la cohérence forte est prioritaire (Oracle RAC pour les systèmes financiers).
Loi d'Amdahl¶
La loi d'Amdahl quantifie le speedup maximal d'un programme quand on ajoute des processeurs. Si une fraction s du programme est strictement séquentielle, le speedup maximal avec N processeurs est :
Quand N tend vers l'infini :
| Fraction séquentielle (s) | Speedup max (N infini) | Speedup avec 16 cœurs |
|---|---|---|
| 1% | 100x | 14.4x |
| 5% | 20x | 10.1x |
| 10% | 10x | 6.4x |
| 25% | 4x | 3.0x |
| 50% | 2x | 1.9x |
Warning
La loi d'Amdahl est impitoyable. Avec 10% de code séquentiel, on ne depassera jamais un speedup de 10x — même avec 1000 cœurs. Avant de scaler horizontalement, il faut mesurer la fraction séquentielle du système. Un lock global, une écriture synchrone en base, un appel API bloquant — tout cela contribue à la fraction séquentielle.
Ou se cache la fraction séquentielle¶
Dans un système réel, la fraction séquentielle n'est pas toujours evidente :
- Serialisation/deserialisation : convertir des données entre formats prend du temps CPU séquentiel
- Coordination distribuée : un consensus Raft ou Paxos serialise les écritures
- Accès partage : une table de routage lue par tous les threads sous un read-lock
- Garbage collection : les pauses GC "stop-the-world" sont séquentielles
- Aggregation des résultats : un map-reduce doit fusionner les résultats partiels
Loi de Gustafson¶
La loi de Gustafson offre une perspective complementaire. Alors qu'Amdahl suppose un problème de taille fixe, Gustafson observe qu'en pratique, on augmente la taille du problème quand on dispose de plus de processeurs.
Avec 10% de fraction séquentielle et 16 cœurs : Gustafson prédit un speedup de 14.5x (contre 6.4x pour Amdahl). La différence ? Amdahl mesure le temps pour un problème fixe. Gustafson mesure la taille du problème traitable en un temps fixe.
En pratique, les deux lois sont pertinentes :
- Amdahl s'applique quand la latence compte (temps de réponse d'une requête)
- Gustafson s'applique quand le throughput compte (volume de données traitees par heure)
Types de parallélisme¶
Parallélisme de données¶
Le même traitement est appliqué a des partitions différentes des données. C'est le modèle le plus courant et le plus facile à scaler.
Exemples : MapReduce, traitement d'images par blocs, calcul matriciel, sharding de base de données.
Parallélisme de tâches¶
Des traitements différents s'exécutent simultanément sur des données potentiellement différentes. Plus complexe à orchestrer.
Exemples : pipeline de microservices, stages d'un compilateur, producer/consumer.
Parallélisme de pipeline¶
Les données traversent une sequence d'étapes de traitement. Chaque étape travaille sur un élément différent. C'est l'équivalent logiciel du pipeline processeur.
Exemples : pipeline de streaming (Kafka Streams, Flink), pipeline CI/CD, traitement video en temps réel.
Haute disponibilité¶
Les clusters servent aussi la disponibilité — la capacité du système a rester opérationnel malgre les pannes.
Actif/passif¶
Un nœud est actif, l'autre est en standby. En cas de panne du nœud actif, le nœud passif prend le relais (failover). Le temps de basculement est typiquement de quelques secondes a quelques minutes.
graph LR
CLIENT["Client"] --requetes--> ACTIF["Noeud actif"]
ACTIF --heartbeat--> PASSIF["Noeud passif<br>(standby)"]
ACTIF --replication--> PASSIF - Avantage : simple, le standby est une copie exacte
- Inconvénient : la moitie des ressources est inutilisee en temps normal
Actif/actif¶
Tous les nœuds traitent du trafic simultanément. En cas de panne d'un nœud, les autres absorbent sa charge.
graph LR
LB["Load balancer"] --requetes--> N1["Noeud 1"]
LB --requetes--> N2["Noeud 2"]
LB --requetes--> N3["Noeud 3"] - Avantage : toutes les ressources sont utilisées, meilleur rapport coût/capacité
- Inconvénient : nécessité un mécanisme de partage ou de partitionnement des données
Métriques de disponibilité¶
| Niveau | Indisponibilite/an | Commentaire |
|---|---|---|
| 99% (deux 9) | 3.65 jours | Acceptable pour le dev |
| 99.9% (trois 9) | 8.76 heures | Standard pour les applications internes |
| 99.99% (quatre 9) | 52.6 minutes | Applications critiques |
| 99.999% (cinq 9) | 5.26 minutes | Telecom, finance — actif/actif obligatoire |
HPC : calcul haute performance¶
Les clusters HPC (High Performance Computing) sont conçus pour maximiser la puissance de calcul brute. Ils différent des clusters web/cloud par leur architecture et leurs contraintes.
MPI (Message Passing Interface)¶
MPI est le standard de communication pour le HPC. Chaque processus a sa propre mémoire ; les processus échangent des messages explicites. MPI fournit des primitives comme :
MPI_Send/MPI_Recv: communication point-à-pointMPI_Bcast: diffusion d'un processus vers tousMPI_Reduce: aggregation (somme, max, etc.) de tous vers un
SLURM¶
SLURM (Simple Linux Utility for Resource Management) est l'ordonnanceur dominant en HPC. Il géré l'allocation des nœuds, la planification des jobs et la priorisation entre utilisateurs.
# Soumettre un job MPI sur 4 noeuds, 32 coeurs chacun
sbatch --nodes=4 --ntasks-per-node=32 --time=02:00:00 job.sh
Interconnects HPC¶
Le réseau est critique en HPC. Les interconnects specialises offrent des latences bien inférieures a Ethernet :
| Technologie | Latence | Bande passante | Usage |
|---|---|---|---|
| InfiniBand HDR | ~1 us | 200 Gbps | HPC, AI training |
| InfiniBand NDR | ~0.5 us | 400 Gbps | HPC, AI training |
| RoCE (RDMA over Ethernet) | ~2-5 us | 100-400 Gbps | Cloud HPC |
| Ethernet 100G | ~5-10 us | 100 Gbps | Cluster générique |
Tip
L'entrainement de grands modèles d'IA (LLM) est aujourd'hui l'un des principaux moteurs d'investissement en clusters HPC. La communication entre GPU (via NVLink, InfiniBand) est souvent le goulot — pas la puissance de calcul brute. Concevoir un système d'entrainement distribué revient à minimiser la communication inter-nœuds, exactement comme le prédit la loi d'Amdahl.
Quorum et consensus¶
Les clusters à haute disponibilité reposent sur des mécanismes de quorum pour éviter le split-brain — la situation où deux partitions du cluster pensent chacune être le cluster actif et acceptent des écritures contradictoires.
Le quorum exige qu'une majorité de nœuds (N/2 + 1) soit d'accord avant de prendre une décision. Avec 3 nœuds, il faut l'accord de 2. Avec 5 nœuds, il faut l'accord de 3.
| Nombre de nœuds | Quorum | Pannes tolerees |
|---|---|---|
| 1 | 1 | 0 |
| 2 | 2 | 0 (inutile) |
| 3 | 2 | 1 |
| 5 | 3 | 2 |
| 7 | 4 | 3 |
Warning
Un cluster a 2 nœuds ne toléré aucune panne par quorum — si un nœud tombe, l'autre n'a pas la majorité. C'est pourquoi les clusters utilisent un nombre impair de nœuds, ou ajoutent un "temoin" (witness) léger qui ne porte pas de données mais participe au vote.
Les protocoles de consensus distribué (Raft, Paxos, ZAB) formalisent ce mécanisme. Etcd, ZooKeeper et Consul implementent ces protocoles pour fournir un stockage de configuration cohérent aux clusters.
Implications pour l'architecte¶
-
Shared-nothing par défaut : dans le cloud, partez du principe que chaque instance est indépendante. Concevez pour la partition des données, pas pour le partage
-
Mesurer la fraction séquentielle : avant de scaler horizontalement, identifiez ce qui ne parallelise pas. Un lock global sur une base de données est l'équivalent d'une fraction séquentielle de 100%
-
Actif/actif > actif/passif : pour les systèmes critiques, l'actif/actif utilisé mieux les ressources et offre un failover plus rapide — au prix d'une complexité de cohérence
-
Le réseau est le nouveau bus : dans un cluster, le réseau joue le rôle du bus mémoire dans un multiprocesseur. Sa latence et sa bande passante conditionnent les performances exactement comme le bus SMP conditionne celles d'un multiprocesseur
-
Nombre impair de nœuds : pour tout cluster base sur le quorum (etcd, ZooKeeper, Kafka controllers), deployez un nombre impair de nœuds. Trois nœuds tolèrent une panne, cinq tolèrent deux pannes
Chapitre suivant : Virtualisation et abstraction matérielle — hyperviseurs, conteneurs et overhead de l'abstraction.