web-dev-qa-db-fra.com

Lire les fichiers envoyés avec spark-submit par le pilote

J'envoie un travail Spark à exécuter sur un cluster distant en exécutant

spark-submit ... --deploy-mode cluster --files some.properties ...

Je souhaite lire le contenu du fichier some.properties à l’aide du driver code, c’est-à-dire avant de créer le contexte Spark et de lancer des tâches RDD. Le fichier est copié dans le pilote distant, mais pas dans le répertoire de travail du pilote.

Les manières de contourner ce problème que je connais sont:

  1. Télécharger le fichier sur HDFS
  2. Stocker le fichier dans le jar de l'application

Les deux sont gênants car ce fichier est fréquemment modifié sur la machine de développement en cours de soumission.

Existe-t-il un moyen de lire le fichier téléchargé à l'aide de l'indicateur --files lors de la méthode principale du code de pilote? 

29
Little Bobby Tables

Oui, vous pouvez accéder aux fichiers téléchargés via l'argument --files.

Voici comment je peux accéder aux fichiers transmis via --files:

./bin/spark-submit \
--class com.MyClass \
--master yarn-cluster \
--files /path/to/some/file.ext \
--jars lib/datanucleus-api-jdo-3.2.6.jar,lib/datanucleus-rdbms-3.2.9.jar,lib/datanucleus-core-3.2.10.jar \
/path/to/app.jar file.ext

et dans mon code Spark:

val filename = args(0)
val linecount = Source.fromFile(filename).getLines.size

Je pense que ces fichiers sont téléchargés sur les postes de travail dans le même répertoire que celui où le fichier jar a été placé. C’est pourquoi il suffit de passer le nom de fichier et non le chemin absolu vers Source.fromFile.

18
Ton Torres

Les options --files et --archives permettent de spécifier des noms de fichiers avec le # similaire à Hadoop. Par exemple, vous pouvez spécifier: --files localtest.txt # appSees.txt, ce qui téléchargera le fichier que vous avez nommé localement localtest.txt dans HDFS, mais sera lié au nom appSees.txt. Votre application doit utiliser le nommez appSees.txt pour le référencer lors de l'exécution sur YARN.

cela fonctionne pour mon application spark streaming en mode fil/client et en mode fil/cluster. peut peut-être vous aider

2
minisheep

Après l’enquête, j’ai trouvé une solution au problème ci-dessus. Envoyez la configuration any.properties lors de l'étincelle d'envoi et utilisez-la à l'aide du pilote d'allumage avant et après l'initialisation de SparkSession. J'espère que cela vous aidera.

any.properties

spark.key=value
spark.app.name=MyApp

SparkTest.Java

import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;

public class SparkTest{

  public Static void main(String[] args){

    String warehouseLocation = new File("spark-warehouse").getAbsolutePath();

    Config conf = loadConf();
    System.out.println(conf.getString("spark.key"));

    // Initialize SparkContext and use configuration from properties
    SparkConf sparkConf = new SparkConf(true).setAppName(conf.getString("spark.app.name"));

    SparkSession sparkSession = 
    SparkSession.builder().config(sparkConf).config("spark.sql.warehouse.dir", warehouseLocation)
                .enableHiveSupport().getOrCreate();

    JavaSparkContext javaSparkContext = new JavaSparkContext(sparkSession.sparkContext());

  }


  public static Config loadConf() {

      String configFileName = "any.properties";
      System.out.println(configFileName);
      Config configs = ConfigFactory.load(ConfigFactory.parseFile(new Java.io.File(configFileName)));
      System.out.println(configs.getString("spark.key")); // get value from properties file
      return configs;
   }
}

Spark Submit:

spark-submit --class SparkTest --master yarn --deploy-mode client --files any.properties,yy-site.xml --jars ...........
1
Prashant Sahoo

utiliser spark-submit --help, constatera que cette option concerne uniquement le répertoire de travail de l'exécuteur, pas le pilote.

--files FILES: Comma-separated list of files to be placed in the working directory of each executor.

0
NicolasLi

Voici une solution intéressante que j'ai développée en Python Spark afin d'intégrer toutes les données sous forme de fichier de l'extérieur à votre plate-forme Big Data.

S'amuser.

# Load from the Spark driver any local text file and return a RDD (really useful in YARN mode to integrate new data at the fly)
# (See https://community.hortonworks.com/questions/38482/loading-local-file-to-Apache-spark.html)
def parallelizeTextFileToRDD(sparkContext, localTextFilePath, splitChar):
    localTextFilePath = localTextFilePath.strip(' ')
    if (localTextFilePath.startswith("file://")):
        localTextFilePath = localTextFilePath[7:]
    import subprocess
    dataBytes = subprocess.check_output("cat " + localTextFilePath, Shell=True)
    textRDD = sparkContext.parallelize(dataBytes.split(splitChar))
    return textRDD

# Usage example
myRDD = parallelizeTextFileToRDD(sc, '~/myTextFile.txt', '\n') # Load my local file as a RDD
myRDD.saveAsTextFile('/user/foo/myTextFile') # Store my data to HDFS
0
prossblad

Pour contourner le problème, vous pouvez créer une SparkContext temporaire en appelant simplement SparkContext.getOrCreate(), puis en lisant le fichier transmis dans le --files à l'aide de SparkFiles.get('FILE').

Une fois que vous avez lu le fichier, récupérez toute la configuration nécessaire requise dans une variable SparkConf().

Après cet appel, cette fonction:

SparkContext.stop(SparkContext.getOrCreate())

Ceci distraira la SparkContext existante et qu'à la ligne suivante, initialisera simplement une nouvelle SparkContext avec les configurations nécessaires telles que celle-ci.

sc = SparkContext(conf=conf).getOrCreate()

Vous avez vous-même une SparkContext avec les réglages souhaités

0
Jugraj Singh