Je ne lis donc qu’un fichier de parquet avec Spark (en utilisant le code SQL) et j’aimerais qu’il soit traité avec 100 partitions. J'ai essayé de régler spark.default.parallelism
à 100, nous avons également essayé de changer la compression du parquet en none (de gzip). Quoi que nous fassions, la première étape du travail par étincelle ne comporte qu'une seule partition (une fois qu'un brassage est effectué, il est repartitionné en 100 et, par la suite, les choses sont bien plus rapides).
Maintenant, selon quelques sources (comme ci-dessous), le parquet devrait être divisible (même si vous utilisez gzip!), Je suis donc très confus et aimerais quelques conseils.
J'utilise spark 1.0.0 et, apparemment, la valeur par défaut de spark.sql.shuffle.partitions
est 200, donc il ne peut en être ainsi. En fait, tous les défauts du parallélisme sont bien plus que 1, alors je ne comprends pas ce qui se passe.
Vous devriez écrire vos fichiers de parquet avec une taille de bloc plus petite. La valeur par défaut est de 128 Mo par bloc, mais vous pouvez le configurer en définissant la configuration parquet.block.size
dans l'enregistreur.
La source de ParquetOuputFormat est ici , si vous voulez creuser dans les détails.
La taille de bloc est la quantité minimale de données que vous pouvez lire dans un fichier de parquet qui est lisible logiquement (comme le parquet est en colonne, vous ne pouvez pas simplement le diviser par ligne ou quelque chose d'aussi trivial comme celui-ci), vous ne pouvez donc pas avoir plus de fils de lecture. que des blocs d'entrée.
Vous avez indiqué que vous souhaitiez contrôler la distribution lors de l'écriture sur le parquet. Lorsque vous créez un parquet à partir de RDD, le parquet préserve les partitions du RDD. Ainsi, si vous créez RDD et spécifiez 100 partitions et à partir de la structure de données au format parquet, il écrira 100 fichiers de parquet distincts dans fs. Pour lire, vous pouvez spécifier le paramètre spark.sql.shuffle.partitions
.
Peut-être que votre fichier de parquet ne prend qu'un seul bloc HDFS. Créez un gros fichier de parquet comportant de nombreux blocs HDFS et chargez-le.
val k = sc.parquetFile("the-big-table.parquet")
k.partitions.length
Vous verrez le même nombre de partitions que les blocs HDFS. Cela a bien fonctionné pour moi (spark-1.1.0)
La nouvelle façon de procéder (Spark 2.x) est de définir
spark.sql.files.maxPartitionBytes
Source: https://issues.Apache.org/jira/browse/SPARK-17998 (la documentation officielle n’est pas encore correcte, manque le .sql)
D'après mon expérience, les paramètres Hadoop n'ont plus d'effet.
Pour ce faire, vous devez utiliser SparkContext
pour définir la propriété de configuration Hadoop (sc.hadoopConfiguration
) mapreduce.input.fileinputformat.split.maxsize
.
En définissant cette propriété sur une valeur inférieure à hdfs.blockSize, vous obtiendrez autant de partitions que le nombre de divisions.
Par exemple:
Lorsque hdfs.blockSize
= 134217728 (128 Mo),
et un fichier est lu qui contient exactement un bloc complet,
et mapreduce.input.fileinputformat.split.maxsize
= 67108864 (64 Mo)
Ensuite, il y aura deux partitions dans lesquelles ces divisions seront lues.