2015-09-22 14 views
5

Ho scritto una semplice app Flask per passare alcuni dati a Spark. Lo script funziona in IPython Notebook, ma non quando provo ad eseguirlo nel proprio server. Non penso che il contesto Spark sia in esecuzione all'interno della sceneggiatura. Come posso far funzionare Spark nel seguente esempio?Accesso a Spark dall'app Flask

from flask import Flask, request 
from pyspark import SparkConf, SparkContext 

app = Flask(__name__) 

conf = SparkConf() 
conf.setMaster("local") 
conf.setAppName("SparkContext1") 
conf.set("spark.executor.memory", "1g") 
sc = SparkContext(conf=conf) 

@app.route('/accessFunction', methods=['POST']) 
def toyFunction(): 
    posted_data = sc.parallelize([request.get_data()]) 
    return str(posted_data.collect()[0]) 

if __name__ == '__main_': 
    app.run(port=8080) 

In IPython Notebook non mi definisco il SparkContext perché viene configurato automaticamente. Non ricordo come ho fatto questo, ho seguito alcuni blog.

Sul server Linux ho impostato il file .py per essere sempre in esecuzione e installato l'ultimo Spark seguendo il passaggio 5 di this guide.

Edit:

Seguendo il consiglio davidism Ora ho invece fatto ricorso a programmi semplici con complessità crescente di localizzare l'errore.

In primo luogo ho creato .py con appena lo script dalla risposta qui sotto (dopo aver regolato in modo appropriato i link):

import sys 
try: 
    sys.path.append("your/spark/home/python") 
    from pyspark import context 
    print ("Successfully imported Spark Modules") 
except ImportError as e: 
    print ("Can not import Spark Modules", e) 

Ciò restituisce "Moduli Spark importati con successo". Tuttavia, il file .py dopo ho fatto restituisce un'eccezione:

from pyspark import SparkContext 
sc = SparkContext('local') 
rdd = sc.parallelize([0]) 
print rdd.count() 

Ciò restituisce un'eccezione:

"processo di gateway di Java è uscito prima di inviare il conducente suo numero di porta"

ricerca in giro per problemi simili Ho trovato this page ma quando eseguo questo codice non succede niente, nessuna stampa sulla console e nessun messaggio di errore. Allo stesso modo, this non ha aiutato nessuno, ottengo la stessa eccezione del gateway Java come sopra. Ho anche installato anaconda come ho sentito questo potrebbe aiutare a unire Python e Java, ancora nessun successo ...

Qualche suggerimento su cosa provare dopo? Sono in perdita.

+0

nota che ho postato sulla mia macchina con ipython notebook utilizzando l'estensione restclient su Firefox e ha funzionato come previsto – Matt

+1

ciò che non funziona? C'è un errore? Come stai postando i dati? Come stai facendo funzionare il server? Stai correndo in modalità di debug? Si prega di [modificare] per includere un [mcve]. – davidism

+0

Ho modificato la domanda – Matt

risposta

5

Okay, ho intenzione di rispondere alla mia domanda, nella speranza che qualcuno là fuori non subirà gli stessi giorni di frustrazione! Si scopre che era una combinazione di codice mancante e cattiva configurazione.

Modifica del codice di: anzi avevo bisogno di inizializzare un contesto Spark aggiungendo il seguente nel preambolo del mio codice:

from pyspark import SparkContext 
sc = SparkContext('local') 

Così il codice completo sarà:

from pyspark import SparkContext 
sc = SparkContext('local') 

from flask import Flask, request 
app = Flask(__name__) 

@app.route('/whateverYouWant', methods=['POST']) #can set first param to '/' 

def toyFunction(): 
    posted_data = sc.parallelize([request.get_data()]) 
    return str(posted_data.collect()[0]) 

if __name__ == '__main_': 
    app.run(port=8080) #note set to 8080! 

Modifica dell'impostazione: È essenziale che il file (nomefilefile.py) sia nella directory corretta, ovvero che b e salvato nella cartella /home/ubuntu/spark-1.5.0-bin-hadoop2.6.

quindi eseguire il seguente comando all'interno della directory:

./bin/spark-submit yourfilename.py 

che avvia il servizio a 10.0.0.XX: 8080/accessFunction /.

Nota che la porta deve essere impostata su 8080 o 8081: Spark consente solo interfaccia utente web per queste porte per impostazione predefinita per master e dei lavoratori, rispettivamente

è possibile testare il servizio con un servizio di ristoratore o aprendo un nuovo terminale e l'invio di richieste POST con i comandi cURL:

curl --data "DATA YOU WANT TO POST" http://10.0.0.XX/8080/accessFunction/ 
+0

Salve @Matt, sto affrontando problemi simili. Sono un po 'confuso con questo. perché è necessario mettere il progetto sotto la directory spark? e che dire di questo XX nell'indirizzo host? –

+0

Hey @Larissa è passato un po 'di tempo da quando l'ho scritto, quindi sono un po' arrugginito. È necessario inserire il progetto nella directory spark per eseguire il comando. Puoi aggirare questo problema aggiungendo ./bin/spark-submit al tuo spark bash e puoi eseguirlo da qualsiasi luogo, ma non voglio complicare eccessivamente questa risposta. Per quanto riguarda il XX che era l'IP locale della scatola, forse avrei dovuto scrivere solo 0.0.0.0, che funzionerà. Dovresti essere in grado di inviare richieste POST tramite postino da un'altra macchina sulla stessa rete. Spero che questo ti aiuti! – Matt

0

Modifica il tuo file .py come mostrato nella guida collegata 'Uso di IPython Notebook con Spark' secondo punto della parte. Instesso sys.path.insert usa sys.path.append. Provate inserire questo frammento:

import sys 
try: 
    sys.path.append("your/spark/home/python") 
    from pyspark import context 
    print ("Successfully imported Spark Modules") 
except ImportError as e: 
    print ("Can not import Spark Modules", e) 
+0

Grazie per avermi contattato. Ho provato a creare un programma il più semplice possibile, in primo luogo consistente nel codice sopra riportato. Quando lo eseguo, ottengo il "successo ...", che è grandioso. Quindi faccio un semplice programma che aggiungerò come modifica alla domanda. Il risultato è un'eccezione: "Il processo del gateway Java è stato chiuso prima di inviare al driver il suo numero di porta" – Matt

+0

Se è già stata inizializzata la variabile "sc", è necessario utilizzare la stessa istanza anziché reinizializzare la variabile. – szentesmarci

1

sono stato in grado di risolvere questo problema aggiungendo la posizione del PySpark e py4j al percorso nel mio file flaskapp.wsgi. Ecco il contenuto completo:

import sys 
sys.path.insert(0, '/var/www/html/flaskapp') 
sys.path.insert(1, '/usr/local/spark-2.0.2-bin-hadoop2.7/python') 
sys.path.insert(2, '/usr/local/spark-2.0.2-bin-hadoop2.7/python/lib/py4j-0.10.3-src.zip') 

from flaskapp import app as application