2016-03-02 124 views
4

我正在設置火花流光與kinesis和紅移。我每10秒鐘從kinesis讀取數據,處理它,並使用spark-redshift lib將它寫入紅移。火花紅移花費很多時間寫紅移

問題是它只花了很多時間只寫了300行。

這就是它顯示我在控制檯

[Stage 56:====================================================> (193 + 1)/200] 

看我的日誌df.write.format是這樣做的。

我在帶有4GB內存和2個核心的亞馬遜EC2的機器上運行spark-setup,使用--master local [*]模式運行。

這是我如何創建流

kinesisStream = KinesisUtils.createStream(ssc, APPLICATION_NAME, STREAM_NAME, ENDPOINT, REGION_NAME, INITIAL_POS, CHECKPOINT_INTERVAL, awsAccessKeyId =AWSACCESSID, awsSecretKey=AWSSECRETKEY, storageLevel=STORAGE_LEVEL)  
CHECKPOINT_INTERVAL = 60 
storageLevel = memory 

kinesisStream.foreachRDD(writeTotable) 
def WriteToTable(df, type): 
    if type in REDSHIFT_PAGEVIEW_TBL: 
     df = df.groupby([COL_STARTTIME, COL_ENDTIME, COL_CUSTOMERID, COL_PROJECTID, COL_FONTTYPE, COL_DOMAINNAME, COL_USERAGENT]).count() 
     df = df.withColumnRenamed('count', COL_PAGEVIEWCOUNT) 

     # Write back to a table 

     url = ("jdbc:redshift://" + REDSHIFT_HOSTNAME + ":" + REDSHIFT_PORT + "/" + REDSHIFT_DATABASE + "?user=" + REDSHIFT_USERNAME + "&password="+ REDSHIFT_PASSWORD) 

     s3Dir = 's3n://' + AWSACCESSID + ':' + AWSSECRETKEY + '@' + BUCKET + '/' + FOLDER 

     print 'Start writing to redshift' 
     df.write.format("com.databricks.spark.redshift").option("url", url).option("dbtable", REDSHIFT_PAGEVIEW_TBL).option('tempdir', s3Dir).mode('Append').save() 

     print 'Finished writing to redshift' 

請讓我知道採取這一多時間

回答

6

寫作既通過Spark和直接紅移時,我有過類似的經歷的原因。 spark-redshift將始終將數據寫入S3,然後使用Redshift複製功能將數據寫入目標表。這種方法是編寫大量記錄的最佳實踐和最有效的方法。這種方法還會在寫入時產生很多開銷,特別是當每次寫入的記錄數量相對較少時。

看上面的輸出,看起來你有大量的分區(大概是200左右)。這很可能是因爲spark.sql.shuffle.partitions設置默認設置爲200。你可以找到更多的細節in the Spark documentation

該組操作可能會生成200個分區。這意味着您正在對S3執行200次單獨的複製操作,每次複製操作在獲取連接和完成寫入操作時都有相當長的延遲時間。

正如我們在下面的評論中討論,並在聊天中,您可以在組的結果,凝聚通過爲較少的分區進行以下修改到行上面:

df = df.coalesce(4).withColumnRenamed('count', COL_PAGEVIEWCOUNT) 

這將減少數量從200到4的分區以及從副本到S3的開銷量爲幾個數量級。您可以嘗試使用分區數來優化性能。您還可以更改spark.sql.shuffle.partitions設置,以根據您正在處理的數據大小和可用內核數量減少分區數量。

+0

不要只寫3行的東西需要4分鐘左右的時間很多。此外,即使我有5000行寫,仍然4分鐘是很多時間 – Nipun

+0

哇,我沒有意識到它花了那麼長時間。在這種情況下,可能發生的情況是分區太多(從上面的輸出中可以看出這種情況)。這可能會導致從機器寫入S3的瓶頸。我不確定這是否適用於流媒體,但對於常規的spark工作,如df.coalesce(1).write.format(「com.databricks.spark.redshift」)。option(「url」,url)。選項(「dbtable」,REDSHIFT_PAGEVIEW_TBL)。選項('tempdir',s3Dir).mode('Append')。save()會起作用。你可以玩分區的數量來合併。 – DemetriKots

+0

我嘗試過,使用coalesce(4)和緩存,但它花費了相同的時間。這很奇怪,但是4分鐘就像寫了10條記錄或1000條記錄一樣。我嘗試聯繫AWS,但它也沒有幫助。嘗試從s3直接加載csv到紅移使用命令,看看是否需要時間,但這也是幾秒鐘。 – Nipun

0

你是databrick API。這是已知的問題。我有同樣的問題。我確實與Databric API團隊交談過。從Avaro文件加載時,Redshift的效果並不理想。我們確實與AWS團隊交談過。他們正在努力。 Databrick API在S3上創建avaro文件,然後複製命令將加載avaro文件。那就是性能殺手。

+0

請發表評論 – adao7000