Le but de l'article est simple: que faire quand votre client veut faire du big data sur un cluster qui est bien trop petit pour y parvenir. Récit d'une belle aventure humaine d'un cas client (bien sûr, ça ne s'est jamais passé, tout ceci est de la pure fiction, toute ressemblance avec une entreprise ayant existé tout ça tout ça).

Le contexte est celui d'un client purement imaginaire, évidemment, qui réalise un projet de big data avec une mise à jour quotidienne de données via des jobs spark (apache spark). A cette fin, une équipe est montée, avec des personnes en charge du développement sous spark, et ... Un "cluster". Premier point de vigilance: la méconnaissance de l'éco système hadoop. La direction technique n'étant ni familière, ni intéressée par le big data, la notion de commodity hardware n'a pas été étudiée comme elle aurait du l'être. En conséquence, toute acquisition était synonyme de disques fort chers, de mémoire à des prix indicibles. Donc, rien... L'équipe a alors du travailler avec un "cluster" d'un seul noeud, une machine de 100 go de ram, 1 to de disque, et 12 processeurs. A terme, un environnement de prod avec 2 to de disques a été mis en place. Au dela de la bataille de chiffres, il s'agit avant tout de bien penser son application pour qu'elle tienne dans le volume prévu. A ce sujet là :

  • le format parquet est à privilégier, puisqu'il est compressé. Si les jobs sont passés les uns après les autres, il est possible de faire tenir un volume décompressé très grand. Sur ce cas, ce client a trouvé empiriquement un facteur de 4.5 entre le volume compressé et le volume alloué sur disque quand spark réalise une lecture du job. Autrement dit, évidemment, il n'y a pas de magie, il faut un volume de disque conséquent pour traiter les données, en particulier les décompresser. Par contre, des tests chez cette entreprise ont également montré qu'un format non compressé comme le CSV (avec la question du typage) n'était pas une source de gains de performance. Le format parquet est bien pensé, et les temps d'exécution sont vraiment très longs si on passe par un fichier non compressé. La raison est assez évidente: décompresser et surtout en mémoire utilise une ressource beaucoup plus rapide qu'un disque dur.
  • tout développement doit être testé, dans le but de vérifier tout simplement que chaque batch termine. Vous aurez très probablement toutes les variantes possibles de outofmemory error. Hormis le réglage évident, il vous faudra probablement réécrire vos jobs pour utiliser des fichiers temporaires. Donc prendre de la place disque. Donc... Tout l'art d'un "cluster" sous dimensionné réside dans le compromis entre multiplier les jobs et les fichiers temporaires, ou ne pas surcharger le disque.
  • Le pouvoir de l'échantillon: comprenez bien qu'il est probable que votre machine soit la seule ressource acceptable pour ne pas attendre une semaine une disponibilité. Dans ce cas, vous n'allez pas charger toutes les données client. Il vous faudra échantillonner, rapatrier ceux ci, et jouer la chaine complète des jobs sur votre machine. Donc, au niveau des développements, la première bonne pratique est de bien connaitre ses données: champs nuls, champs vides, clés fonctionnelles, etc. Prenez des échantillons très petits (1000 lignes maximum) mais le plus riche possible, donc avec le maximum de cas "spéciaux". Testez un maximum toutes les étapes de votre chaine, et le maximum via des tests automatisés. Evidemment, spark est long au démarrage et vous aurez besoin de plusieurs minutes pour savoir si les tests passent. Mais c'est toujours plus rapide que de quémander du cluster. Notez bien qu'au niveau de la conception, vous devrez avoir du code qui permet d'injecter des datasets depuis plusieurs sources de données: en test et en prod.
  • Des tensions vives vont exister dans l'équipe, puisqu'évidemment, il n'y a pas la place de faire tourner l'ensemble des jobs en même temps. Sur les phases de tests de performance, par exemple, il sera question de transparence, et d'équité. Le système d'un tableau blanc avec réservation des ressources n'a pas marché chez le client. Il a suffi qu'un coup de pression soit mis sur un développement pour que toutes les bonnes intentions disparaissent. C'est au management, ou à l'équipe idéalement, de garantir l'équité.

Conclusion

On peut bien évidemment rentrer dans une guerre de posture et raler que le cluster n'est pas assez grand pour y faire tenir les jobs. On peut, mais le temps que le client lance la démarche d'acquisition de ressources (évidemment pas des commodity hardware), il se sera déroulé une ou deux fins de missions. L'approche pragmatique doit dominer, avec plusieurs impératifs:

  • faire valider que les algorithmes terminent avec de place sur la machine, et sans erreur de type "manque de ressources"
  • tester un maximum tous les cas bizarres dans des tests d'intégration de manière automatisée. Faites bon usage de junit, il est là pour ça. Echantillonez, mais surtout, prenez en compte les cas spéciaux dès les premiers tests
  • requêtez vos données (avec apache drill par exemple) pour bien les connaitre: volumes, cas spéciaux, pourcentages de croissance par jour / mois / année, pour bien évaluer si les jobs qui passent aujourd'hui passeront toujours demain.
  • ne sous estimez pas le temps géologique d'acquisition de nouvelles ressources, et faites avec. Levez très tôt que le cluster est surchargé, pour prendre en compte toute la dimension politique d'un budget supplémentaire
 

Comments are closed.

Set your Twitter account name in your settings to use the TwitterBar Section.