Séance 7

MapReduce distribué et performance

Rémi Sharrock

BGD701 — Télécom Paris

Objectifs

  • Faire tourner le MapReduce de la séance 6 sur plusieurs machines
  • Partager proprement des machines communes
  • Mesurer l’accélération et la comprendre avec la loi d’Amdahl
  • Survivre à une panne, et prouver que le résultat ne change pas

Le système

Programme Combien Rôle
Travailleur un par machine un serveur : fait les maps et les reduces
Maître un seul distribue les tâches, relance en cas d’échec. Ne calcule rien
Déployeur un script lance et arrête les travailleurs par SSH

Tout vient des séances 1 à 6 : sockets, threads, protocole.py, horloge monotone, MapReduce.

Le déroulement

  1. Map : chaque travailleur lit un fichier, écrit RR partitions sur son disque local
  2. Barrière : le maître attend la fin de tous les maps
  3. Shuffle : chaque réducteur va chercher sa partition chez chaque mappeur
  4. Reduce : il additionne, garde son résultat en local
  5. Collecte : le maître rassemble les RR résultats

Le shuffle : combien de demandes ?

Chaque réducteur demande sa partition à chaque map : M×RM \times R demandes. Est-ce un compte exact ou un maximum ?

Cas mesuré Demandes Utiles
32 fichiers de texte, R=8R = 8 256 presque toutes
30 fichiers ne contenant que chat 240 30

M×RM \times R est le maximum. Notre code, naïf, l’atteint toujours : il demande aussi les partitions vides. Et avec un seul mot, un seul reduce sert à quelque chose.

Les règles du terrain

Où écrire les intermédiaires ?

Chemin Où sont les octets 64 petits fichiers
/tmp/... sur le disque local 0,30 s
~/... sur le serveur NFS, partagé par toute l’école de 1,06 à 2,60 s

NN machines sur /tmp = NN disques. NN machines sur ~ = un seul serveur, pour tout le monde. Intermédiaires → /tmp.

Partager les machines

Règle Pourquoi
Un port à votre nom : 40000 + uid % 20000 sinon deux étudiants se volent le port 50007
Un PING qui renvoie votre login le succès de ssh ne prouve pas que le travailleur tourne
Une connexion SSH à la fois l’école limite les sessions simultanées
Nettoyer, et vérifier sinon des processus orphelins gênent tout le monde

Le piège du nettoyage

# FAUX : pkill tue aussi le shell distant, le rm ne s'execute jamais
$ ssh MACHINE "pkill -f travailleur.py ; rm -rf /tmp/bgd701-\$USER"

# JUSTE
$ ssh MACHINE "pkill -u \$USER -f '[t]ravailleur.py' ; rm -rf /tmp/bgd701-\$USER"
  • [t]ravailleur.py reconnaît le travailleur, pas la commande elle-même
  • Les apostrophes sont obligatoires : sinon zsh répond no matches found et n’exécute rien

Faire tourner

Trois commandes

$ python3 deployer.py deployer 4
  ok      tp-1a201-10.enst.fr
  ok      tp-1a201-27.enst.fr
  ok      tp-1a201-31.enst.fr
  ok      tp-1a201-13.enst.fr
4 travailleur(s) dans travailleurs.txt (port 51114)

$ python3 maitre.py
TOTAL : 1.56 s
18810 mots distincts, 4/4 travailleurs utilises

$ python3 deployer.py nettoyer

Toujours vérifier

$ python3 verifier.py
distribue  :  1.37 s (4 travailleurs)
sequentiel :  2.07 s (1 processus)
OK : 18810 mots distincts, resultats identiques

Un système qui ne plante pas n’est pas forcément juste. Seule la comparaison avec un calcul de référence le prouve.

Mesurer

L’accélération

S(p)=T(1)T(p)E(p)=S(p)p S(p) = \frac{T(1)}{T(p)} \qquad\qquad E(p) = \frac{S(p)}{p}

  • SS : combien de fois plus vite qu’avec une machine
  • EE : la part de chaque machine réellement utile
  • Trois mesures par point, on garde la médiane

La règle absolue

Le même jeu de données à tous les points.

Nos mesures

32 fichiers de 1 Mo, R=8R = 8, travailleurs déjà lancés.

Machines 1 2 4 8 16
Temps (s) 18,38 9,47 5,03 2,97 2,02
Accélération 1,00 1,94 3,65 6,19 9,10
Efficacité 100 % 97 % 91 % 77 % 57 %

Pourquoi pas 16 fois plus vite ?

  • Les vagues : à 16 machines, chacune fait encore 2 maps à la suite
  • R=8R = 8 : au-delà de 8 machines, le reduce n’accélère plus
  • Les coûts fixes : connexions, barrière, collecte

Et le déploiement ?

19 s pour lancer 16 travailleurs, dix fois le calcul. On les lance une fois, puis on s’en sert pour tous les calculs.

La loi d’Amdahl

Processeur ou disque ?

Un serveur de calcul passe 70 % de son temps dans les processeurs et 30 % sur les disques.

Amélioration Gain sur le composant Coût
Nouveaux processeurs 50 % plus rapides 10 000 €
Nouveaux disques 150 % plus rapides 7 000 €
  1. Lequel donne la meilleure performance ?
  2. Lequel donne le meilleur rapport performance / coût ?

Le calcul, en minutes

Un calcul de 60 min : 42 min de processeur, 18 min de disque.

Processeur Disque Total
Aujourd’hui 42 18 60 min
Processeurs ×1,5 28 18 46 min
Disques ×2,5 42 7,2 49,2 min

On n’accélère que le temps passé dans le composant amélioré. Le reste ne bouge pas.

La loi d’Amdahl

aa = part du temps améliorée, kk = facteur d’accélération de cette part.

S=TavantTaprès=1(1−a)+ak S = \frac{T_{\text{avant}}}{T_{\text{après}}} = \frac{1}{(1-a) + \dfrac{a}{k}}

Amélioration aa kk Accélération Coût par %
Processeurs 0,7 1,5 +30 % 329 €
Disques 0,3 2,5 +22 % 319 €

Même infiniment rapide, le disque donnerait au plus 1/0,71/0\mathord{,}7 : +43 %.

Le prix est-il le bon critère ?

  • Un objectif : le calcul doit passer sous 45 min → aucune option ne suffit seule ; les deux ensemble : 35,2 min, pour 17 000 €
  • Un budget : avec 8 000 €, seuls les disques sont possibles
  • Le profil change avec le travail : un programme qui lit davantage inverse la conclusion

On améliore ce qui pèse le plus dans le temps, et on le sait en mesurant.

Le parallélisme : un cas particulier

ff = part séquentielle. Avec pp machines, la part 1−f1 - f va pp fois plus vite :

S(p)=1f+1−fpS(∞)=1f S(p) = \frac{1}{f + \dfrac{1-f}{p}} \qquad\qquad S(\infty) = \frac{1}{f}

ff 10 machines 100 machines 1000 machines plafond
5 % 6,9 16,8 19,6 20
10 % 5,3 9,2 9,9 10

Sur notre système

  • Avec 16 machines, accélération de 9,10 : f≈5%f \approx 5\,\%, plafond ≈ 20
  • Profil des maps (exercice 7.3) : calcul 79 %, lecture 15 %, écriture 6 %
  • Une écriture infiniment rapide donnerait au mieux +6 %

C’est pourquoi passer du NFS à /tmp change peu le total quand le serveur est calme : l’écriture pèse peu. C’est le calcul qu’il faut accélérer.

Les pannes

Deux façons de mourir

4 machines, 32 fichiers. Sans panne : 6,1 s.

Ce qui arrive Le maître l’apprend Total
Le processus est tué tout de suite : connexion refusée 7,4 s
La machine est figée seulement par le timeout 88,7 s

Un silence ne dit pas si la machine est morte ou lente : il faut choisir un délai (séance 5).

Refaire la tâche ailleurs

  • Les tâches sont idempotentes : les refaire donne le même résultat
  • Tout ce qui était sur le disque local d’un mort est perdu, même terminé
  • Mesuré : machine tuée juste après la barrière → ses 8 maps terminés sont refaits
  • Résultat final : identique au calcul sans panne

À vous

Les exercices

7.1 Faire tourner sur 4 machines, vérifier le résultat
7.2 NFS contre /tmp (petit, et on nettoie)
7.3 Où passe le temps : lecture, calcul, écriture
7.4 La courbe d’accélération, de 1 à 16 machines
7.5 Tuer une machine, cinq fois
7.6 Un autre traitement que le comptage de mots
7.7 Quel composant améliorer ?

Ce qu’il faut retenir

  • Intermédiaires sur /tmp : le disque local passe à l’échelle
  • Machines partagées : port à votre nom, une connexion SSH à la fois, nettoyer et vérifier
  • Même jeu de données à chaque mesure
  • Amdahl : on accélère ce qui pèse le plus ; plafond 1/f1/f
  • Tâches idempotentes : on les refait ailleurs
  • Toujours comparer au calcul de référence