web-dev-qa-db-fra.com

Comment la partition Spark (ing)) fonctionne-t-elle sur les fichiers HDFS?

Je travaille avec Apache Spark sur un cluster utilisant HDFS. Autant que je sache, HDFS distribue des fichiers sur des nœuds de données. Donc, si vous mettez un "fichier.txt" sur le système de fichiers , il sera divisé en partitions. J'appelle maintenant

rdd = SparkContext().textFile("hdfs://.../file.txt") 

de Apache Spark. Est-ce que rdd a maintenant automatiquement les mêmes partitions que "fichier.txt" sur le système de fichiers? Qu'est-ce qui se passe quand j'appelle

rdd.repartition(x)

où x> puis les partitions utilisées par hdfs? Est-ce que Spark va réorganiser physiquement les données sur hdfs pour qu'elles fonctionnent localement?

Exemple: je mets un fichier texte de 30 Go sur le système HDFS, qui le distribue sur 10 nœuds. Est-ce que Spark a) utilisera les mêmes 10 partitons? et b) mélangez-vous 30 Go dans la grappe lorsque j'appelle la répartition (1000)?

45
Degget

Lorsque Spark lit un fichier à partir de HDFS, il crée une seule partition pour un seul fractionnement d'entrée. Le fractionnement d'entrée est défini par Hadoop InputFormat utilisé pour lire ce fichier. Par exemple, si vous utilisez textFile(), il s'agira de TextInputFormat dans Hadoop, ce qui vous renverrait une seule partition pour un seul bloc de HDFS (mais la division entre les partitions se ferait sur une division de ligne, pas la scission exacte des blocs), sauf si vous avez un fichier texte compressé, vous obtiendrez une partition unique pour un fichier unique (car les fichiers texte compressés ne sont pas divisibles).

Lorsque vous appelez rdd.repartition(x), les données de N que vous avez dans les partitions rdd à x que vous souhaitez créer sont mélangées. être fait à tour de rôle.

Si vous avez un fichier texte non compressé de 30 Go stocké sur HDFS, avec le paramètre de taille de bloc HDFS par défaut (128 Mo), il serait stocké dans 235 blocs, ce qui signifie que le RDD que vous avez lu dans ce fichier aurait 235 partitions. Lorsque vous appelez repartition(1000), votre RDD est marqué comme à repartitionner, mais en fait, il ne sera mélangé à 1000 partitions que lorsque vous exécuterez une action sur ce RDD ( concept d'exécution paresseux)

80
0x0FFF

Voici l’instantané de "Comment les blocs dans HDFS sont chargés dans Spark sous forme de partitions"

Dans cette image, 4 blocs HDFS sont chargés en tant que Spark dans la mémoire de 3 travailleurs

Dataset in HDFS broken into partitions


Exemple: je mets un fichier texte de 30 Go sur le système HDFS, qui le distribue sur 10 nœuds.

Va étincelle

a) utilise les mêmes 10 partitions?

Spark charge les mêmes 10 blocs HDFS dans la mémoire des employés en tant que partitions. Je suppose que la taille de bloc d'un fichier de 30 Go devrait être de 3 Go pour obtenir 10 partitions/blocs (avec la configuration par défaut)

b) mélangez 30 Go sur le cluster lorsque j'appelle la répartition (1000)?

Oui, Spark mélange les données entre les nœuds de travail afin de créer 1000 partitions dans la mémoire de celui-ci.

Remarque:

HDFS Block -> Spark partition   : One block can represent as One partition (by default)
Spark partition -> Workers      : Many/One partitions can present in One workers 
11
mrsrinivas

Lors de la lecture de fichiers HDFS non compartimentés (par exemple, parquet) avec spark-sql, le nombre de partitions DataFrame df.rdd.getNumPartitions Dépend de ces facteurs:

  • spark.default.parallelism (Se traduit approximativement par #cores disponibles pour l'application)
  • spark.sql.files.maxPartitionBytes (128 Mo par défaut)
  • spark.sql.files.openCostInBytes (4 Mo par défaut)

Une estimation approximative du nombre de partitions est:

  • Si vous avez suffisamment de cœurs pour lire toutes vos données en parallèle (c’est-à-dire au moins un cœur pour chaque 128 Mo de vos données)

    AveragePartitionSize ≈ min(4MB, TotalDataSize/#cores) NumberOfPartitions ≈ TotalDataSize/AveragePartitionSize

  • Si vous n'avez pas assez de cœurs ,

    AveragePartitionSize ≈ 128MB NumberOfPartitions ≈ TotalDataSize/AveragePartitionSize

Les calculs exacts sont légèrement compliqués et peuvent être trouvés dans la base de code de FileSourceScanExec, voir ici .

10
Apoorve Dave

Ajout à @ 0x0FFF S'il prend HDFS comme fichier d'entrée, il calculera comme pour cette rdd = SparkContext().textFile("hdfs://.../file.txt") et lorsque vous réaliserez rdd.getNumPatitions, Il en résultera Max(2, Number of HDFS block). J'ai fait beaucoup d'expériences et trouvé cela comme résultat. Encore une fois explicitement, vous pouvez faire rdd = SparkContext().textFile("hdfs://.../file.txt", 400) pour obtenir 400 en tant que partitions ou même effectuer des re-partitions avec rdd.repartition Ou de les réduire à 10 avec rdd.coalesce(10)

6
ChikuMiku