Utilisation du connecteur HDFS avec Spark
Introduction
Cet article fournit une procédure pas à pas qui indique comment utiliser le connecteur HDFS avec la structure d'application Spark. Dans la procédure pas à pas, nous utilisons le système d'exploitation Oracle Linux 7.4 et exécutons Spark en tant que système autonome sur un seul ordinateur.
Prérequis
Voici les prérequis pour la réalisation de la procédure pas à pas :
- Vous devez disposer du droit d'accès permettant de créer une instance de calcul. Pour obtenir des instructions, reportez-vous à Création d'une instance.
- Vous devez pouvoir vous connecter à l'instance de service que vous avez lancée. Pour obtenir des instructions, reportez-vous à Connexion à une instance.
- Vous devez disposer de l'OCID, de l'empreinte et de la clé privée appropriés pour l'utilisateur Identity and Access Management (IAM) que vous allez utiliser pour interagir avec Object Storage. Pour obtenir des instructions, reportez-vous à Configuration et prérequis.
- Vous devez disposer d'un bucket Object Storage auquel vous pouvez vous connecter.
- L'utilisateur IAM doit pouvoir lire et écrire dans ce bucket à l'aide de la console.
Utilisation de Spark
Installation de Spark et des dépendances
Pour cet exemple, installez Spark dans le répertoire de base de l'utilisateur en cours. Pour les scénarios de production, vous ne devez pas effectuer cette opération.
Les versions 2.7.7.0 et ultérieures n'installent plus toutes les dépendances tierces requises. Celles-ci sont regroupées sous le dossier
third-party/lib dans l'archive ZIP et doivent être installées manuellement.- Créez une instance de votre service Compute. Pour obtenir des instructions, reportez-vous à Création d'une instance.
- Vérifiez que l'instance de service dispose d'une adresse IP publique afin de pouvoir vous connecter à l'aide d'une connexion SSH (Secure Shell). Pour obtenir des instructions, reportez-vous à Connexion à une instance.
- Connectez-vous à l'instance de service à l'aide d'une connexion SSH.
- Installez Spark et ses dépendances, ainsi que Java et Scala à l'aide des exemples de code ci-dessous.
# We'll use wget to download some of the artifacts that need to be installed
sudo yum install wget
# First install Java
sudo yum install java-1.8.0-openjdk.x86_64
export JAVA_HOME=/usr/lib/jvm/jre-1.8.0-openjdk
# Should be something like: OpenJDK Runtime Environment (build 1.8.0_161-b14)
java -version
# Then install Scala
wget https://downloads.lightbend.com/scala/2.12.4/scala-2.12.4.rpm
sudo yum install scala-2.12.4.rpm
# Should be something like: Scala code runner version 2.12.4 -- Copyright 2002-2017, LAMP/EPFL and Lightbend, Inc.
scala -version
# Then download Spark
wget https://archive.apache.org/dist/spark/spark-2.2.1/spark-2.2.1-bin-hadoop2.7.tgz
tar xvf spark-2.2.1-bin-hadoop2.7.tgz
export SPARK_HOME=$HOME/spark-2.2.1-bin-hadoop2.7
export PATH=$PATH:$SPARK_HOME/bin
# Start a Spark master
cd $SPARK_HOME
./sbin/start-master.sh
Téléchargement du connecteur HDFS et création des fichiers de configuration
Pour cet exemple, placez les fichiers JAR et les fichiers de clés dans le répertoire de base de l'utilisateur en cours. Pour les scénarios de production, vous devez placer ces fichiers dans un emplacement commun qui applique les droits d'accès appropriés (c'est-à-dire, un emplacement lisible par l'utilisateur sous lequel Spark et Hive sont exécutés).
Téléchargez le connecteur HDFS dans l'instance de service et ajoutez les fichiers de configuration pertinents à l'aide de l'exemple de code suivant. Pour plus d'informations, reportez-vous à Connecteur HDFS pour Object Storage.
wget https://github.com/oracle/oci-hdfs-connector/releases/download/v2.9.2.1/oci-hdfs.zip
unzip oci-hdfs.zip -d oci-hdfs
cd $HOME
mkdir .oci
# Create or copy your API key into the $HOME/.oci directory
cd $SPARK_HOME/conf
# Create a core-site.xml (e.g. by transferring one you have, using vi etc.). Consult
# https://docs.oracle.com/iaas/Content/API/SDKDocs/hdfsconnector.htm#Properties
# for what this should look like
# Create a spark-defaults.conf file from the template
cp spark-defaults.conf.template spark-defaults.conf
Ajoutez ce qui suit à la fin du fichier spark-defaults.conf :
spark.sql.hive.metastore.sharedPrefixes= shaded.oracle,com.oracle.bmc
Préparation des données
Pour le test des données, nous utiliserons l'ensemble de données MovieLens.
- Téléchargez en local le dernier ensemble de données à l'adresse https://grouplens.org/datasets/movielens/latest/. Veillez à télécharger l'ensemble de données "Small".
- Décompressez le fichier de téléchargement.
- Téléchargez le fichier
movies.csvvers le bucket Object Storage.
Test à l'aide du shell Spark
Lorsque les données sont prêtes, nous pouvons lancer le shell Spark et effectuer le test à l'aide d'un exemple de commande :
cd $SPARK_HOME
./bin/spark-shell
scala> sc.wholeTextFiles("oci://PipedUploadTest@sampletenancy/")
java.io.IOException: No FileSystem for scheme: oci
Vous recevez une erreur à ce stade car le schéma du système de fichiers oci:// n'est pas disponible. Nous devons référencer le fichier JAR avant de démarrer le shell Spark. L'exemple ci-dessous illustre cette opération :
./bin/spark-shell --jars $HOME/oci-hdfs/lib/oci-hdfs-full-1.2.7.jar --driver-class-path $HOME/oci-hdfs/lib/oci-hdfs-full-1.2.7.jar
scala> sc.wholeTextFiles("oci://PipedUploadTest@sampletenancy/")
res0: org.apache.spark.rdd.RDD[(String, String)] = oci://PipedUploadTest@sampletenancy/ MapPartitionsRDD[1] at wholeTextFiles at <console>:25
scala> sc.textFile("oci://PipedUploadTest@sampletenancy/movies.csv").take(20).foreach(println)
movieId,title,genres
1,Toy Story (1995),Adventure|Animation|Children|Comedy|Fantasy
2,Jumanji (1995),Adventure|Children|Fantasy
3,Grumpier Old Men (1995),Comedy|Romance
4,Waiting to Exhale (1995),Comedy|Drama|Romance
5,Father of the Bride Part II (1995),Comedy
6,Heat (1995),Action|Crime|Thriller
7,Sabrina (1995),Comedy|Romance
8,Tom and Huck (1995),Adventure|Children
9,Sudden Death (1995),Action
10,GoldenEye (1995),Action|Adventure|Thriller
11,"American President, The (1995)",Comedy|Drama|Romance
12,Dracula: Dead and Loving It (1995),Comedy|Horror
13,Balto (1995),Adventure|Animation|Children
14,Nixon (1995),Drama
15,Cutthroat Island (1995),Action|Adventure|Romance
16,Casino (1995),Crime|Drama
17,Sense and Sensibility (1995),Drama|Romance
18,Four Rooms (1995),Comedy
19,Ace Ventura: When Nature Calls (1995),Comedy
La commande a réussi et nous pouvons donc nous connecter à Object Storage. Si vous ne souhaitez pas transmettre l'argument --jars à chaque exécution de la commande, vous pouvez copier le fichier JAR oci-hdfs-full dans le répertoire $SPARK_HOME/jars.
Démarrage du serveur Spark Thrift
Démarrez le serveur Spark Thrift sur le port 10015 et utilisez l'outil de ligne de commande Beeline pour établir une connexion JDBC, puis exécutez une requête de base, comme indiqué ici :
cd $SPARK_HOME
./sbin/start-thriftserver.sh --hiveconf hive.server2.thrift.port=10015
Une fois que le serveur Spark est en cours d'exécution, nous pouvons lancer Beeline, comme indiqué ci-dessous :
cd $SPARK_HOME
./bin/beeline
Beeline version 1.2.1.spark2 by Apache Hive
beeline>
Ensuite, connectez-vous au serveur, comme indiqué ci-dessous :
Pour cet exemple, nous n'avons configuré aucune sécurité. Par conséquent, tous les noms utilisateur et mots de passe sont acceptés. Pour les scénarios de production, vous ne pouvez pas procéder ainsi.
beeline> !connect jdbc:hive2://localhost:10015 testuser testpass
Connecting to jdbc:hive2://localhost:10015
log4j:WARN No appenders could be found for logger (org.apache.hive.jdbc.Utils).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Connected to: Spark SQL (version 2.2.1)
Driver: Hive JDBC (version 1.2.1.spark2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://localhost:10015>
Si nous vérifions à présent les tables existantes, nous voyons ce qui suit :
0: jdbc:hive2://localhost:10015> show tables;
+-----------+------------+--------------+--+
| database | tableName | isTemporary |
+-----------+------------+--------------+--+
+-----------+------------+--------------+--+
No rows selected (0.724 seconds)
Aucune table n'existe actuellement. Toutefois, nous pouvons créer une table et la lier au fichier movies.csv que vous avez téléchargé et placé dans le bucket Object Storage, comme indiqué ici :
0: jdbc:hive2://localhost:10015> create table test_table (movieId integer, title string, genres string) using csv options (path "oci://myBucket@myTenant/movies.csv", header "true", delimiter ",");
0: jdbc:hive2://localhost:10015> describe formatted test_table;
+-------------------------------+------------------------------------------------------------+----------+--+
| col_name | data_type | comment |
+-------------------------------+------------------------------------------------------------+----------+--+
| movieId | int | NULL |
| title | string | NULL |
| genres | string | NULL |
| | | |
| # Detailed Table Information | | |
| Database | default | |
| Table | test_table | |
| Owner | opc | |
| Created | Thu Mar 01 20:45:18 GMT 2018 | |
| Last Access | Thu Jan 01 00:00:00 GMT 1970 | |
| Type | EXTERNAL | |
| Provider | csv | |
| Table Properties | [transient_lastDdlTime=1519937118] | |
| Location | oci://PipedUploadTest@sampletenancy/movies.csv | |
| Serde Library | org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe | |
| InputFormat | org.apache.hadoop.mapred.SequenceFileInputFormat | |
| OutputFormat | org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat | |
| Storage Properties | [delimiter=,, header=true, serialization.format=1] | |
+-------------------------------+------------------------------------------------------------+----------+--+
La table stocke ses données en externe dans Object Storage et les données sont accessibles via le connecteur HDFS (modèle de système de fichiers oci://). Maintenant qu'une table est présente, nous pouvons l'interroger :
0: jdbc:hive2://localhost:10015> select * from test_table limit 10;
+----------+-------------------------------------+----------------------------------------------+--+
| movieId | title | genres |
+----------+-------------------------------------+----------------------------------------------+--+
| 1 | Toy Story (1995) | Adventure|Animation|Children|Comedy|Fantasy |
| 2 | Jumanji (1995) | Adventure|Children|Fantasy |
| 3 | Grumpier Old Men (1995) | Comedy|Romance |
| 4 | Waiting to Exhale (1995) | Comedy|Drama|Romance |
| 5 | Father of the Bride Part II (1995) | Comedy |
| 6 | Heat (1995) | Action|Crime|Thriller |
| 7 | Sabrina (1995) | Comedy|Romance |
| 8 | Tom and Huck (1995) | Adventure|Children |
| 9 | Sudden Death (1995) | Action |
| 10 | GoldenEye (1995) | Action|Adventure|Thriller |
+----------+-------------------------------------+----------------------------------------------+--+