Spark java.lang.StackOverflower错误

Spark java.lang.StackOverflower错误,java,apache-spark,mapreduce,Java,Apache Spark,Mapreduce,我使用spark来计算用户评论的pagerank,但是当我在一个大数据集(40k个条目)上运行代码时,我不断得到sparkjava.lang.StackOverflowerError。但是,当在少量条目上运行代码时,它可以正常工作 输入示例: product/productId: B00004CK40 review/userId: A39IIHQF18YGZA review/profileName: C. A. M. Salas review/helpfulness: 0/0 revi

我使用spark来计算用户评论的pagerank,但是当我在一个大数据集(40k个条目)上运行代码时,我不断得到spark
java.lang.StackOverflowerError
。但是,当在少量条目上运行代码时,它可以正常工作

输入示例:

product/productId: B00004CK40   review/userId: A39IIHQF18YGZA   review/profileName: C. A. M. Salas  review/helpfulness: 0/0 review/score: 4.0   review/time: 1175817600 review/summary: Reliable comedy review/text: Nice script, well acted comedy, and a young Nicolette Sheridan. Cusak is in top form.
守则:

public void calculatePageRank() {
    sc.clearCallSite();
    sc.clearJobGroup();

    JavaRDD < String > rddFileData = sc.textFile(inputFileName).cache();
    sc.setCheckpointDir("pagerankCheckpoint/");

    JavaRDD < String > rddMovieData = rddFileData.map(new Function < String, String > () {

        @Override
        public String call(String arg0) throws Exception {
            String[] data = arg0.split("\t");
            String movieId = data[0].split(":")[1].trim();
            String userId = data[1].split(":")[1].trim();
            return movieId + "\t" + userId;
        }
    });

    JavaPairRDD<String, Iterable<String>> rddPairReviewData = rddMovieData.mapToPair(new PairFunction < String, String, String > () {

        @Override
        public Tuple2 < String, String > call(String arg0) throws Exception {
            String[] data = arg0.split("\t");
            return new Tuple2 < String, String > (data[0], data[1]);
        }
    }).groupByKey().cache();


    JavaRDD<Iterable<String>> cartUsers = rddPairReviewData.map(f -> f._2());
      List<Iterable<String>> cartUsersList = cartUsers.collect();
      JavaPairRDD<String,String> finalCartesian = null;
      int iterCounter = 0;
      for(Iterable<String> out : cartUsersList){
          JavaRDD<String> currentUsersRDD = sc.parallelize(Lists.newArrayList(out));
          if(finalCartesian==null){
              finalCartesian = currentUsersRDD.cartesian(currentUsersRDD);
          }
          else{
              finalCartesian = currentUsersRDD.cartesian(currentUsersRDD).union(finalCartesian);
              if(iterCounter % 20 == 0) {
                  finalCartesian.checkpoint();
              }
          }
      }
      JavaRDD<Tuple2<String,String>> finalCartesianToTuple = finalCartesian.map(m -> new Tuple2<String,String>(m._1(),m._2()));

      finalCartesianToTuple = finalCartesianToTuple.filter(x -> x._1().compareTo(x._2())!=0);
      JavaPairRDD<String, String> userIdPairs = finalCartesianToTuple.mapToPair(m -> new Tuple2<String,String>(m._1(),m._2()));

      JavaRDD<String> userIdPairsString = userIdPairs.map(new Function < Tuple2<String, String>, String > () {

        //Tuple2<Tuple2<MovieId, userId>, Tuple2<movieId, userId>>
          @Override
          public String call (Tuple2<String, String> t) throws Exception {
            return t._1 + " " + t._2;
          }
      });

    try {

//calculate pagerank using this https://github.com/apache/spark/blob/master/examples/src/main/java/org/apache/spark/examples/JavaPageRank.java
        JavaPageRank.calculatePageRank(userIdPairsString, 100);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    sc.close();

}
public void calculateragerank(){
sc.clearCallSite();
sc.clearJobGroup();
JavaRDDrddFileData=sc.textFile(inputFileName).cache();
sc.setCheckpointDir(“pagerankCheckpoint/”);
JavaRDDrddMovieData=rddFileData.map(新函数(){
@凌驾
公共字符串调用(字符串arg0)引发异常{
字符串[]数据=arg0.split(“\t”);
字符串movieId=data[0]。拆分(“:”[1]。修剪();
字符串userId=data[1]。拆分(“:”[1]。修剪();
返回movieId+“\t”+用户id;
}
});
javapairdd rddPairReviewData=rddMovieData.mapToPair(新的PairFunction(){
@凌驾
公共元组2调用(字符串arg0)引发异常{
字符串[]数据=arg0.split(“\t”);
返回新的Tuple2(数据[0],数据[1]);
}
}).groupByKey().cache();
JavaRDD cartUsers=rddpaireviewdata.map(f->f._2());
List cartUsersList=cartUsers.collect();
javapairdd finalCartesian=null;
int iterCounter=0;
for(可编辑输出:cartUsersList){
JavaRDD currentUsersRDD=sc.parallelize(Lists.newArrayList(out));
如果(finalCartesian==null){
finalCartesian=currentUsersRDD.cartesian(currentUsersRDD);
}
否则{
finalCartesian=currentUsersRDD.cartesian(currentUsersRDD.union)(finalCartesian);
如果(iterCounter%20==0){
finalCartesian.checkpoint();
}
}
}
JavaRDD finalcartesiantuple=finalCartesian.map(m->newtuple2(m._1(),m._2());
FINALCARTESIANTOUPLE=FINALCARTESIANTOUPLE.filter(x->x.\u 1()。与(x.\u 2())比较)!=0);
javapairdd userIdPairs=finalCartesianToTuple.mapToPair(m->newtuple2(m.\u 1(),m.\u 2());
JavaRDD useridpairstring=userIdPairs.map(新函数(){
//元组2
@凌驾
公共字符串调用(tuple2t)引发异常{
返回t._1+“”+t._2;
}
});
试一试{
//使用此参数计算pagerankhttps://github.com/apache/spark/blob/master/examples/src/main/java/org/apache/spark/examples/JavaPageRank.java
calculatePageRank(userIdPairsString,100);
}捕获(例外e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
sc.close();
}

当for循环变得非常大时,Spark就不能再跟踪沿袭。在for循环中启用检查点,以便每隔10次左右检查rdd。检查点将解决此问题。之后不要忘记清理检查点目录


当DAG变大并且代码中发生了太多级别的转换时,就会出现此问题。当最后执行某个操作时,JVM将无法保存操作以执行延迟执行


检查点是一种选择。我建议为这种聚合实现spark sql。如果您的数据是结构化的,请尝试将其加载到dataframes中,并执行分组和其他mysql函数来实现这一点。

我有很多建议,可以帮助您极大地提高问题代码的性能

  • 缓存:缓存应用于那些需要反复参考以进行相同/不同操作(迭代算法)的数据集
  • 一个例子是RDD。
    count
    -告诉您数据中的行数 文件,则需要读取该文件。因此,如果您写入RDD。
    count
    ,则在 此时将读取文件,计算行数,然后 计数将被返回

    如果您再次调用RDD.
    count
    会怎么样?同样的事情:文件将 再次读取并计数。那么RDD.
    缓存做什么呢?现在,如果您运行
    RDD.
    count
    第一次,文件将被加载、缓存和删除 已计数。如果您再次调用RDD。
    count
    ,该操作将使用 缓存。它将只从缓存中获取数据并计算 行,无需重新计算

    阅读有关缓存的更多信息

    在代码示例中,您没有重用缓存的任何内容。因此,您可以从中删除
    .cache

  • 并行化:在代码示例中,您已经并行化了RDD中已经是分布式集合的每个元素。我建议您合并
    rddFileData
    rddMovieData
    rddPairReviewData
    步骤,以便一次性完成
  • 清除
    。收集
    ,因为这会将结果带回驱动程序,可能是错误的实际原因