Uso del connettore HDFS con Spark

Introduction

In questo articolo vengono fornite informazioni dettagliate sull'uso del connettore HDFS (Hadoop Distributed File System) con la struttura dell'applicazione Spark. Per le procedure dettagliate, utilizziamo il sistema operativo Oracle Linux 7.4 e eseguiamo Spark come standalone su un singolo computer.

Requisiti indispensabili

Di seguito sono riportati i prerequisiti per il completamento della procedura guidata.

  • È necessario disporre dell'autorizzazione per creare un'istanza di computazione. Per istruzioni, vedere Creazione di un'istanza.
  • È necessario essere in grado di connettersi all'istanza del servizio avviata. Per istruzioni, vedere Connessione a un'istanza.
  • Devi disporre dell'OCID, dell'impronta digitale e della chiave privata appropriati per l'utente IAM (Identity and Access Management) che utilizzerai per interagire con uno storage degli oggetti. Per istruzioni, vedere Impostazione e prerequisiti.
  • Devi disporre di un bucket di storage degli oggetti a cui puoi connetterti.
  • L'utente IAM deve essere in grado di leggere e scrivere in tale bucket utilizzando la console.

Uso di Spark

Installa Spark e dipendenze

Nota

Ai fini dell'esempio, installare Spark nella directory home dell'utente corrente. Si noti che per gli scenari di produzione non è possibile eseguire questa operazione.
Nota

Le versioni 2.7.7.0 e successive non installano più tutte le dipendenze di terze parti richieste. Le dipendenze di terze parti richieste vengono raggruppate nella cartella third-party/lib nell'archivio zip e devono essere installate manualmente.
  1. Creare un'istanza del servizio di computazione. Per istruzioni, vedere Creazione di un'istanza.
  2. Assicurarsi che l'istanza del servizio disponga di un indirizzo IP pubblico in modo da poter eseguire la connessione mediante una connessione SSH (Secure Shell). Per istruzioni, vedere Connessione a un'istanza.
  3. Connettersi all'istanza di servizio utilizzando una connessione SSH.
  4. Installa Spark e le sue dipendenze, Java e Scala, utilizzando gli esempi di codice che seguono.
# 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

Scaricare il connettore HDFS e creare i file di configurazione

Nota

Ai fini di questo esempio, inserire i file JAR e i file chiave nella directory home dell'utente corrente. Per gli scenari di produzione, invece, inserire questi file in una posizione comune che applica le autorizzazioni appropriate (ovvero, leggibile dall'utente in cui sono in esecuzione Spark e Hive).

Scaricare il connettore HDFS nell'istanza del servizio e aggiungere i file di configurazione pertinenti utilizzando il seguente esempio di codice. Per ulteriori informazioni, vedere HDFS Connector for 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

Nel file spark-defaults.conf, aggiungere quanto segue nella parte inferiore:

spark.sql.hive.metastore.sharedPrefixes= shaded.oracle,com.oracle.bmc

Prepara i dati

Per i dati di test, verrà utilizzato il set di dati MovieLens.

  1. Scaricare il data set più recente all'indirizzo https://grouplens.org/datasets/movielens/latest/. Assicurarsi di scaricare il set di dati "Piccolo".
  2. Decomprimere il file di download.
  3. Caricare il file movies.csv nel bucket di storage degli oggetti.

Test mediante la shell Spark

Con i dati pronti, ora possiamo avviare la shell Spark e testarla utilizzando un comando di esempio:

cd $SPARK_HOME
./bin/spark-shell
 
scala> sc.wholeTextFiles("oci://PipedUploadTest@sampletenancy/")
java.io.IOException: No FileSystem for scheme: oci

Si riceve un errore a questo punto perché lo schema del file system oci:// non è disponibile. È necessario fare riferimento al file JAR prima di avviare la shell Spark. Di seguito viene fornito un esempio.

./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

Il comando è riuscito, pertanto è possibile connettersi allo storage degli oggetti. Tenere presente che se non si desidera passare l'argomento --jars ogni volta che il comando viene eseguito, è possibile copiare il file JAR oci-hdfs-full nella directory $SPARK_HOME/jars.

Avviare il server Thrift Spark

Avviare Spark Thrift Server sulla porta 10015 e utilizzare lo strumento della riga di comando Beeline per stabilire una connessione JDBC e quindi eseguire una query di base, come mostrato qui:

cd $SPARK_HOME
./sbin/start-thriftserver.sh --hiveconf hive.server2.thrift.port=10015

Una volta che il server Spark è in esecuzione, possiamo avviare Beeline, come mostrato qui:

cd $SPARK_HOME
./bin/beeline
Beeline version 1.2.1.spark2 by Apache Hive
beeline>

Successivamente, connettersi al server, come mostrato qui:

Nota

Ai fini del presente esempio, non è stata configurata alcuna sicurezza, pertanto verranno accettati qualsiasi nome utente e password. Per gli scenari di produzione non lo faresti.
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>

Se ora controlliamo per vedere quali tabelle esistono, vediamo quanto segue:

0: jdbc:hive2://localhost:10015> show tables;
+-----------+------------+--------------+--+
| database  | tableName  | isTemporary  |
+-----------+------------+--------------+--+
+-----------+------------+--------------+--+
No rows selected (0.724 seconds)

Attualmente non esiste. Tuttavia, è possibile creare una tabella e collegarla al file movies.csv scaricato e posizionato nel bucket di storage degli oggetti, come mostrato qui:

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]         |          |
+-------------------------------+------------------------------------------------------------+----------+--+

Tenere presente che la tabella memorizza i dati esternamente nello storage degli oggetti e che è possibile accedere ai dati mediante il connettore HDFS (schema del file system oci://). Ora che abbiamo un tavolo, possiamo interrogarlo:

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                    |
+----------+-------------------------------------+----------------------------------------------+--+