Apache spark 筛选阶段在RDD沿袭重新执行中丢失
我有一个关于RDD和谱系图的问题。让我举例说明: 我有一个如下所示的数据文件:Apache spark 筛选阶段在RDD沿袭重新执行中丢失,apache-spark,Apache Spark,我有一个关于RDD和谱系图的问题。让我举例说明: 我有一个如下所示的数据文件: ID; parent; level; type;content; Budget; 999999 ;;a;Total;total; 313344394; 01 ;;a;Part 1;Chancellery of the President of the Republic of Poland; 171524; 02 ;;a;Part 2;Chancellery of the Sejm; 430780; 03 ;;a;Pa
ID; parent; level; type;content; Budget;
999999 ;;a;Total;total; 313344394;
01 ;;a;Part 1;Chancellery of the President of the Republic of Poland; 171524;
02 ;;a;Part 2;Chancellery of the Sejm; 430780;
03 ;;a;Part 3;OFFICE OF THE SENATE; 176212;
04 ;;a;Part 4;SUPREME COURT; 88161;
请注意,对于最后一个预算字段,有一个前导空格。
因此,我读入数据,创建一个由选定列组成的RDD:
scala> val baseRDD=sc.textFile(dataFile)
baseRDD: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[103] at textFile at <console>:29
scala> val budgetRDD=baseRDD.map(_.split(";")).map(x => (x(0),x(4), x(5)))
budgetRDD: org.apache.spark.rdd.RDD[(String, String, String)] = MapPartitionsRDD[101] at map at <console>:31
这是可以理解的,因为预算栏中有前导空格。
因此,我没有使用trim,而是编辑并删除了数据文件中的前导空格:
ID; parent; level; type;content;Budget;
999999 ;;a;Total;total;313344394;
01 ;;a;Part 1;Chancellery of the President of the Republic of Poland;171524;
02 ;;a;Part 2;Chancellery of the Sejm;430780;
03 ;;a;Part 3;OFFICE OF THE SENATE;176212;
04 ;;a;Part 4;SUPREME COURT;88161;
进行了此更改后,对于上面的沿袭图,我的期望是重新运行take
操作将重新执行沿袭图并产生所需的结果。但事实并非如此,相反,我得到了另一个错误,表明没有应用排除标题行的筛选步骤:
scala> idBudgetRDD.take(2)
16/02/12 03:47:03 ERROR Executor: Exception in task 0.0 in stage 147.0 (TID 180)
java.lang.NumberFormatException: For input string: "Budget"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
有人能解释发生了什么事吗?我的想法是,由于延迟求值和沿袭,修复数据文件并重新执行
take
将导致沿袭图整体重新运行。结果是我上面使用的过滤器已修复,因此在修改文件后,它不再适用。我可以通过指定一个依赖于匹配ID字符串的筛选器来解决此问题,如下所示:
val idBudgetRDD = budgetRDD.filter(! _.0.startsWith("ID;")).map{case(id,name,money) => (id, money.toInt)}
这始终与标题行匹配,重新运行take会产生正确的结果。您的
headerRow
变量包含什么?抱歉,我错过了这一行,并将其添加到上面:val headerRow=budgetRDD。首先在再次执行take
之前是否更新了此变量?啊,现在我明白了。headerRow变量在具体化后需要更新。我犯了错误,谢谢。我假设如果我用类似于val dataRows=budgetRDD.filter(!=budgetRDD.first)
的东西替换过滤器步骤中的变量,这可能会起作用。我尝试使用上面的过滤器,并得到以下错误:16/02/12 05:14:47警告TaskSetManager:在阶段149.0(TID 182,localhost)中丢失任务0.0:org.apache.spark.SparkException:RDD转换和操作只能由驱动程序调用,不能在其他转换内部调用;例如,rdd1.map(x=>rdd2.values.count()*x)无效,因为无法在rdd1.map转换内部执行值转换和计数操作。有关更多信息,请参阅SPARK-5063。
有什么建议吗?
scala> idBudgetRDD.take(2)
16/02/12 03:47:03 ERROR Executor: Exception in task 0.0 in stage 147.0 (TID 180)
java.lang.NumberFormatException: For input string: "Budget"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
val idBudgetRDD = budgetRDD.filter(! _.0.startsWith("ID;")).map{case(id,name,money) => (id, money.toInt)}