2015-09-22 54 views
5

我寫了一個簡單的Flask應用程序將一些數據傳遞給Spark。該腳本在IPython Notebook中工作,但不是當我嘗試在它自己的服務器中運行它時。我不認爲Spark上下文在腳本中運行。在下面的例子中,我如何獲得Spark?從Flask訪問Spark應用程序

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) 

在IPython Notebook中,我沒有定義SparkContext,因爲它是自動配置的。我不記得我是如何做到這一點的,我跟着一些博客。

在Linux服務器上,我已經將.py設置爲始終運行並安裝最新的Spark,跟隨到this guide的第5步。

編輯

繼davidism建議我現在已經不是訴諸簡單的程序與日益複雜本地化錯誤。

首先我創建的.py與剛剛從下面的答案腳本(後適當調整鏈接):

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) 

這將返回「成功導入星火模塊」。然而,接下來的.py文件我做了回報異常:

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

這將返回例外:

搜索周圍類似的問題「的Java網關進程發送驅動其端口號之前退出」我發現this page,但是當我運行這段代碼時,沒有任何反應,控制檯上沒有打印,也沒有錯誤消息。同樣,this也沒有幫助,我得到了與上面相同的Java網關異常。我也安裝了anaconda,因爲我聽說這可能有助於聯合python和java,再次沒有成功......

任何有關下一步嘗試的建議?我很茫然。

+0

注意,我用的Firefox的擴展RESTClient實現我的機器有IPython的筆記本上公佈它的工作如預期 – Matt

+1

什麼是不工作?有錯誤嗎?你如何發佈數據?你如何運行服務器?你在調試模式下運行嗎?請[edit]包含[mcve]。 – davidism

+0

我編輯了問題 – Matt

回答

5

好了,所以我要回答我的問題,希望有人在那裏不會遭受挫折的同一天!事實證明,這是缺少代碼和糟糕設置的組合。

編輯代碼: 我確實需要通過附加在我的代碼的序言以下初始化一個Spark語境:

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

所以完整的代碼將是:

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! 

編輯設置: 重要的是文件(yourrfilename.py)在正確的目錄中,即它必須b e保存到文件夾/home/ubuntu/spark-1.5.0-bin-hadoop2.6。

然後在目錄中發出以下命令:

./bin/spark-submit yourfilename.py 

從而啓動在10.0.0.XX服務:8080/accessFunction /。

注意,端口必須設置爲8080或8081:星火只允許這些端口默認情況下,主機和工人分別

你可以用一個RESTful服務或通過打開測試出服務的網絡用戶界面一個新的終端,並與捲曲的命令發送POST請求:

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

嗨@Matt,我面臨着類似的問題。我對此有點困惑。爲什麼需要將該項目放在spark目錄下?以及主機地址中的這個XX怎麼樣? –

+0

嘿@Larissa自從我寫了那麼一段時間以來,我有點生疏。您需要將該項目放入spark目錄以運行該命令。如果您將./bin/spark-submit添加到您的spark bash中並且您可以從任何位置運行它,則可以解決此問題,但我不想過分複雜化該答案。至於是盒子本地IP的XX,也許我應該只寫0.0.0.0,這將起作用。儘管如此,您應該可以通過郵遞員從另一臺機器發送POST請求。希望這可以幫助! – Matt

0

修改您的.py文件,如鏈接指南「使用帶Spark的IPython Notebook」第二部分所示。 Insed sys.path.insert使用sys.path.append。嘗試插入此片段:

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

感謝您回覆我。我曾嘗試創建一個儘可能簡單的程序,首先由上面的代碼組成。當我運行它時,我得到了「成功......」,這很棒。然後我製作一個簡單的程序,作爲對問題的修改。結果是一個例外:「在發送驅動程序的端口號之前退出Java網關進程」 – Matt

+0

如果您已經初始化變量'sc',那麼您必須使用相同的實例,而不是重新初始化該變量。 – szentesmarci

1

我能夠在我的flaskapp.wsgi文件中添加PySpark的位置和py4j的路徑來解決這個問題。以下是全文:

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