2015-11-06 74 views
0

我想知道什麼樣的Spark運行時採樣RDD/DF與完整RDD/DF的運行時相比。我不知道它是否有所作爲,但我目前正在使用Java + Spark 1.5.1 + Hadoop 2.6。Spark採樣 - 比使用完整RDD/DataFrame速度快多少

JavaRDD<Row> rdd = sc.textFile(HdfsDirectoryPath()).map(new Function<String, Row>() { 
     @Override 
     public Row call(String line) throws Exception { 
      String[] fields = line.split(usedSeparator); 
      GenericRowWithSchema row = new GenericRowWithSchema(fields, schema);//Assum that the schema has 4 integer columns 
      return row; 
      } 
     }); 

DataFrame df = sqlContext.createDataFrame(rdd, schema); 
df.registerTempTable("df"); 
DataFrame selectdf = sqlContext.sql("Select * from df"); 
Row[] res = selectdf.collect(); 

DataFrame sampleddf = sqlContext.createDataFrame(rdd, schema).sample(false, 0.1);// 10% of the original DS 
sampleddf.registerTempTable("sampledf"); 
DataFrame selecteSampledf = sqlContext.sql("Select * from sampledf"); 
res = selecteSampledf.collect(); 

我期望採樣速度最佳接近〜90%。但對我來說,它看起來像火花穿過整個DF或做一個計數,基本上幾乎與完整DF選擇相同。樣品生成後,它執行選擇。

我是否正確的這個假設或是以錯誤的方式使用的採樣是什麼導致我最終得到兩個選擇所需的相同運行時間?

回答

0

我認爲採樣速度最佳接近90%。

嗯,有幾個原因,這些期望是不現實的:

  • 沒有關於數據分佈的任何前面的假設,以獲得均勻的樣品,你必須執行一個完整的數據集掃描。這或多或少會發生什麼,當您在Spark中使用sampletakeSample方法時
  • SELECT *是一個相對輕量級的操作。取決於您有足夠時間處理單個分區的資源量可以忽略不計
  • 採樣不會減少分區數量。如果您不需要​​3210或repartition,則最終可能會有大量幾乎爲空的分區。這意味着不理想的資源使用情況。
  • ,同時隨機數發生器通常是相當有效的產生隨機數是不是免費的

有抽樣至少有兩個重要的好處:

  • 更低的內存使用率,包括垃圾收集
  • 較少的工作較少的數據進行序列化/反序列化並在洗牌或收集的情況下傳輸

如果您想要從採樣中獲得最大收益對採樣,合併和緩存有意義。

+1

Grea,謝謝你的提示。我真的需要嘗試合併,因爲我也過濾了幾次相同的rdd,這意味着如果我理解你的話,我最終會得到相同大小的rdd。 當我擁有比內存更多的數據時,Cachning有點問題。 還有一個問題。爲什麼當我將文件讀入rdd時不會收集「分佈假設」或大小? – user5490570

+0

我的意思是分佈是一個統計性質的問題。如果對此有所瞭解,可以更聰明地進行抽樣,特別是如果隨機性不是一個硬性要求。例如參見[BlinkDB](http://blinkdb.org/) – zero323