Patientons avec les nouveautés de Spark 3.0

On attend Spark 3.0.0 depuis la preview 2 de Noël 2019. Ici vous n'aurez pas la date de release, mais un résumé des principaux changements et nouveautés et connus à ce jour, que l'on pourra attendre de cette nouvelle version majeure de Spark. Je vous invite aussi à voir nos précédents articles sur Spark comme celui-ci sur Spark 2.4 et les autres.

Disclaimer!!! Attention quelques liens sont donnés vers la preview 2 de Spark 3.0. Elle pourrait comporter des bugs et erreurs dans sa documentation.

Compatibilité des versions

Premièrement, sur la compatibilité, Spark 3.0.0 pourra s’exécuter avec :

  • Java 8 / 11
    • Le support de versions antérieures à Java 8 version 8u92 est déprécié.
  • Scala 2.12
    • Spark 3 arrête le support de Scala 2.11, qui est déjà déprécié depuis Spark 2.4.1.
  • Python 2.7+/3.4+
    • Le support des versions de Python 2 et 3 antérieures à la version 3.6 est déprécié.
  • R 3.1+
    • Le support de version antérieure à R 3.4 est déprécié.

Il n'y aura plus de support d'Hadoop 2.6, la version par défaut sera la 2.7.

Principaux changements et nouveautés

  • Changement dans le module MLlib
    • L'API basé sur les RDD ne devrait plus être supporté. En effet, cette API côté MLlib était en mode maintenance depuis Spark 2.0 et devrait être supprimée avec la version 3.0.
  • Support des fichiers binaires
    • La nouvelle version apportera le support de fichiers binaires, comme les images, l'audio ou les vidéos. On pourra donc lire ces fichiers pour récupérer les métadonnées sous forme de DataFrame. Par contre, la réécriture d'un DataFrame vers un fichier binaire de ce type n'est pas possible. Une documentation sur la preview est fournie, avec le ticket JIRA.
  • L'API DataSource V2 sera changée
    • Introduite dans Spark 2.3, l'API change dans Spark 3.0 et offre une meilleure intégration avec les optimiseurs Spark, les sources tierces auront de meilleures performances avec cette version.
  • Meilleures performances
    • Accélération du Catalyst Optimizer grâce à des améliorations des algorithmes, par exemple sur le JIRA, SPARK-25974 et SPARK-27815 parmi d'autres.
    • Dynamic Partition Pruning (traité dans cet article plus bas)
  • Spark Graph ?
    • Spark Graph est un nouveau module développé par Neo4J, dont le nom projet de base était "Cypher for Apache Spark" puis "Morpheus". Il apporte le langage Cypher à Spark. Cypher est un langage de requêtage dédié pour les graphes (une sorte de SQL, mais adaptés aux parcours de graphes). Plus d'information dans cette présentation.
    • Néanmoins le module ne va probablement pas être disponible pour la release de Spark 3.0 d'après cette discussion.
  • Utilisation des ressources GPU
    • Malgré le support des ressources GPU par YARN et Kubernetes, Spark ne prenait pas en compte les ressources GPU exposées par ces derniers. Avec Spark 3 il sera possible d'allouer les ressources des GPU sur le cluster de manière native, cela fonctionnera avec YARN, Kubernetes et le mode Standalone. Cela pourrait être très utile pour des utilisations comme le Deep Learning. Pour en savoir plus, vous pouvez regarder l'Epic associée SPARK-24615.

  • Beaucoup de codes dépréciés en 2.x vont être supprimés. 🎉

Pour en savoir plus, vous pouvez aussi consulter les entrées du JIRA de Spark pour voir les autres features et bugfix.

Un point sur le Dynamic Partition Pruning

Vous connaissiez peut-être déjà le Static Partition Pruning, où quand on avait ce genre de jointure :

SELECT t1.foo FROM t1
JOIN t2
	ON t1.partcol = t2.partcol 
	AND t2.partcol = 1

Avec t1 partitionné sur la colonne partcol. À la compilation, Spark va inférer que t1.partcol = 1, va faire son "pruning" et pouvoir choisir les bonnes partitions à scanner. Tout cela parce que le filtre se fait sur les colonnes de partitions.

Or qu'en est-il avec une jointure de ce type ?

SELECT * FROM dim_table 
JOIN fact_table 
	ON (dim_table.partcol = fact_table.somcol) 
WHERE dim_table.othercol > 10.

Ici on a une jointure entre une table de fait fact_table (potentiellement très grande) et une table de dimension dim_table (qui n'est pas forcément partitionnée et petite). Le filtre se fait sur la colonne othercol de la table dim_table qui n'est pas la colonne de jointure.

Spark ne peut savoir qu'au runtime ce qu'il faut filtrer sur la table fact_table avec le résultat du filtre sur dim_table . Si la table de dimension est petite, Spark va probablement faire un Broadcast Hash Join, durant ce processus une HashTable est créée à partir de la table de dimension et le résultat est mis dans une variable de broadcast.

Avant, cette variable de broadcast était diffusée à tous les workers et alors le filtrage se faisait localement sur chaque partition de la table de fait et ainsi on évitait un shuffle.

Maintenant, avec le Dynamic Partition Pruning, on va prendre cette variable de broadcast qui servira de filtre dynamique. On l'utilisera dans la stratégie de scan de la table de fait et on ne sélectionnera que les partitions qui nous intéresse. Donc on évite un shuffle et un scan inutile de partitions.

Au niveau performance, des tests ont été faits par les équipes de Databricks sur le benchmark TPC-DS dont les résultats ont donné :

  • Pour 1 To de données, pour environ 60% de requêtes. On a une accélération qui va de 2x à 18x plus vite.
  • Pour 10 To, il y a des accélérations qui vont jusqu'à 100x.
  • Dans ces requêtes accélérées, ils ont observé que 90% de la donnée était rétirée du scope, d'où le gain de performance.

Vous trouverez ici un talk de Databricks sur le sujet et aussi le ticket JIRA associé à cette feature.

Comment faire pour se préparer ?

Si vous voulez vous préparer à une migration vers la version 3.0, il existe plusieurs guides officiels de migration de Spark 2.4 vers Spark 3.0, que l'ont peut trouver dans la documentation de la preview 2. Vous remarquerez qu'il y a le plus de changements dans Spark SQL.

En Scala, il faut en premier sortir de Scala 2.11 en passant à Spark 2.4.1.

Vous pouvez en suite tester la 3.0.0-preview2 Spark :

  • En téléchargement direct ici
  • Ou directement dans votre projet sbt avec :
    libraryDependencies += "org.apache.spark" %% "spark-sql" % "3.0.0-preview2"

Conclusion

Voilà pour les principales features que l'ont pourra attendre de Spark 3.0. À ce jour, nous ne connaissons toujours pas de date de release. Mais peut être en saurons-nous plus lors du Spark+AI Summit 2020 qui se déroulera du 22 au 26 Juin et qui, à cause de la situation mondiale actuelle, sera virtuel et gratuit pour tous. https://databricks.com/sparkaisummit/north-america-2020


Photographie par Adrien Delforge sur Unsplash