web-dev-qa-db-fra.com

Déterminer le nombre optimal de partitions Spark en fonction des travailleurs, des cœurs et de la taille de DataFrame

Il existe plusieurs concepts similaires mais différents dans Spark-land concernant la façon dont le travail est réparti sur différents nœuds et exécuté simultanément. Plus précisément, il existe:

  • Le nœud Spark Driver (sparkDriverCount)
  • Le nombre de nœuds de travail disponibles pour un cluster Spark (numWorkerNodes)
  • Le nombre d'exécuteurs Spark (numExecutors)
  • Le DataFrame étant exploité simultanément par tous les travailleurs/exécuteurs (dataFrame)
  • Le nombre de lignes dans le dataFrame (numDFRows)
  • Le nombre de partitions sur le dataFrame (numPartitions)
  • Et enfin, le nombre de cœurs CPU disponibles sur chaque nœud de travail (numCpuCoresPerWorker)

I croire que tous les Spark clusters ont n et un seul Spark Driver, et puis 0+ nœuds de travail. Si je me trompe, commencez par me corriger! En supposant que je suis plus ou moins correct à ce sujet, verrouillons quelques variables ici. Disons que nous avons un Spark cluster avec 1 pilote et 4 nœuds de travail, et chaque travailleur Node a 4 cœurs de processeur (donc un total de 16 cœurs de processeur). Donc, le "donné" ici est:

sparkDriverCount = 1
numWorkerNodes = 4
numCpuCores = numWorkerNodes * numCpuCoresPerWorker = 4 * 4 = 16

Étant donné que la configuration, je me demande comment déterminer quelques éléments. Plus précisément:

  • Quelle est la relation entre numWorkerNodes et numExecutors? Existe-t-il un ratio connu/généralement accepté de travailleurs/exécuteurs? Existe-t-il un moyen de déterminer numExecutors étant donné numWorkerNodes (ou toute autre entrée)?
  • Existe-t-il un rapport connu/généralement accepté/optimal de numDFRows à numPartitions? Comment calcule-t-on le nombre "optimal" de partitions en fonction de la taille du dataFrame?
  • J'ai entendu d'autres ingénieurs dire qu'une "règle générale" est: numPartitions = numWorkerNodes * numCpuCoresPerWorker, une vérité à cela? En d'autres termes, il prescrit que l'on doit avoir 1 partition par cœur de CPU.
19
smeeb

Oui, une application spark a n seul pilote .

Quelle est la relation entre numWorkerNodes et numExecutors?

Un travailleur peut héberger plusieurs exécuteurs, vous pouvez le considérer comme le travailleur comme la machine/le nœud de votre cluster et l'exécuteur comme un processus (s'exécutant dans un noyau) qui s'exécute sur ce travailleur.

Donc `numWorkerNodes <= numExecutors '.

Y a-t-il une ration pour eux?

Personnellement, ayant travaillé dans un faux cluster, où mon ordinateur portable était le pilote et une machine virtuelle dans le même ordinateur portable était le travailleur, et dans un industriel cluster de> 10k nœuds, je n'avais pas besoin de m'en soucier, car il semble que spark s'en occupe.

J'utilise juste:

--num-executors 64

quand je lance/soumets mon script et spark sait, je suppose, combien de travailleurs il doit invoquer (bien sûr, en prenant également en compte d'autres paramètres et la nature des machines).

Ainsi, personnellement, je ne connais pas un tel ratio.


Existe-t-il un rapport connu/généralement accepté/optimal de numDFRows à numPartitions?

Je n'en connais pas, mais en règle générale, vous pouvez vous fier au produit de #executors par # executor.cores, puis le multiplier par 3 ou 4. Bien sûr, c'est un heuristique . Dans pyspark cela ressemblerait à ceci:

sc = SparkContext(appName = "smeeb-App")
total_cores = int(sc._conf.get('spark.executor.instances')) * int(sc._conf.get('spark.executor.cores'))
dataset = sc.textFile(input_path, total_cores * 3)

Comment calcule-t-on le nombre "optimal" de partitions en fonction de la taille du DataFrame?

Voilà une excellente question. Bien sûr, il est difficile de répondre et cela dépend de vos données, de votre cluster, etc., mais comme indiqué ici avec moi-même.

Trop peu de partitions et vous aurez d'énormes blocs de données, surtout lorsque vous avez affaire à bigdata , mettant ainsi votre application en mémoire.

Trop de partitions et vous aurez votre hdfs prendre beaucoup de pression, car toutes les métadonnées qui doivent être générées à partir de hdfs augmentent de manière significative à mesure que le nombre de partitions augmente (car il gère les fichiers temporaires, etc.). *

Donc, ce que vous voulez, c'est aussi trouver un sweet spot pour le nombre de partitions, qui est l'une des parties de peaufiner votre application . :)

'règle générale' est: numPartitions = numWorkerNodes * numCpuCoresPerWorker, est-ce vrai?

Ah, j'écrivais l'heuristique ci-dessus avant de voir ça. Donc, c'est déjà répondu, mais prenez en compte la différence entre un travailleur et un exécuteur testamentaire .


* Je viens d'échouer pour cela aujourd'hui: Préparer mes données volumineuses avec Spark via Python , lorsque l'utilisation de trop de partitions est causée Les tâches actives sont un nombre négatif dans l'interface utilisateur Spark .

20
gsamaras