簡體   English   中英

它對火花RDD聯盟來說非常緩慢

[英]it is very slow for spark RDD union

我有2個spark RDD,dataRDD和newPairDataRDD,它們用於spark SQL查詢。 當我的應用程序初始化時,dataRDD將被初始化。 一個指定的hbase實體中的所有數據都將存儲到dataRDD。

當客戶端的SQL查詢到來時,我的APP將獲得所有新的更新並插入newPairDataRDD。 dataRDD聯合newPairDataRDD並在spark SQL上下文中注冊為表。

我在dataRDD中找到了0條記錄,在newPairDataRDD中找到了1條新的插入記錄。 工會需要4秒鍾。 那太慢了

我認為這是不合理的。 誰知道怎么做得更快? 謝謝簡單的代碼如下

    // Step1: load all data from hbase to dataRDD when initial, this only run once. 
    JavaPairRDD<String, Row>  dataRDD= getAllBaseDataToJavaRDD();
    dataRDD.cache();
    dataRDD.persist(StorageLevel.MEMORY_ONLY());
    logger.info(dataRDD.count());

    // Step2: when spark sql query coming, load latest updated and inserted data from db to newPairDataRDD

    JavaPairRDD<String, Row> newPairDataRDD = getUpdateOrInstertBaseDataToJavaRDD();
    // Step3: if count>0 do union and reduce

       if(newPairDataRDD.count() > 0) {

        JavaPairRDD<String, Row> unionedRDD =dataRDD.union(newPairDataRDD);

    // if data was updated in DB, need to delete the old version from the dataRDD.

        dataRDD = unionedRDD.reduceByKey(
            new Function2<Row, Row, Row>() {
            // @Override
            public Row call(Row r1, Row r2) {
             return r2;
             }
            });
    }
//step4: register the dataRDD
JavaSchemaRDD schemaRDD = sqlContext.applySchema(dataRDD..values(), schema);

//step5: execute sql query
retRDD = sqlContext.sql(sql);
List<org.apache.spark.sql.api.java.Row> rows = retRDD.collect();

從火花web ui,我可以在下面看到。 顯然它需要4s才能結合

完成階段(8)

StageId描述提交的持續時間任務:成功/總輸入隨機讀取隨機寫入

6收集於SparkPlan.scala:85 +詳情2015年4月4日8:17 2 s 8-Aug 156.0 B.

7聯盟SparkSqlQueryForMarsNew.java:389+details 1/4/2015 8:17 4 s 8-Aug 64.0 B 156.0 B

實現所需的更有效方法是使用flatMapValues() cogroup()flatMapValues() ,除了向dataRDD添加新分區外,使用union幾乎沒有,這意味着必須在reduceByKey()之前對所有數據進行混洗。 flatMapValues() cogroup()flatMapValues()將僅導致newPairDataRDD重新分區。

JavaPairRDD<String, Tuple2<List<Row>, List<Row>>> unionedRDD = dataRDD.cogroup(newPairDataRDD);
JavaPairRDD<String, Row> updated = unionedRDD.flatMapValues(
    new Function<Tuple2<List<Row>, List<Row>>, Iterable<Row>>() {
        public Iterable<Row> call(Tuple2<List<Row>, List<Row>> grouped) {
            if (grouped._2.nonEmpty()) {
                return grouped._2;
            } else {
                return grouped._1;
            }
        }
    });

或者在斯卡拉

val unioned = dataRDD.cogroup(newPairDataRDD)
val updated = unioned.flatMapValues { case (oldVals, newVals) =>
    if (newVals.nonEmpty) newVals else oldVals
}

免責聲明,我不習慣用Java編寫火花! 如果以上錯誤,請有人糾正我!

嘗試重新分區您的RDD:

JavaPairRDD unionedRDD = dataRDD.repartition(sc.defaultParallelism * 3).union(newPairDataRDD.repartition(sc.defaultParallelism * 3));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM